diff options
author | cvs2svn <cvs2svn@FreeBSD.org> | 1994-09-22 21:36:03 +0000 |
---|---|---|
committer | cvs2svn <cvs2svn@FreeBSD.org> | 1994-09-22 21:36:03 +0000 |
commit | d800145de13dfb0b944fa341818d04d11d5ef669 (patch) | |
tree | 7196b548abb7434c1a970688aee57ea7d51d86c4 | |
parent | ab9d9cc0964202713327d43f5b849b1b8ada203f (diff) |
This commit was manufactured by cvs2svn to create tagvendor/bind4/4.9.3BETA9
'BIND_4_9_3_BETA9'.
Notes
Notes:
svn path=/vendor/bind4/dist/; revision=2990
svn path=/vendor/bind4/4.9.3BETA9/; revision=2992; tag=vendor/bind4/4.9.3BETA9
38 files changed, 0 insertions, 18802 deletions
diff --git a/usr.sbin/named/Version.c b/usr.sbin/named/Version.c deleted file mode 100644 index 7cbce2820e86..000000000000 --- a/usr.sbin/named/Version.c +++ /dev/null @@ -1,88 +0,0 @@ -/* - * @(#)Version.c 4.9 (Berkeley) 7/21/90 - * $Id: Version.c,v 4.9.1.3 1994/06/01 21:09:39 vixie Exp $ - */ - -#ifndef lint -char sccsid[] = "@(#)named %VERSION% %WHEN% %WHOANDWHERE%"; -char rcsid[] = "$Id: Version.c,v 4.9.1.3 1994/06/01 21:09:39 vixie Exp $"; -#endif /* not lint */ - -char Version[] = "named %VERSION% %WHEN%\n\t%WHOANDWHERE%"; - -#ifdef COMMENT - -SCCS/s.Version.c: - -D 4.8.3 90/06/27 17:05:21 bloom 37 35 00031/00028/00079 -Version distributed with 4.3 Reno tape (June 1990) - -D 4.8.2 89/09/18 13:57:11 bloom 35 34 00020/00014/00087 -Interim fixes release - -D 4.8.1 89/02/08 17:12:15 karels 34 33 00026/00017/00075 -branch for 4.8.1 - -D 4.8 88/07/09 14:27:00 karels 33 28 00043/00031/00049 -4.8 is here! - -D 4.7 87/11/20 13:15:52 karels 25 24 00000/00000/00062 -4.7.3 beta - -D 4.6 87/07/21 12:15:52 karels 25 24 00000/00000/00062 -4.6 declared stillborn - -D 4.5 87/02/10 12:33:25 kjd 24 18 00000/00000/00062 -February 1987, Network Release. Child (bind) grows up, parent (kevin) leaves home. - -D 4.4 86/10/01 10:06:26 kjd 18 12 00020/00017/00042 -October 1, 1986 Network Distribution - -D 4.3 86/06/04 12:12:18 kjd 12 7 00015/00028/00044 -Version distributed with 4.3BSD - -D 4.2 86/04/30 20:57:16 kjd 7 1 00056/00000/00016 -Network distribution Freeze and one more version until 4.3BSD - -D 1.1 86/04/30 19:30:00 kjd 1 0 00016/00000/00000 -date and time created 86/04/30 19:30:00 by kjd - -code versions: - -Makefile - Makefile 4.14 (Berkeley) 2/28/88 -db.h - db.h 4.13 (Berkeley) 2/17/88 -db_dump.c - db_dump.c 4.20 (Berkeley) 2/17/88 -db_load.c - db_load.c 4.26 (Berkeley) 2/28/88 -db_lookup.c - db_lookup.c 4.14 (Berkeley) 2/17/88 -db_reload.c - db_reload.c 4.15 (Berkeley) 2/28/88 -db_save.c - db_save.c 4.13 (Berkeley) 2/17/88 -db_update.c - db_update.c 4.16 (Berkeley) 2/28/88 -ns_forw.c - ns_forw.c 4.26 (Berkeley) 3/28/88 -ns_init.c - ns_init.c 4.23 (Berkeley) 2/28/88 -ns_main.c - Copyright (c) 1986 Regents of the University of California.\n\ - ns_main.c 4.30 (Berkeley) 3/7/88 -ns_maint.c - ns_maint.c 4.23 (Berkeley) 2/28/88 -ns_req.c - ns_req.c 4.32 (Berkeley) 3/31/88 -ns_resp.c - ns_resp.c 4.50 (Berkeley) 4/7/88 -ns_sort.c - ns_sort.c 4.3 (Berkeley) 2/17/88 -ns_stats.c - ns_stats.c 4.3 (Berkeley) 2/17/88 -newvers.sh - newvers.sh 4.4 (Berkeley) 3/28/88 - -#endif /* COMMENT */ diff --git a/usr.sbin/named/db_defs.h b/usr.sbin/named/db_defs.h deleted file mode 100644 index db9b32c2e256..000000000000 --- a/usr.sbin/named/db_defs.h +++ /dev/null @@ -1,172 +0,0 @@ -/* - * from db.h 4.16 (Berkeley) 6/1/90 - * $Id: db_defs.h,v 1.11 1994/07/22 08:42:39 vixie Exp $ - */ - -/* - * ++Copyright++ 1985, 1990 - * - - * Copyright (c) 1985, 1990 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - - * Portions Copyright (c) 1993 by Digital Equipment Corporation. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies, and that - * the name of Digital Equipment Corporation not be used in advertising or - * publicity pertaining to distribution of the document or software without - * specific, written prior permission. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT - * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - * - - * --Copyright-- - */ - -/* - * Global definitions for data base routines. - */ - -#define INVBLKSZ 7 /* # of namebuf pointers per block */ -#define INVHASHSZ 919 /* size of inverse hash table */ - - /* max length of data in RR data field */ -#define MAXDATA 2048 - -#define DB_ROOT_TIMBUF 3600 -#define TIMBUF 300 - -/* - * Hash table structures. - */ -struct databuf { - struct databuf *d_next; /* linked list */ - u_int32_t d_ttl; /* time to live */ - /* if d_zone == DB_Z_CACHE, then - * d_ttl is actually the time when - * the record will expire. - * otherwise (for authoritative - * primary and secondary zones), - * d_ttl is the time to live. - */ - unsigned d_flags :7; /* see below */ - unsigned d_cred :3; /* DB_C_{??????} */ - unsigned d_clev :6; - int16_t d_zone; /* zone number or 0 for the cache */ - int16_t d_class; /* class number */ - int16_t d_type; /* type number */ - int16_t d_mark; /* place to mark data */ - int16_t d_size; /* size of data area */ -#ifdef NCACHE - int16_t d_rcode; /* rcode added for negative caching */ -#endif - int16_t d_rcnt; -#ifdef STATS - struct nameser *d_ns; /* NS from whence this came */ -#endif -/*XXX*/ u_int32_t d_nstime; /* NS response time, milliseconds */ - u_char d_data[sizeof(char*)]; /* malloc'd (padded) */ -}; -#define DATASIZE(n) (sizeof(struct databuf) - sizeof(char*) + n) - -/* - * d_flags definitions - */ -#define DB_F_HINT 0x01 /* databuf belongs to fcachetab */ - -/* - * d_cred definitions - */ -#define DB_C_ZONE 4 /* authoritative zone - best */ -#define DB_C_AUTH 3 /* authoritative answer */ -#define DB_C_ANSWER 2 /* non-authoritative answer */ -#define DB_C_ADDITIONAL 1 /* additional data */ -#define DB_C_CACHE 0 /* cache - worst */ - -struct namebuf { - char *n_dname; /* domain name */ - u_int n_hashval; /* hash value of n_dname */ - struct namebuf *n_next; /* linked list */ - struct databuf *n_data; /* data records */ - struct namebuf *n_parent; /* parent domain */ - struct hashbuf *n_hash; /* hash table for children */ -}; - -#ifdef INVQ -struct invbuf { - struct invbuf *i_next; /* linked list */ - struct namebuf *i_dname[INVBLKSZ]; /* domain name */ -}; -#endif - -struct hashbuf { - int h_size; /* size of hash table */ - int h_cnt; /* number of entries */ - struct namebuf *h_tab[1]; /* malloc'ed as needed */ -}; -#define HASHSIZE(s) (s*sizeof(struct namebuf *) + 2*sizeof(int)) - -#define HASHSHIFT 3 -#define HASHMASK 0x1f - -/* - * Flags to updatedb - */ -#define DB_NODATA 0x01 /* data should not exist */ -#define DB_MEXIST 0x02 /* data must exist */ -#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_Z_CACHE (0) /* cache-zone-only db_dump() */ -#define DB_Z_ALL (-1) /* normal db_dump() */ - -/* - * Error return codes - */ -#define OK 0 -#define NONAME -1 -#define NOCLASS -2 -#define NOTYPE -3 -#define NODATA -4 -#define DATAEXISTS -5 -#define NODBFILE -6 -#define TOOMANYZONES -7 -#define GOODDB -8 -#define NEWDB -9 -#define AUTH -10 diff --git a/usr.sbin/named/db_dump.c b/usr.sbin/named/db_dump.c deleted file mode 100644 index 4a0d2c93f1f0..000000000000 --- a/usr.sbin/named/db_dump.c +++ /dev/null @@ -1,892 +0,0 @@ -#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 4.9.1.12 1994/07/22 08:42:39 vixie Exp $"; -#endif /* not lint */ - -/* - * ++Copyright++ 1986, 1988, 1990 - * - - * Copyright (c) 1986, 1988, 1990 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - - * Portions Copyright (c) 1993 by Digital Equipment Corporation. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies, and that - * the name of Digital Equipment Corporation not be used in advertising or - * publicity pertaining to distribution of the document or software without - * specific, written prior permission. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT - * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - * - - * --Copyright-- - */ - -#include <sys/param.h> -#include <sys/stat.h> -#include <netinet/in.h> -#include <arpa/nameser.h> -#include <arpa/inet.h> -#include <netdb.h> -#include <stdio.h> -#include <syslog.h> -#include <resolv.h> -#include <errno.h> - -#include "named.h" - -static int scan_root __P((struct hashbuf *)); -static const char *MkCredStr __P((int)); - -#ifdef ALLOW_T_UNSPEC -static void putbyte __P((int, char **)); -#endif - -/* - * Dump current cache in a format similar to RFC 883. - * - * We try to be careful and determine whether the operation succeeded - * so that the new cache file can be installed. - */ - -void -doachkpt() -{ - FILE *fp; - char tmpcheckfile[256]; - - /* nowhere to checkpoint cache... */ - if (cache_file == NULL) { - dprintf(3, (ddt, "skipping doachkpt (cache_file == NULL)\n")); - return; - } - - dprintf(3, (ddt, "doachkpt()\n")); - - (void) sprintf(tmpcheckfile, "%s.chk", cache_file); - if ((fp = fopen(tmpcheckfile, "w")) == NULL) { - dprintf(3, (ddt, - "doachkpt(can't open %s for write)\n", tmpcheckfile)); - return; - } - - (void) gettime(&tt); - fprintf(fp, "; Dumped at %s", ctime(&tt.tv_sec)); - fflush(fp); - if (ferror(fp)) { - dprintf(3, (ddt, "doachkpt(write to checkpoint file failed)\n")); - return; - } - - if (fcachetab != NULL) { - int n = scan_root(hashtab); - - if (n < MINROOTS) { - syslog(LOG_ERR, "%d root hints... (too low)", n); - fprintf(fp, "; ---- Root hint cache dump ----\n"); - (void) db_dump(fcachetab, fp, DB_Z_CACHE, ""); - } - } - - if (hashtab != NULL) { - fprintf(fp, "; ---- Cache dump ----\n"); - if (db_dump(hashtab, fp, DB_Z_CACHE, "") == NODBFILE) { - dprintf(3, (ddt, "doachkpt(checkpoint failed)\n")); - (void) my_fclose(fp); - return; - } - } - - (void) fsync(fileno(fp)); - if (my_fclose(fp) == EOF) { - return; - } - - if (rename(tmpcheckfile, cache_file)) { - dprintf(3, (ddt, "doachkpt(install %s to %s failed, %d)\n", - tmpcheckfile, cache_file, errno)); - } -} - -/* - * What we do is scan the root hint cache to make sure there are at least - * MINROOTS root pointers with non-0 TTL's so that the checkpoint will not - * lose the root. Failing this, all pointers are written out w/ TTL ~0 - * (root pointers timed out and prime_cache() not done or failed). - */ - -static int -scan_root(htp) - struct hashbuf *htp; -{ - register struct databuf *dp; - register struct namebuf *np; - struct timeval soon; - int roots = 0; - - dprintf(1, (ddt, "scan_root(0x%x)\n", 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 */ - /* time buffer for safety... */ - (void) gettime(&soon); - soon.tv_sec += TIMBUF; - - for (np = htp->h_tab[0]; np != NULL; np = np->n_next) { - if (np->n_dname[0] == '\0') { - dp = np->n_data; - while (dp != NULL) { - if (dp->d_type == T_NS && - dp->d_ttl > soon.tv_sec) { - roots++; - if (roots >= MINROOTS) - return (roots); - } - dp = dp->d_next; - } - } - } - return (roots); -} - -#ifdef notdef -mark_cache(htp, ttl) - struct hashbuf *htp; - int ttl; -{ - register struct databuf *dp; - register struct namebuf *np; - struct namebuf **npp, **nppend; - struct timeval soon; - - dprintf(1, (ddt, "mark_cache()\n")); - - (void) gettime(&soon); - soon.tv_sec += TIMBUF; - - npp = htp->h_tab; - nppend = npp + htp->h_size; - while (npp < nppend) { - for (np = *npp++; np != NULL; np = np->n_next) { - if (np->n_data == NULL) - continue; - for (dp = np->n_data; dp != NULL; dp = dp->d_next) { - if (dp->d_ttl < soon.tv_sec) - dp->d_ttl = ttl; - } - } - } - - npp = htp->h_tab; - nppend = npp + htp->h_size; - while (npp < nppend) { - for (np = *npp++; np != NULL; np = np->n_next) { - if (np->n_hash == NULL) - continue; - mark_cache(np->n_hash, ttl); - } - } -} -#endif /* notdef */ - -/* - * Dump current data base in a format similar to RFC 883. - */ - -void -doadump() -{ - FILE *fp; - - dprintf(3, (ddt, "doadump()\n")); - - if ((fp = fopen(dumpfile, "w")) == NULL) - return; - gettime(&tt); - fprintf(fp, "; Dumped at %s", ctime(&tt.tv_sec)); - if (zones && nzones) - zt_dump(fp); - fputs( -"; Note: Cr=(auth,answer,addtnl,cache) tag only shown for non-auth RR's\n", - fp); - fputs( -"; Note: NT=milliseconds for any A RR which we've used as a nameserver\n", - fp); - fprintf(fp, "; --- Cache & Data ---\n"); - if (hashtab != NULL) - (void) db_dump(hashtab, fp, DB_Z_ALL, ""); - fprintf(fp, "; --- Hints ---\n"); - if (fcachetab != NULL) - (void) db_dump(fcachetab, fp, DB_Z_ALL, ""); - (void) my_fclose(fp); -} - -#ifdef ALLOW_UPDATES -/* Create a disk database to back up zones - */ -void -zonedump(zp) - register struct zoneinfo *zp; -{ - FILE *fp; - char *fname; - struct hashbuf *htp; - char *op; - struct stat st; - - /* Only dump zone if there is a cache specified */ - if (zp->z_source && *(zp->z_source)) { - dprintf(1, (ddt, "zonedump(%s)\n", zp->z_source)); - - if ((fp = fopen(zp->z_source, "w")) == NULL) - return; - if (op = strchr(zp->z_origin, '.')) - op++; - gettime(&tt); - htp = hashtab; - if (nlookup(zp->z_origin, &htp, &fname, 0) != NULL) { - db_dump(htp, fp, zp-zones, (op == NULL ? "" : op)); - zp->z_flags &= ~Z_CHANGED; /* Checkpointed */ - } - (void) my_fclose(fp); - if (stat(zp->z_source, &st) == 0) - zp->z_ftime = st.st_mtime; - } else { - dprintf(1, (ddt, "zonedump: no zone to dump\n")); - } -} -#endif - -int -zt_dump(fp) - FILE *fp; -{ - register struct zoneinfo *zp; - - fprintf(fp, ";; ++zone table++\n"); - for (zp = &zones[1]; zp < &zones[nzones]; zp++) { - char *pre, buf[64]; - u_int cnt; - - fprintf(fp, "; %s (type %d, class %d, source %s)\n", - zp->z_origin, zp->z_type, zp->z_class, - zp->z_source ? zp->z_source : "Nil"); - fprintf(fp, ";\ttime=%ld, lastupdate=%ld, serial=%u,\n", - zp->z_time, zp->z_lastupdate, zp->z_serial); - fprintf(fp, ";\trefresh=%u, retry=%u, expire=%u, minimum=%u\n", - zp->z_refresh, zp->z_retry, - 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); - sprintf(buf, ";\tz_addr[%d]: ", zp->z_addrcnt); - pre = buf; - for (cnt = 0; cnt < zp->z_addrcnt; cnt++) { - fprintf(fp, "%s[%s]", pre, inet_ntoa(zp->z_addr[cnt])); - pre = ", "; - } - if (zp->z_addrcnt) - fputc('\n', fp); - } - fprintf(fp, ";; --zone table--\n"); -} - -int -db_dump(htp, fp, zone, origin) - struct hashbuf *htp; - FILE *fp; - int zone; - char *origin; -{ - register struct databuf *dp = NULL; - register struct namebuf *np; - struct namebuf **npp, **nppend; - char dname[MAXDNAME]; - u_int32_t n; - u_int32_t addr; - int j, i; - register u_char *cp; - u_char *end; - char *proto, *sep; - int found_data = 0, tab, printed_origin = 0; - - npp = htp->h_tab; - nppend = npp + htp->h_size; - while (npp < nppend) { - for (np = *npp++; np != NULL; np = np->n_next) { - if (np->n_data == NULL) - continue; - /* Blecch - can't tell if there is data here for the - * right zone, so can't print name yet - */ - found_data = 0; - /* we want a snapshot in time... */ - for (dp = np->n_data; dp != NULL; dp = dp->d_next) { - /* Is the data for this zone? */ - if (zone != DB_Z_ALL && dp->d_zone != zone) - continue; - if (dp->d_zone == DB_Z_CACHE && - dp->d_ttl <= tt.tv_sec && - (dp->d_flags & DB_F_HINT) == 0) - continue; - if (!printed_origin) { - fprintf(fp, "$ORIGIN %s.\n", origin); - printed_origin++; - } - tab = 0; -#ifdef NCACHE - if (dp->d_rcode == NXDOMAIN || - dp->d_rcode == NOERROR_NODATA) { - fputc(';', fp); - } else if (found_data == 0 || found_data == 1) { - found_data = 2; - } -#endif /*NCACHE*/ - if (found_data == 0 || found_data == 2) { - if (np->n_dname[0] == 0) { - if (origin[0] == 0) - fprintf(fp, ".\t"); - else - fprintf(fp, ".%s.\t", origin); /* ??? */ - } else - fprintf(fp, "%s\t", np->n_dname); - if (strlen(np->n_dname) < 8) - tab = 1; - found_data++; - } else { - (void) putc('\t', fp); - tab = 1; - } - if (dp->d_zone == DB_Z_CACHE) { - if (dp->d_flags & DB_F_HINT - && (int32_t)(dp->d_ttl - tt.tv_sec) - < DB_ROOT_TIMBUF) - fprintf(fp, "%d\t", DB_ROOT_TIMBUF); - else - fprintf(fp, "%d\t", - (int)(dp->d_ttl - tt.tv_sec)); - } else if (dp->d_ttl != 0 && - dp->d_ttl != zones[dp->d_zone].z_minimum) - fprintf(fp, "%d\t", (int)dp->d_ttl); - else if (tab) - (void) putc('\t', fp); - fprintf(fp, "%s\t%s\t", - p_class(dp->d_class), - p_type(dp->d_type)); - cp = (u_char *)dp->d_data; - sep = "\t;"; -#ifdef NCACHE -#ifdef RETURNSOA - if (dp->d_rcode == NOERROR_NODATA) { - fprintf(fp, "NODATA%s-$", sep); - goto eoln; - } -#else - if (dp->d_rcode == NXDOMAIN || - dp->d_rcode == NOERROR_NODATA) { - fprintf(fp, "%s%s-$", - (dp->d_rcode == NXDOMAIN) - ?"NXDOMAIN" :"NODATA", - sep); - goto eoln; - } -#endif -#endif - /* - * Print type specific data - */ - switch (dp->d_type) { - case T_A: - switch (dp->d_class) { - case C_IN: - case C_HS: - GETLONG(n, cp); - n = htonl(n); - fprintf(fp, "%s", - inet_ntoa(*(struct in_addr *)&n)); - break; - } - if (dp->d_nstime) { - fprintf(fp, "%sNT=%d", - sep, dp->d_nstime); - sep = " "; - } - break; - case T_CNAME: - case T_MB: - case T_MG: - case T_MR: - case T_PTR: - fprintf(fp, "%s.", cp); - break; - - case T_NS: - cp = (u_char *)dp->d_data; - if (cp[0] == '\0') - fprintf(fp, ".\t"); - else - fprintf(fp, "%s.", cp); - break; - - case T_HINFO: - case T_ISDN: - if (n = *cp++) { - fprintf(fp, "\"%.*s\"", (int)n, cp); - cp += n; - } else - fprintf(fp, "\"\""); - if (n = *cp++) - fprintf(fp, " \"%.*s\"", (int)n, cp); - else - fprintf(fp, " \"\""); - break; - - case T_SOA: - fprintf(fp, "%s.", cp); - cp += strlen((char *)cp) + 1; - fprintf(fp, " %s. (\n", cp); -#if defined(RETURNSOA) && defined(NCACHE) - if (dp->d_rcode == NXDOMAIN) - fputs(";", fp); -#endif - cp += strlen((char *)cp) + 1; - GETLONG(n, cp); - fprintf(fp, "\t\t%lu", n); - GETLONG(n, cp); - fprintf(fp, " %lu", n); - GETLONG(n, cp); - fprintf(fp, " %lu", n); - GETLONG(n, cp); - fprintf(fp, " %lu", n); - GETLONG(n, cp); - fprintf(fp, " %lu )", n); -#if defined(RETURNSOA) && defined(NCACHE) - if (dp->d_rcode == NXDOMAIN) { - fprintf(fp,";%s.;NXDOMAIN%s-$",cp,sep); - } -#endif - break; - - case T_MX: - case T_AFSDB: - case T_RT: - GETSHORT(n, cp); - fprintf(fp,"%lu", n); - fprintf(fp," %s.", cp); - break; - - case T_TXT: - case T_X25: - end = (u_char *)dp->d_data + dp->d_size; - (void) putc('"', fp); - while (cp < end) { - if (n = *cp++) { - for (j = n ; j > 0 && cp < end ; j--) - if (*cp == '\n') { - (void) putc('\\', fp); - (void) putc(*cp++, fp); - } else - (void) putc(*cp++, fp); - } - } - (void) fputs("\"", fp); - break; - - case T_NSAP: - (void) fputs(inet_nsap_ntoa(dp->d_size, - dp->d_data, NULL), - fp); - break; - - case T_UINFO: - fprintf(fp, "\"%s\"", cp); - break; - - case T_UID: - case T_GID: - if (dp->d_size == INT32SZ) { - GETLONG(n, cp); - } else { - n = -2; /* XXX - hack */ - } - fprintf(fp, "%u", n); - break; - - case T_WKS: - GETLONG(addr, cp); - addr = htonl(addr); - fprintf(fp, "%s ", - inet_ntoa(*(struct in_addr *)&addr)); - proto = protocolname(*cp); - cp += sizeof(char); - fprintf(fp, "%s ", proto); - i = 0; - while(cp < (u_char *)dp->d_data + dp->d_size) { - j = *cp++; - do { - if (j & 0200) - fprintf(fp, " %s", - servicename(i, proto)); - j <<= 1; - } while (++i & 07); - } - break; - - case T_MINFO: - case T_RP: - fprintf(fp, "%s.", cp); - cp += strlen((char *)cp) + 1; - fprintf(fp, " %s.", cp); - break; -#ifdef ALLOW_T_UNSPEC - case T_UNSPEC: - /* Dump binary data out in an ASCII-encoded - format */ - { - /* Allocate more than enough space: - * actually need 5/4 size + 20 or so - */ - 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); - } - break; -#endif /* ALLOW_T_UNSPEC */ - default: - fprintf(fp, "%s?d_type=%d?", - sep, dp->d_type); - sep = " "; - } - if (dp->d_cred < DB_C_ZONE) { - fprintf(fp, "%sCr=%s", - sep, MkCredStr(dp->d_cred)); - sep = " "; - } else { - fprintf(fp, "%sCl=%d", - sep, dp->d_clev); - sep = " "; - } -eoln: -#ifdef STATS - if (dp->d_ns) { - fprintf(fp, "%s[%s]", - sep, inet_ntoa(dp->d_ns->addr)); - sep = " "; - } -#endif - putc('\n', fp); - } - } - } - if (ferror(fp)) - return(NODBFILE); - - npp = htp->h_tab; - nppend = npp + htp->h_size; - while (npp < nppend) { - for (np = *npp++; np != NULL; np = np->n_next) { - if (np->n_hash == NULL) - continue; - getname(np, dname, sizeof(dname)); - if (db_dump(np->n_hash, fp, zone, dname) == NODBFILE) - return(NODBFILE); - } - } - return(OK); -} - -static const char * -MkCredStr(cred) - int cred; -{ - static char badness[20]; - - switch (cred) { - case DB_C_ZONE: return "zone"; - case DB_C_AUTH: return "auth"; - case DB_C_ANSWER: return "answer"; - case DB_C_ADDITIONAL: return "addtnl"; - case DB_C_CACHE: return "cache"; - default: break; - } - sprintf(badness, "?%d?", cred); - return (badness); -} - -#ifdef ALLOW_T_UNSPEC -/* - * Subroutines to convert between 8 bit binary bytes and printable ASCII. - * Computes the number of bytes, and three kinds of simple checksums. - * Incoming bytes are collected into 32-bit words, then printed in base 85: - * exp(85,5) > exp(2,32) - * The ASCII characters used are between '!' and 'u'; - * 'z' encodes 32-bit zero; 'x' is used to mark the end of encoded data. - * - * Originally by Paul Rutter (philabs!per) and Joe Orost (petsd!joe) for - * the atob/btoa programs, released with the compress program, in mod.sources. - * Modified by Mike Schwartz 8/19/86 for use in BIND. - */ - -/* Make sure global variable names are unique */ -#define Ceor T_UNSPEC_Ceor -#define Csum T_UNSPEC_Csum -#define Crot T_UNSPEC_Crot -#define word T_UNSPEC_word -#define bcount T_UNSPEC_bcount - -static int32_t Ceor, Csum, Crot, word, bcount; - -#define EN(c) ((int) ((c) + '!')) -#define DE(c) ((c) - '!') -#define AddToBuf(bufp, c) **bufp = c; (*bufp)++; -#define times85(x) ((((((x<<2)+x)<<2)+x)<<2)+x) - -/* Decode ASCII-encoded byte c into binary representation and - * place into *bufp, advancing bufp - */ -static int -byte_atob(c, bufp) - register c; - char **bufp; -{ - if (c == 'z') { - if (bcount != 0) - return(CONV_BADFMT); - else { - putbyte(0, bufp); - putbyte(0, bufp); - putbyte(0, bufp); - putbyte(0, bufp); - } - } else if ((c >= '!') && (c < ('!' + 85))) { - if (bcount == 0) { - word = DE(c); - ++bcount; - } else if (bcount < 4) { - word = times85(word); - word += DE(c); - ++bcount; - } else { - word = times85(word) + DE(c); - putbyte((int)((word >> 24) & 255), bufp); - putbyte((int)((word >> 16) & 255), bufp); - putbyte((int)((word >> 8) & 255), bufp); - putbyte((int)(word & 255), bufp); - word = 0; - bcount = 0; - } - } else - return(CONV_BADFMT); - return(CONV_SUCCESS); -} - -/* Compute checksum info and place c into *bufp, advancing bufp */ -static void -putbyte(c, bufp) - register c; - char **bufp; -{ - Ceor ^= c; - Csum += c; - Csum += 1; - if ((Crot & 0x80000000)) { - Crot <<= 1; - Crot += 1; - } else { - Crot <<= 1; - } - Crot += c; - AddToBuf(bufp, c); -} - -/* Read the ASCII-encoded data from inbuf, of length inbuflen, and convert - it into T_UNSPEC (binary data) in outbuf, not to exceed outbuflen bytes; - outbuflen must be divisible by 4. (Note: this is because outbuf is filled - in 4 bytes at a time. If the actual data doesn't end on an even 4-byte - boundary, there will be no problem...it will be padded with 0 bytes, and - numbytes will indicate the correct number of bytes. The main point is - that since the buffer is filled in 4 bytes at a time, even if there is - not a full 4 bytes of data at the end, there has to be room to 0-pad the - data, so the buffer must be of size divisible by 4). Place the number of - output bytes in numbytes, and return a failure/success status */ -int -atob(inbuf, inbuflen, outbuf, outbuflen, numbytes) - char *inbuf; - int inbuflen; - char *outbuf; - int outbuflen; - int *numbytes; -{ - int inc, nb; - int32_t oeor, osum, orot; - char *inp, *outp = outbuf, *endoutp = &outbuf[outbuflen]; - - if ( (outbuflen % 4) != 0) - return(CONV_BADBUFLEN); - Ceor = Csum = Crot = word = bcount = 0; - for (inp = inbuf, inc = 0; inc < inbuflen; inp++, inc++) { - if (outp > endoutp) - return(CONV_OVERFLOW); - if (*inp == 'x') { - inp +=2; - break; - } else { - if (byte_atob(*inp, &outp) == CONV_BADFMT) - return(CONV_BADFMT); - } - } - - /* Get byte count and checksum information from end of buffer */ - if(sscanf(inp, "%ld %lx %lx %lx", numbytes, &oeor, &osum, &orot) != 4) - return(CONV_BADFMT); - if ((oeor != Ceor) || (osum != Csum) || (orot != Crot)) - return(CONV_BADCKSUM); - return(CONV_SUCCESS); -} - -/* Encode binary byte c into ASCII representation and place into *bufp, - advancing bufp */ -static void -byte_btoa(c, bufp) - register c; - char **bufp; -{ - Ceor ^= c; - Csum += c; - Csum += 1; - if ((Crot & 0x80000000)) { - Crot <<= 1; - Crot += 1; - } else { - Crot <<= 1; - } - Crot += c; - - word <<= 8; - word |= c; - if (bcount == 3) { - if (word == 0) { - AddToBuf(bufp, 'z'); - } else { - register int tmp = 0; - register int32_t tmpword = word; - - if (tmpword < 0) { - /* Because some don't support unsigned long */ - tmp = 32; - tmpword -= (int32_t)(85 * 85 * 85 * 85 * 32); - } - if (tmpword < 0) { - tmp = 64; - tmpword -= (int32_t)(85 * 85 * 85 * 85 * 32); - } - AddToBuf(bufp, - EN((tmpword / (int32_t)(85 * 85 * 85 * 85)) + tmp)); - tmpword %= (int32_t)(85 * 85 * 85 * 85); - AddToBuf(bufp, EN(tmpword / (85 * 85 * 85))); - tmpword %= (85 * 85 * 85); - AddToBuf(bufp, EN(tmpword / (85 * 85))); - tmpword %= (85 * 85); - AddToBuf(bufp, EN(tmpword / 85)); - tmpword %= 85; - AddToBuf(bufp, EN(tmpword)); - } - bcount = 0; - } else { - bcount += 1; - } -} - - -/* - * Encode the binary data from inbuf, of length inbuflen, into a - * null-terminated ASCII representation in outbuf, not to exceed outbuflen - * bytes. Return success/failure status - */ -static int -btoa(inbuf, inbuflen, outbuf, outbuflen) - char *inbuf; - int inbuflen; - char *outbuf; - int outbuflen; -{ - int32_t inc, nb; - int32_t oeor, osum, orot; - char *inp, *outp = outbuf, *endoutp = &outbuf[outbuflen -1]; - - Ceor = Csum = Crot = word = bcount = 0; - for (inp = inbuf, inc = 0; inc < inbuflen; inp++, inc++) { - byte_btoa((unsigned char) (*inp), &outp); - if (outp >= endoutp) - return(CONV_OVERFLOW); - } - while (bcount != 0) { - byte_btoa(0, &outp); - if (outp >= endoutp) - return(CONV_OVERFLOW); - } - /* Put byte count and checksum information at end of buffer, delimited - by 'x' */ - (void) sprintf(outp, "x %ld %lx %lx %lx", inbuflen, Ceor, Csum, Crot); - if (&outp[strlen(outp) - 1] >= endoutp) - return(CONV_OVERFLOW); - else - return(CONV_SUCCESS); -} -#endif /* ALLOW_T_UNSPEC */ diff --git a/usr.sbin/named/db_func.h b/usr.sbin/named/db_func.h deleted file mode 100644 index 1c7275cb46e0..000000000000 --- a/usr.sbin/named/db_func.h +++ /dev/null @@ -1,102 +0,0 @@ -/* db_proc.h - prototypes for functions in db_*.c - * - * $Id: db_func.h,v 1.8 1994/07/23 23:23:56 vixie Exp $ - */ - -/* ++from db_update.c++ */ -extern int db_update __P((char name[], - struct databuf *odp, - struct databuf *newdp, - int flags, - struct hashbuf *htp)); -/* --from db_update.c-- */ - -/* ++from db_reload.c++ */ -extern void db_reload __P((void)); -/* --from db_reload.c-- */ - -/* ++from db_save.c++ */ -extern struct namebuf *savename __P((char *)); -#ifdef DMALLOC -extern struct databuf *savedata_tagged __P((char *, int, - int, int, u_int32_t, - u_char *, int)); -#define savedata(class, type, ttl, data, size) \ - savedata_tagged(__FILE__, __LINE__, class, type, ttl, data, size) -#else -extern struct databuf *savedata __P((int, int, u_int32_t, - u_char *, int)); -#endif -extern struct hashbuf *savehash __P((struct hashbuf *)); -/* --from db_save.c-- */ - -/* ++from db_dump.c++ */ -extern int db_dump __P((struct hashbuf *, FILE *, int, char *)), - zt_dump __P((FILE *)), - atob __P((char *, int, char *, int, int *)); -extern void doachkpt __P((void)), - doadump __P((void)); -#ifdef ALLOW_UPDATES -extern void zonedump __P((struct zoneinfo *)); -#endif -/* --from db_dump.c-- */ - -/* ++from db_load.c++ */ -extern void endline __P((FILE *)), - get_netlist __P((FILE *, struct netinfo **, - 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)), - position_on_netlist __P((struct in_addr, - struct netinfo *)); -extern struct netinfo *addr_on_netlist __P((struct in_addr, - struct netinfo *)); -/* --from db_load.c-- */ - -/* ++from db_glue.c++ */ -extern void buildservicelist __P((void)), - buildprotolist __P((void)), - gettime __P((struct timeval *)), - getname __P((struct namebuf *, char *, int)); -extern int servicenumber __P((char *)), - protocolnumber __P((char *)), - my_close __P((int)), - my_fclose __P((FILE *)), -#ifdef GEN_AXFR - get_class __P((char *)), -#endif - writemsg __P((int, u_char *, int)), - dhash __P((u_char *, int)), - samedomain __P((const char *, const char *)); -extern char *protocolname __P((int)), - *servicename __P((u_int16_t, char *)), - *savestr __P((char *)); -#ifndef BSD -extern int getdtablesize __P((void)); -#endif -extern struct databuf *rm_datum __P((struct databuf *, - struct namebuf *, - struct databuf *)); -extern struct namebuf *rm_name __P((struct namebuf *, - struct namebuf **, - struct namebuf *)); -#ifdef INVQ -extern void addinv __P((struct namebuf *, struct databuf *)), - rminv __P((struct databuf *)); -struct invbuf *saveinv __P((void)); -#endif -/* --from db_glue.c-- */ - -/* ++from db_lookup.c++ */ -extern struct namebuf *nlookup __P((char *, struct hashbuf **, - char **, int)); -extern int match __P((struct databuf *, int, int)); -/* --from db_lookup.c-- */ - -/* ++from db_secure.c++ */ -#ifdef SECURE_ZONES -extern int build_secure_netlist __P((struct zoneinfo *)); -#endif -/* --from db_secure.c-- */ diff --git a/usr.sbin/named/db_glob.h b/usr.sbin/named/db_glob.h deleted file mode 100644 index 74ae45d45763..000000000000 --- a/usr.sbin/named/db_glob.h +++ /dev/null @@ -1,93 +0,0 @@ -/* - * from db.h 4.16 (Berkeley) 6/1/90 - * $Id: db_glob.h,v 1.2 1994/04/12 08:57:50 vixie Exp $ - */ - -/* - * ++Copyright++ 1985, 1990 - * - - * Copyright (c) 1985, 1990 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - - * Portions Copyright (c) 1993 by Digital Equipment Corporation. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies, and that - * the name of Digital Equipment Corporation not be used in advertising or - * publicity pertaining to distribution of the document or software without - * specific, written prior permission. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT - * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - * - - * --Copyright-- - */ - -/* - * Global variables for data base routines. - */ - - /* ONE_WEEK maximum ttl */ -DECL int max_cache_ttl INIT(7*24*60*60); - - /* 5 minute minimum ttl */ -DECL int min_cache_ttl INIT(5*60); - - /* current line number */ -DECL int lineno; - -#ifdef DUMPFILE -DECL char *dumpfile INIT(DUMPFILE); -#else -DECL char *dumpfile INIT(_PATH_DUMPFILE); -#endif - - /* root hash table */ -DECL struct hashbuf *hashtab INIT(NULL); - - /* hash table of cache read from file */ -DECL struct hashbuf *fcachetab INIT(NULL); - -#ifdef INVQ - /* Inverse query hash table */ -DECL struct invbuf *invtab[INVHASHSZ]; -#endif - -#ifdef FORCED_RELOAD -DECL int reloading INIT(0); -#endif /* FORCED_RELOAD */ diff --git a/usr.sbin/named/db_glue.c b/usr.sbin/named/db_glue.c deleted file mode 100644 index f3f306941ba4..000000000000 --- a/usr.sbin/named/db_glue.c +++ /dev/null @@ -1,710 +0,0 @@ -#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 4.9.1.12 1994/07/22 08:42:39 vixie Exp $"; -#endif /* not lint */ - -/* - * ++Copyright++ 1986, 1988 - * - - * Copyright (c) 1986, 1988 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - - * Portions Copyright (c) 1993 by Digital Equipment Corporation. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies, and that - * the name of Digital Equipment Corporation not be used in advertising or - * publicity pertaining to distribution of the document or software without - * specific, written prior permission. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT - * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - * - - * --Copyright-- - */ - -#include <sys/types.h> -#include <sys/uio.h> -#include <sys/param.h> -#include <sys/stat.h> -#include <netinet/in.h> -#include <arpa/nameser.h> -#include <stdio.h> -#include <syslog.h> -#include <ctype.h> -#include <netdb.h> -#include <resolv.h> -#include <errno.h> - -#include "named.h" - -struct valuelist { - struct valuelist *next, *prev; - char *name; - char *proto; - int port; -} *servicelist, *protolist; - -#if defined(ultrix) -/* ultrix 4.0 has some icky packaging details. work around them here. - * since this module is linked into named and named-xfer, we end up - * forcing both to drag in our own res_send rather than ultrix's hesiod - * version of that. - */ -static const int (*unused_junk)__P((const u_char *, int, u_char *, int)) = - res_send; -; -#endif - -void -buildservicelist() -{ - struct servent *sp; - struct valuelist *slp; - -#ifdef MAYBE_HESIOD - setservent(0); -#else - setservent(1); -#endif - while (sp = getservent()) { - slp = (struct valuelist *)malloc(sizeof(struct valuelist)); - slp->name = savestr(sp->s_name); - slp->proto = savestr(sp->s_proto); - slp->port = ntohs((u_int16_t)sp->s_port); - slp->next = servicelist; - slp->prev = NULL; - if (servicelist) - servicelist->prev = slp; - servicelist = slp; - } - endservent(); -} - -void -buildprotolist() -{ - struct protoent *pp; - struct valuelist *slp; - -#ifdef MAYBE_HESIOD - setprotoent(0); -#else - setprotoent(1); -#endif - while (pp = getprotoent()) { - slp = (struct valuelist *)malloc(sizeof(struct valuelist)); - slp->name = savestr(pp->p_name); - slp->port = pp->p_proto; - slp->next = protolist; - slp->prev = NULL; - if (protolist) - protolist->prev = slp; - protolist = slp; - } - endprotoent(); -} - -static int -findservice(s, list) - register char *s; - register struct valuelist **list; -{ - register struct valuelist *lp = *list; - int n; - - for (; lp != NULL; lp = lp->next) - if (strcasecmp(lp->name, s) == 0) { - if (lp != *list) { - lp->prev->next = lp->next; - if (lp->next) - lp->next->prev = lp->prev; - (*list)->prev = lp; - lp->next = *list; - *list = lp; - } - return (lp->port); - } - if (sscanf(s, "%d", &n) != 1 || n <= 0) - n = -1; - return (n); -} - -/* - * Convert service name or (ascii) number to int. - */ -int -servicenumber(p) - char *p; -{ - return (findservice(p, &servicelist)); -} - -/* - * Convert protocol name or (ascii) number to int. - */ -int -protocolnumber(p) - char *p; -{ - return (findservice(p, &protolist)); -} - -#if defined(__STDC__) || defined(__GNUC__) -static struct servent * -cgetservbyport(u_int16_t port, - char *proto) -#else -static struct servent * -cgetservbyport(port, proto) - u_int16_t port; - char *proto; -#endif -{ - register struct valuelist **list = &servicelist; - register struct valuelist *lp = *list; - static struct servent serv; - - port = htons(port); - for (; lp != NULL; lp = lp->next) { - if (port != (u_int16_t)lp->port) - continue; - if (strcasecmp(lp->proto, proto) == 0) { - if (lp != *list) { - lp->prev->next = lp->next; - if (lp->next) - lp->next->prev = lp->prev; - (*list)->prev = lp; - lp->next = *list; - *list = lp; - } - serv.s_name = lp->name; - serv.s_port = htons((u_int16_t)lp->port); - serv.s_proto = lp->proto; - return (&serv); - } - } - return (0); -} - -static struct protoent * -cgetprotobynumber(proto) - register int proto; -{ - register struct valuelist **list = &protolist; - register struct valuelist *lp = *list; - static struct protoent prot; - - for (; lp != NULL; lp = lp->next) - if (lp->port == proto) { - if (lp != *list) { - lp->prev->next = lp->next; - if (lp->next) - lp->next->prev = lp->prev; - (*list)->prev = lp; - lp->next = *list; - *list = lp; - } - prot.p_name = lp->name; - prot.p_proto = lp->port; - return (&prot); - } - return (0); -} - -char * -protocolname(num) - int num; -{ - static char number[8]; - struct protoent *pp; - - pp = cgetprotobynumber(num); - if(pp == 0) { - (void) sprintf(number, "%d", num); - return (number); - } - return (pp->p_name); -} - -#if defined(__STDC__) || defined(__GNUC__) -char * -servicename(u_int16_t port, char *proto) -#else -char * -servicename(port, proto) - u_int16_t port; - char *proto; -#endif -{ - static char number[8]; - struct servent *ss; - - ss = cgetservbyport(htons(port), proto); - if (ss == 0) { - (void) sprintf(number, "%d", port); - return (number); - } - return (ss->s_name); -} - -int -db_getclev(origin) - char *origin; -{ - int lev = 0; - dprintf(1, (ddt, "db_getclev of \"%s\"", origin)); - if (origin && *origin) - lev++; - while (origin && (origin = strchr(origin, '.'))) { - origin++; - lev++; - } - dprintf(1, (ddt, " = %d\n", lev)); - return (lev); -} - -void -gettime(ttp) - struct timeval *ttp; -{ - if (gettimeofday(ttp, NULL) < 0) - syslog(LOG_ERR, "gettimeofday: %m"); - return; -} - -#if !defined(BSD) -int -getdtablesize() -{ -#if defined(USE_POSIX) - int j = (int) sysconf(_SC_OPEN_MAX); - - if (j >= 0) - return (j); -#endif /* POSIX */ - return (FD_SETSIZE); -} -#endif /* BSD */ - -int -my_close(fd) - int fd; -{ - int s = close(fd); - - if (s < 0) { - syslog(LOG_ERR, "close(%d) failed: %m", fd); - dprintf(3, (ddt, "close(%d) failed: %s\n", - fd, strerror(errno))); - } else { - dprintf(3, (ddt, "close(%d) succeeded\n", fd)); - } - return (s); -} - -#ifdef GEN_AXFR -/* - * Map class names to number - */ -struct map { - char *token; - int val; -}; - -static struct map map_class[] = { - "in", C_IN, - "chaos", C_CHAOS, - "hs", C_HS, - NULL, 0, -}; - -int -get_class(class) - char *class; -{ - struct map *mp; - - if (isdigit(*class)) - return (atoi(class)); - for (mp = map_class; mp->token != NULL; mp++) - if (strcasecmp(class, mp->token) == 0) - return (mp->val); - return (C_IN); -} -#endif - -int -my_fclose(fp) - FILE *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 { - dprintf(3, (ddt, "fclose(%d) succeeded\n", fd)); - } - return (s); -} - -/* - * Make a copy of a string and return a pointer to it. - */ -char * -savestr(str) - char *str; -{ - char *cp; - - cp = (char *)malloc(strlen(str) + 1); - if (cp == NULL) { - syslog(LOG_ERR, "savestr: %m"); - exit(1); - } - (void) strcpy(cp, str); - return (cp); -} - -int -writemsg(rfd, msg, msglen) - int rfd; - u_char *msg; - int msglen; -{ - struct iovec iov[2]; - u_char len[INT16SZ]; - - __putshort(msglen, len); - iov[0].iov_base = (char *)len; - iov[0].iov_len = INT16SZ; - iov[1].iov_base = (char *)msg; - iov[1].iov_len = msglen; - if (writev(rfd, iov, 2) != INT16SZ + msglen) { - dprintf(1, (ddt, "write failed %d\n", errno)); - return (-1); - } - return (0); -} - -/* rm_datum(dp, np, pdp) - * remove datum 'dp' from name 'np'. pdp is previous data pointer. - * return value: - * "next" field from removed datum, suitable for relinking - */ -struct databuf * -rm_datum(dp, np, pdp) - register struct databuf *dp; - register struct namebuf *np; - register struct databuf *pdp; -{ - register struct databuf *ndp = dp->d_next; - - dprintf(3, (ddt, "rm_datum(%x, %x, %x) -> %x\n", - dp, np->n_data, pdp, ndp)); -#ifdef INVQ - rminv(dp); -#endif - if (pdp == NULL) - np->n_data = ndp; - else - pdp->d_next = ndp; -#ifdef DATUMREFCNT - if (--(dp->d_rcnt)) { - switch(dp->d_type) { - case T_NS: - dprintf(1, (ddt, "rm_datum: %s rcnt = %d\n", - dp->d_data, dp->d_rcnt)); - break; - case T_A: - dprintf(1, (ddt, "rm_datum: %08.8X rcnt = %d\n", - *(int32_t*)(dp->d_data), dp->d_rcnt)); - break; - default: - dprintf(1, (ddt, "rm_datum: rcnt = %d\n", dp->d_rcnt)); - } - } else -#endif - free((char *)dp); - return (ndp); -} - -/* rm_name(np, he, pnp) - * remove name 'np' from parent 'pp'. pnp is previous name pointer. - * return value: - * "next" field from removed name, suitable for relinking - */ -struct namebuf * -rm_name(np, pp, pnp) - struct namebuf *np, **pp, *pnp; -{ - struct namebuf *nnp = np->n_next; - char *msg; - - /* verify */ - 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(); - } - - /* unlink */ - if (pnp) { - pnp->n_next = nnp; - } else { - *pp = nnp; - } - - /* deallocate */ - free(np->n_dname); - free((char*) np); - - /* done */ - return (nnp); -} - -/* - * Get the domain name of 'np' and put in 'buf'. Bounds checking is done. - */ -void -getname(np, buf, buflen) - struct namebuf *np; - char *buf; - int buflen; -{ - register char *cp; - register int i; - - cp = buf; - while (np != NULL) { - if ((i = strlen(np->n_dname))+1 >= buflen) { - *cp = '\0'; - syslog(LOG_ERR, "domain name too long: %s...\n", buf); - strcpy(buf, "Name_Too_Long"); - return; - } - if (cp != buf) - *cp++ = '.'; - (void) strcpy(cp, np->n_dname); - cp += i; - buflen -= (i+1); - np = np->n_parent; - } - *cp = '\0'; -} - -#ifdef INVQ -/* - * Add data 'dp' to inverse query tables for name 'np'. - */ -void -addinv(np, dp) - struct namebuf *np; - struct databuf *dp; -{ - register struct invbuf *ip; - register int hval, i; - - switch (dp->d_type) { - case T_A: - case T_UID: - case T_GID: - break; - - default: - return; - } - - hval = dhash(dp->d_data, dp->d_size); - for (ip = invtab[hval]; ip != NULL; ip = ip->i_next) - for (i = 0; i < INVBLKSZ; i++) - if (ip->i_dname[i] == NULL) { - ip->i_dname[i] = np; - return; - } - ip = saveinv(); - ip->i_next = invtab[hval]; - invtab[hval] = ip; - ip->i_dname[0] = np; -} - -/* - * Remove data 'odp' from inverse query table. - */ -void -rminv(odp) - struct databuf *odp; -{ - register struct invbuf *ip; - register struct databuf *dp; - struct namebuf *np; - register int i; - - for (ip = invtab[dhash(odp->d_data, odp->d_size)]; ip != NULL; - ip = ip->i_next) { - for (i = 0; i < INVBLKSZ; i++) { - if ((np = ip->i_dname[i]) == NULL) - break; - for (dp = np->n_data; dp != NULL; dp = dp->d_next) { - if (dp != odp) - continue; - while (i < INVBLKSZ-1) { - ip->i_dname[i] = ip->i_dname[i+1]; - i++; - } - ip->i_dname[i] = NULL; - return; - } - } - } -} - -/* - * Allocate an inverse query buffer. - */ -struct invbuf * -saveinv() -{ - register struct invbuf *ip; - - ip = (struct invbuf *) malloc(sizeof(struct invbuf)); - if (ip == NULL) { - syslog(LOG_ERR, "saveinv: %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; - int dlen; -{ - register u_char *cp; - register unsigned hval; - register int n; - - n = dlen; - if (n > 8) - n = 8; - hval = 0; - for (cp = dp; --n >= 0; ) { - hval <<= 1; - hval += *cp++; - } - return (hval % INVHASHSZ); -} - -/* -** SAMEDOMAIN -- Check whether a name belongs to a domain -** ------------------------------------------------------ -** -** Returns: -** TRUE if the given name lies in the domain. -** FALSE otherwise. -** -** Trailing dots are first removed from name and domain. -** Always compare complete subdomains, not only whether the -** domain name is the trailing string of the given name. -** -** "host.foobar.top" lies in "foobar.top" and in "top" and in "" -** but NOT in "bar.top" -** -** this implementation of samedomain() is thanks to Bob Heiney. -*/ - -int -samedomain(a, b) - const char *a, *b; -{ - size_t la, lb; - const char *cp; - - la = strlen(a); - lb = strlen(b); - - /* don't count trailing dots, if any. */ - if (la && a[la-1]=='.') - la--; - if (lb && b[lb-1]=='.') - lb--; - - /* lb==0 means b is the root domain, so a must be in b. */ - if (lb == 0) - return (1); - - /* b longer than a means a can't be in b. */ - if (lb > la) - return (0); - - /* We use strncasecmp because we might be trying to - * ignore trailing dots. */ - if (lb == la) - return (strncasecmp(a, b, lb) == 0); - - /* Ok, we know la > lb. */ - - /* Point at the character before the last 'lb' characters of a. */ - cp = a + (la - lb - 1); - - /* If it isn't '.', can't be a match (this lets us avoid - * having "foobar.com" match "bar.com"). */ - if (*cp != '.') - return (0); - - cp++; - - /* We use strncasecmp because we might be trying to - * ignore trailing dots. */ - return (strncasecmp(cp, b, lb)==0); -} diff --git a/usr.sbin/named/db_load.c b/usr.sbin/named/db_load.c deleted file mode 100644 index dfd46e3af38f..000000000000 --- a/usr.sbin/named/db_load.c +++ /dev/null @@ -1,1214 +0,0 @@ -#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 4.9.1.18 1994/07/23 23:23:56 vixie Exp $"; -#endif /* not lint */ - -/* - * ++Copyright++ 1986, 1988, 1990 - * - - * Copyright (c) 1986, 1988, 1990 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - - * Portions Copyright (c) 1993 by Digital Equipment Corporation. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies, and that - * the name of Digital Equipment Corporation not be used in advertising or - * publicity pertaining to distribution of the document or software without - * specific, written prior permission. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT - * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - * - - * --Copyright-- - */ - -/* - * Load data base from ascii backupfile. Format similar to RFC 883. - */ - -#include <sys/param.h> -#include <sys/stat.h> -#include <netinet/in.h> -#include <arpa/nameser.h> -#include <arpa/inet.h> -#include <stdio.h> -#include <syslog.h> -#include <ctype.h> -#include <netdb.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 empty_token = 0; - -/* - * Map class and type names to number - */ -struct map { - char token[8]; - int val; -}; - -struct map m_class[] = { - "in", C_IN, -#ifdef notdef - "any", C_ANY, /* any is a QCLASS, not CLASS */ -#endif - "chaos", C_CHAOS, - "hs", C_HS, -}; -#define NCLASS (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, -#ifdef notdef - "any", T_ANY, /* any is a QTYPE, not TYPE */ -#endif -#ifdef ALLOW_T_UNSPEC - "unspec", T_UNSPEC, -#endif /* ALLOW_T_UNSPEC */ -}; -#define NTYPE (sizeof(m_type) / sizeof(struct map)) - -/* - * Parser token values - */ -#define CURRENT 1 -#define DOT 2 -#define AT 3 -#define DNAME 4 -#define INCLUDE 5 -#define ORIGIN 6 -#define ERROR 7 - -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. - * 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; - struct zoneinfo *zp; - int doinginclude; -{ - register char *cp; - register struct map *mp; - char domain[MAXDNAME]; - char origin[MAXDNAME]; - char tmporigin[MAXDNAME]; - char buf[MAXDATA]; - char data[MAXDATA]; - char *cp1; - char *op; - int c, class, type, ttl, dbflags, dataflags, multiline; - static int read_soa; /* number of soa's read */ - struct databuf *dp; - FILE *fp; - int slineno, i, errs = 0, didinclude = 0; - register u_int32_t n; - struct stat sb; - struct in_addr ina; - - if (!doinginclude) { - read_soa = 0; - clev = db_getclev(in_origin); - } - - dprintf(1, (ddt,"db_load(%s, %s, %d, %d)\n", - filename, in_origin, zp - zones, doinginclude)); - - (void) strcpy(origin, in_origin); - if ((fp = fopen(filename, "r")) == NULL) { - syslog(LOG_ERR, "%s: %m", filename); - dprintf(1, (ddt, "db_load: error opening file %s\n", - filename)); - return (-1); - } - if (zp->z_type == Z_CACHE) { - dbflags = DB_NODATA | DB_NOHINTS; - dataflags = DB_F_HINT; - } else { - dbflags = DB_NODATA; - dataflags = 0; - } - gettime(&tt); - if (fstat(fileno(fp), &sb) < 0) { - syslog(LOG_ERR, "%s: %m", filename); - sb.st_mtime = (int)tt.tv_sec; - } - slineno = lineno; - lineno = 1; - domain[0] = '\0'; - class = zp->z_class; - zp->z_flags &= ~(Z_INCLUDE|Z_DB_BAD); - while ((c = gettoken(fp, filename)) != EOF) { - switch (c) { - case INCLUDE: - if (!getword((char *)buf, sizeof(buf), fp)) - /* file name*/ - break; - if (!getword(tmporigin, sizeof(tmporigin), fp)) - strcpy(tmporigin, origin); - else { - makename(tmporigin, origin); - endline(fp); - } - didinclude = 1; - errs += db_load((char *)buf, tmporigin, zp, 1); - continue; - - case ORIGIN: - (void) strcpy((char *)buf, origin); - if (!getword(origin, sizeof(origin), fp)) - break; - dprintf(3, (ddt, "db_load: origin %s, buf %s\n", - origin, buf)); - makename(origin, buf); - dprintf(3, (ddt, "db_load: origin now %s\n", origin)); - continue; - - case DNAME: - if (!getword(domain, sizeof(domain), fp)) - break; - n = strlen(domain) - 1; - if (domain[n] == '.') - domain[n] = '\0'; - else if (*origin) { - (void) strcat(domain, "."); - (void) strcat(domain, origin); - } - goto gotdomain; - - case AT: - (void) strcpy(domain, origin); - goto gotdomain; - - case DOT: - domain[0] = '\0'; - /* fall thru ... */ - case CURRENT: - gotdomain: - if (!getword((char *)buf, sizeof(buf), fp)) { - if (c == CURRENT) - continue; - break; - } - cp = buf; - ttl = 0; - if (isdigit(*cp)) { - n = 0; - do { - if (n > (INT_MAX - (*cp - '0')) / 10) { - syslog(LOG_ERR, - "%s: line %d: number > %lu\n", - filename, lineno, INT_MAX); - dprintf(1, (ddt, - "%s: line %d: number > %lu\n", - filename, lineno, INT_MAX)); - n = INT_MAX; - cp++; - } else - n = n * 10 + (*cp++ - '0'); - } - while (isdigit(*cp)); - if (zp->z_type == Z_CACHE) { - /* this allows the cache entry to age */ - /* while sitting on disk (powered off) */ - if (n > max_cache_ttl) - n = max_cache_ttl; - n += sb.st_mtime; - } - ttl = n; - if (!getword((char *)buf, sizeof(buf), fp)) - break; - } - for (mp = m_class; mp < m_class+NCLASS; 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++) - if (!strcasecmp((char *)buf, mp->token)) { - type = mp->val; - goto fndtype; - } - dprintf(1, (ddt, "%s: Line %d: Unknown type: %s.\n", - filename, lineno, buf)); - errs++; - syslog(LOG_ERR, "%s: Line %d: Unknown type: %s.\n", - filename, lineno, buf); - break; - fndtype: -#ifdef ALLOW_T_UNSPEC - /* Don't do anything here for T_UNSPEC... - * read input separately later - */ - if (type != T_UNSPEC) { -#endif - if (!getword((char *)buf, sizeof(buf), fp)) - break; - dprintf(3, - (ddt, - "d='%s', c=%d, t=%d, ttl=%d, data='%s'\n", - domain, class, type, ttl, buf)); -#ifdef ALLOW_T_UNSPEC - } -#endif - /* - * Convert the ascii data 'buf' to the proper format - * based on the type and pack into 'data'. - */ - switch (type) { - case T_A: - if (!inet_aton(buf, &ina)) - goto err; - n = ntohl(ina.s_addr); - cp = data; - PUTLONG(n, cp); - n = INT32SZ; - break; - - case T_HINFO: - case T_ISDN: - n = strlen((char *)buf); - if (n > 255) { - syslog(LOG_WARNING, - "%s: line %d: CPU type too long", - filename, lineno); - n = 255; - } - data[0] = n; - bcopy(buf, (char *)data + 1, (int)n); - if (n == 0) - goto err; - n++; - if (!getword((char *)buf, sizeof(buf), fp)) - i = 0; - else { - endline(fp); - i = strlen((char *)buf); - } - if (i == 0) { - /* goto err; */ - /* XXX tolerate for now */ - data[n++] = 1; - data[n++] = '?'; - break; - } - if (i > 255) { - syslog(LOG_WARNING, - "%s:%d: OS type too long", - filename, lineno); - i = 255; - } - data[n] = i; - bcopy(buf, data + n + 1, i); - n += i + 1; - break; - - case T_SOA: - case T_MINFO: - case T_RP: - (void) strcpy((char *)data, (char *)buf); - makename(data, origin); - cp = data + strlen((char *)data) + 1; - if (!getword((char *)cp, - sizeof(data) - (cp - data), fp)) - goto err; - makename(cp, origin); - cp += strlen((char *)cp) + 1; - if (type != T_SOA) { - n = cp - data; - break; - } - if (class != zp->z_class) { - syslog(LOG_WARNING, - "%s:%d: %s", - filename, lineno, - "SOA class not same as zone's"); - } - c = getnonblank(fp, filename); - if (c == '(') { - multiline = 1; - } else { - multiline = 0; - ungetc(c, fp); - } - zp->z_serial = getnum(fp, filename, 1); - n = (u_int32_t) zp->z_serial; - PUTLONG(n, cp); - zp->z_refresh = getnum(fp, filename, 0); - n = (u_int32_t) zp->z_refresh; - PUTLONG(n, cp); - if (zp->z_type == Z_SECONDARY -#if defined(STUBS) - || zp->z_type == Z_STUB -#endif - ) { - zp->z_time = sb.st_mtime - + zp->z_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); - n = (u_int32_t) zp->z_expire; - PUTLONG (n, cp); - zp->z_minimum = getnum(fp, filename, 0); - n = (u_int32_t) zp->z_minimum; - PUTLONG (n, cp); - n = cp - data; - if (multiline) { - if (getnonblank(fp, filename) != ')') - goto err; - } - read_soa++; - endline(fp); - break; - - case T_UID: - case T_GID: - n = 0; - cp = buf; - while (isdigit(*cp)) - n = n * 10 + (*cp++ - '0'); - if (cp == buf) - goto err; - cp = data; - PUTLONG(n, cp); - n = INT32SZ; - break; - - case T_WKS: - /* Address */ - if (!inet_aton(buf, &ina)) - goto err; - n = ntohl(ina.s_addr); - cp = data; - PUTLONG(n, cp); - *cp = (char)getprotocol(fp, filename); - /* Protocol */ - n = INT32SZ + sizeof(char); - /* Services */ - n = getservices((int)n, data, fp, filename); - break; - - case T_NS: - case T_CNAME: - case T_MB: - case T_MG: - case T_MR: - case T_PTR: - (void) strcpy((char *)data, (char *)buf); - makename(data, origin); - n = strlen((char *)data) + 1; - break; - - case T_UINFO: - cp = strchr((char *)buf, '&'); - bzero(data, sizeof(data)); - if ( cp != NULL) { - (void) strncpy((char *)data, - (char *)buf, cp - buf); - op = strchr(domain, '.'); - if ( op != NULL) - (void) strncat((char *)data, - domain,op-domain); - else - (void) strcat((char *)data, - domain); - (void) strcat((char *)data, - (char *)++cp); - } else - (void) strcpy((char *)data, - (char *)buf); - n = strlen((char *)data) + 1; - break; - case T_MX: - case T_AFSDB: - case T_RT: - n = 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 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; - /* - * there is expansion here so make sure we - * don't overflow data - */ - if (i > sizeof(data) * 255 / 256) { - syslog(LOG_WARNING, - "%s: line %d: TXT record truncated", - filename, lineno); - i = sizeof(data) * 255 / 256; - } - while (i > 255) { - *cp++ = 255; - bcopy(cp1, cp, 255); - cp += 255; - cp1 += 255; - i -= 255; - } - *cp++ = i; - bcopy(cp1, cp, i); - cp += i; - n = cp - data; - endline(fp); - break; - - case T_NSAP: - n = inet_nsap_addr(buf, data, MAXDATA); - if (n == 0) - goto err; - endline(fp); - break; -#ifdef ALLOW_T_UNSPEC - case T_UNSPEC: - { - int rcode; - fgets(buf, sizeof(buf), fp); - dprintf(1, (ddt, "loading T_UNSPEC\n")); - if (rcode = atob(buf, - strlen((char*)buf), - data, sizeof(data), - &n)) { - if (rcode == CONV_OVERFLOW) { - dprintf(1, - (ddt, - "Load T_UNSPEC: input buffer overflow\n" - ) - ); - errs++; - syslog(LOG_ERR, - "Load T_UNSPEC: input buffer overflow"); - } else { - dprintf(1, - (ddt, - "Load T_UNSPEC: Data in bad atob format\n" - ) - ); - errs++; - syslog(LOG_ERR, - "Load T_UNSPEC: Data in bad atob format"); - } - } - } - break; -#endif /* ALLOW_T_UNSPEC */ - - default: - goto err; - } -#ifdef STUBS - if (type == T_SOA && zp->z_type == Z_STUB) - continue; -#endif -#ifdef NO_GLUE - /* - * Ignore data outside the zone. - */ - if (zp->z_type != Z_CACHE && - !samedomain(domain, zp->z_origin)) - { - syslog(LOG_WARNING, - "%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; - dp->d_flags = dataflags; - dp->d_cred = DB_C_ZONE; - dp->d_clev = clev; - if ((c = db_update(domain, dp, dp, dbflags, - (zp->z_type == Z_CACHE) - ? fcachetab - : hashtab)) - != OK) { -#ifdef DEBUG - if (debug && (c != DATAEXISTS)) - fprintf(ddt, "update failed %s %d\n", - domain, type); -#endif - free((char*) dp); - } - continue; - - case ERROR: - break; - } - err: - errs++; - syslog(LOG_ERR, "%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++; - } - (void) my_fclose(fp); - lineno = slineno; - if (doinginclude == 0) { - 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 (read_soa == 0) - syslog(LOG_ERR, "%s: no SOA record", filename); - else - syslog(LOG_ERR, "%s: multiple SOA records", - filename); - } - } -#ifdef SECURE_ZONES - build_secure_netlist(zp); -#endif - if (errs) - zp->z_flags |= Z_DB_BAD; - return (errs); -} - -static int -gettoken(fp, src) - register FILE *fp; - char *src; -{ - register int c; - char op[32]; - - for (;;) { - c = getc(fp); - top: - switch (c) { - case EOF: - return (EOF); - - case '$': - if (getword(op, sizeof(op), fp)) { - if (!strcasecmp("include", op)) - return (INCLUDE); - 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", - src, lineno, op); - return (ERROR); - - case ';': - while ((c = getc(fp)) != EOF && c != '\n') - ; - goto top; - - case ' ': - case '\t': - return (CURRENT); - - case '.': - return (DOT); - - case '@': - return (AT); - - case '\n': - lineno++; - continue; - - default: - (void) ungetc(c, fp); - return (DNAME); - } - } -} - -/* int - * getword(buf, size, fp) - * get next word, skipping blanks & comments. - * parameters: - * buf - destination - * size - of destination - * fp - file to read from - * return value: - * 0 = no word; perhaps EOL or EOF - * 1 = word was read - */ -int -getword(buf, size, fp) - char *buf; - int size; - FILE *fp; -{ - register char *cp; - register int c; - - empty_token = 0; - for (cp = buf; (c = getc(fp)) != EOF; ) { - if (c == ';') { - while ((c = getc(fp)) != EOF && c != '\n') - ; - c = '\n'; - } - if (c == '\n') { - if (cp != buf) - ungetc(c, fp); - else - lineno++; - break; - } - if (isspace(c)) { - while (isspace(c = getc(fp)) && c != '\n') - ; - ungetc(c, fp); - if (cp != buf) /* Trailing whitespace */ - break; - continue; /* Leading whitespace */ - } - if (c == '"') { - while ((c = getc(fp)) != EOF && c != '"' && c != '\n') { - if (c == '\\') { - if ((c = getc(fp)) == EOF) - c = '\\'; - if (c == '\n') - lineno++; - } - if (cp >= buf+size-1) - break; - *cp++ = c; - } - if (c == '\n') { - lineno++; - break; - } - if ((c = getc(fp)) != EOF) - ungetc(c, fp); - if (c == EOF || isspace(c) || c == '\n') { - *cp = '\0'; - return (1); - } - else - continue; - } - if (c == '\\') { - if ((c = getc(fp)) == EOF) - c = '\\'; - if (c == '\n') - lineno++; - } - if (cp >= buf+size-1) - break; - *cp++ = (char)c; - } - *cp = '\0'; - if (cp == buf) - empty_token = 1; - return (cp != buf); -} - -/* -From: kagotani@cs.titech.ac.jp -Message-Id: <9007040716.AA26646@saeko.cs.titech.ac.jp> -Subject: named bug report and fix -Date: Wed, 04 Jul 90 16:16:52 JST - -I found a bug in the BIND source code. Named with this bug parses -the serial_no field of SOA records incorrectly. For example: - expression internal - in files expression I expect - 1. 1000 10000 - 1.2 10002 10002 - 1.23 100023 10023 - 2.3 20003 20003 -Especially I can not accept that "2.3" is treated as if it is -smaller than "1.23" in their internal expressions. - -[ if you define SENSIBLE_DOTS in ../conf/options.h, you get - m. kagotani's expected behaviour. this is NOT compatible - with pre-4.9 versions of BIND. --vix ] -*/ - -int -getnum(fp, src, is_serial) - FILE *fp; - char *src; - int is_serial; -{ - register int c, n; - int seendigit = 0; - int seendecimal = 0; - int m = 0; - int allow_dots = 0; - -#ifdef DOTTED_SERIAL - allow_dots += is_serial; -#endif - for (n = 0; (c = getc(fp)) != EOF; ) { - if (isspace(c)) { - if (c == '\n') - lineno++; - if (seendigit) - break; - continue; - } - if (c == ';') { - while ((c = getc(fp)) != EOF && c != '\n') - ; - if (c == '\n') - lineno++; - if (seendigit) - break; - continue; - } - if (!isdigit(c)) { - if (c == ')' && seendigit) { - (void) ungetc(c, fp); - break; - } - if (seendecimal || c != '.' || !allow_dots) { - syslog(LOG_ERR, "%s:%d: expected a number", - src, lineno); - dprintf(1, (ddt, "%s:%d: expected a number", - src, lineno)); - exit(1); /* XXX why exit here?? */ - } else { - if (!seendigit) - n = 1; -#ifdef SENSIBLE_DOTS - n = n * 10000; -#else - n = n * 1000; -#endif - seendigit = 1; - seendecimal = 1; - } - continue; - } -#ifdef SENSIBLE_DOTS - if (seendecimal) - m = m * 10 + (c - '0'); - else - n = n * 10 + (c - '0'); -#else - n = n * 10 + (c - '0'); -#endif - seendigit = 1; - } - if (m > 9999) { - syslog(LOG_ERR, - "%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?? */ - } - if (seendecimal) { - syslog(LOG_INFO, - "%s:%d: decimal serial number interpreted as %d", - src, lineno, n+m); - } - return (n + m); -} - -static int -getnonblank(fp, src) - FILE *fp; - char *src; -{ - register int c; - - while ( (c = getc(fp)) != EOF ) { - if (isspace(c)) { - if (c == '\n') - lineno++; - continue; - } - if (c == ';') { - while ((c = getc(fp)) != EOF && c != '\n') - ; - if (c == '\n') - lineno++; - continue; - } - return(c); - } - syslog(LOG_ERR, "%s: line %d: unexpected EOF", src, lineno); - dprintf(1, (ddt, "%s: line %d: unexpected EOF", src, lineno)); - return (EOF); -} - -/* - * Take name and fix it according to following rules: - * "." means root. - * "@" means current origin. - * "name." means no changes. - * "name" means append origin. - */ -static void -makename(name, origin) - char *name, *origin; -{ - int n; - - if (origin[0] == '.') - origin++; - n = strlen(name); - if (n == 1) { - if (name[0] == '.') { - name[0] = '\0'; - return; - } - if (name[0] == '@') { - (void) strcpy(name, origin); - return; - } - } - if (n > 0) { - if (name[n - 1] == '.') - name[n - 1] = '\0'; - else if (origin[0] != '\0') { - name[n] = '.'; - (void) strcpy(name + n + 1, origin); - } - } -} - -void -endline(fp) - register FILE *fp; -{ - register int c; - - while (c = getc(fp)) { - if (c == '\n') { - (void) ungetc(c,fp); - break; - } else if (c == EOF) { - break; - } - } -} - -#define MAXPORT 256 -#define MAXLEN 24 - -static int -getprotocol(fp, src) - FILE *fp; - char *src; -{ - int k; - char b[MAXLEN]; - - (void) getword(b, sizeof(b), fp); - - k = protocolnumber(b); - if(k == -1) - syslog(LOG_ERR, "%s: line %d: unknown protocol: %s.", - src, lineno, b); - return(k); -} - -static int -getservices(n, data, fp, src) - int n; - char *data, *src; - FILE *fp; -{ - int j, ch; - int k; - int maxl; - int bracket; - char b[MAXLEN]; - char bm[MAXPORT/8]; - - for (j = 0; j < MAXPORT/8; j++) - bm[j] = 0; - maxl = 0; - bracket = 0; - while (getword(b, sizeof(b), fp) || bracket) { - if (feof(fp) || ferror(fp)) - break; - if (strlen(b) == 0) - continue; - if ( b[0] == '(') { - bracket++; - continue; - } - if ( b[0] == ')') { - bracket = 0; - while ((ch = getc(fp)) != EOF && ch != '\n') - ; - if (ch == '\n') - lineno++; - break; - } - k = servicenumber(b); - if (k == -1) { - syslog(LOG_WARNING, - "%s: line %d: Unknown service '%s'", - src, lineno, b); - continue; - } - if ((k < MAXPORT) && (k)) { - bm[k/8] |= (0x80>>(k%8)); - if (k > maxl) - maxl=k; - } - else { - syslog(LOG_WARNING, - "%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); - maxl = maxl/8+1; - bcopy(bm, data+n, maxl); - return(maxl+n); -} - -/* get_netlist(fp, netlistp, allow) - * get list of nets from 'fp', put on *netlistp, 'allow' controls - * whether hosts, nets, or both shall be accepted without warnings. - * (note that they are always accepted; 'allow' just controls the - * warnings.) - */ -void -get_netlist(fp, netlistp, allow, print_tag) - FILE *fp; - struct netinfo **netlistp; - int allow; - char *print_tag; -{ - struct netinfo *ntp = NULL, **end = netlistp; - char buf[BUFSIZ], *maskp; - struct in_addr ina; - - dprintf(1, (ddt, "get_netlist(%s)", print_tag)); - while (getword(buf, sizeof(buf), fp)) { - if (strlen(buf) == 0) - break; - if ((maskp = strchr(buf, '&')) != NULL) - *maskp++ = '\0'; - dprintf(1, (ddt," %s", buf)); - if (ntp == NULL) { - ntp = (struct netinfo *)malloc(sizeof(struct netinfo)); - } - if (!inet_aton(buf, &ntp->my_addr)) { - syslog(LOG_ERR, "%s contains bogus element (%s)", - print_tag, buf); - continue; - } - if (maskp) { - if (!inet_aton(maskp, &ina)) { - syslog(LOG_ERR, - "%s element %s has bad mask (%s)", - print_tag, buf, maskp); - continue; - } - } else { - if (allow & ALLOW_HOSTS) - ina.s_addr = 0xffffffff; /* "exact" */ - else - ina.s_addr = net_mask(ntp->my_addr); - } - ntp->next = NULL; - ntp->mask = ina.s_addr; - ntp->addr = ntp->my_addr.s_addr & ntp->mask; - - /* Check for duplicates */ - if (addr_on_netlist(ntp->my_addr, *netlistp)) - continue; - - if (ntp->addr != ntp->my_addr.s_addr) { - ina.s_addr = ntp->addr; - syslog(LOG_WARNING, - "%s element (%s) mask problem (%s)", - print_tag, buf, inet_ntoa(ina)); - } - - *end = ntp; - end = &ntp->next; - ntp = NULL; - } - if (ntp) - free((char *)ntp); - - dprintf(1, (ddt, "\n")); -#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, " %s", inet_ntoa(ntp->my_addr)); - fprintf(ddt, " next x%x\n", ntp->next); - } -#endif -} - -struct netinfo * -addr_on_netlist(addr, netlist) - struct in_addr addr; - struct netinfo *netlist; -{ - u_int32_t a = addr.s_addr; - struct netinfo *t; - - for (t = netlist; t != NULL; t = t->next) - if (t->addr == (a & t->mask)) - return t; - return NULL; -} - -int -position_on_netlist(addr, netlist) - struct in_addr addr; - struct netinfo *netlist; -{ - u_int32_t a = addr.s_addr; - struct netinfo *t; - int position = 0; - - for (t = netlist; t != NULL; t = t->next) - if (t->addr == (a & t->mask)) - break; - else - position++; - return position; -} - -void -free_netlist(netlistp) - struct netinfo **netlistp; -{ - register struct netinfo *ntp, *next; - - for (ntp = *netlistp; ntp != NULL; ntp = next) { - next = ntp->next; - free((char *)ntp); - } - *netlistp = NULL; -} diff --git a/usr.sbin/named/db_lookup.c b/usr.sbin/named/db_lookup.c deleted file mode 100644 index 9084491c9137..000000000000 --- a/usr.sbin/named/db_lookup.c +++ /dev/null @@ -1,196 +0,0 @@ -#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 4.9.1.5 1994/06/01 21:09:39 vixie Exp $"; -#endif /* not lint */ - -/* - * ++Copyright++ 1986 - * - - * Copyright (c) 1986 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - - * Portions Copyright (c) 1993 by Digital Equipment Corporation. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies, and that - * the name of Digital Equipment Corporation not be used in advertising or - * publicity pertaining to distribution of the document or software without - * specific, written prior permission. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT - * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - * - - * --Copyright-- - */ - -/* - * Table lookup routines. - */ - -#include <syslog.h> -#include <sys/param.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/nameser.h> -#include <stdio.h> -#include <ctype.h> - -#include "named.h" - -/* - * Lookup 'name' and return a pointer to the namebuf; - * NULL otherwise. If 'insert', insert name into tables. - * Wildcard lookups are handled. - */ -struct namebuf * -nlookup(name, htpp, fname, insert) - char *name; - struct hashbuf **htpp; - char **fname; - int insert; -{ - register struct namebuf *np; - register char *cp; - register int c; - register unsigned hval; - register struct hashbuf *htp; - struct namebuf *parent = NULL; - - htp = *htpp; - hval = 0; - *fname = "???"; - for (cp = name; c = *cp++; ) { - if (c == '.') { - parent = np = nlookup(cp, htpp, fname, insert); - if (np == NULL) - return (NULL); - if (*fname != cp) - return (np); - if ((htp = np->n_hash) == NULL) { - if (!insert) { - if (np->n_dname[0] == '*' && - np->n_dname[1] == '\0') - *fname = name; - return (np); - } - htp = savehash((struct hashbuf *)NULL); - np->n_hash = htp; - } - *htpp = htp; - break; - } - hval <<= HASHSHIFT; - hval += (isupper(c) ? tolower(c) : c) & HASHMASK; - } - c = *--cp; - *cp = '\0'; - /* - * Lookup this label in current hash table. - */ - for (np = htp->h_tab[hval % htp->h_size]; - np != NULL; - np = np->n_next) { - if (np->n_hashval == hval && - strcasecmp(name, np->n_dname) == 0) { - *fname = name; - *cp = c; - return (np); - } - } - if (!insert) { - /* - * Look for wildcard in this hash table. - * Don't use a cached "*" name as a wildcard, - * only authoritative. - */ - hval = ('*' & HASHMASK) % htp->h_size; - for (np = htp->h_tab[hval]; np != NULL; np = np->n_next) { - 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->n_parent = parent; - np->n_hashval = hval; - hval %= htp->h_size; - np->n_next = htp->h_tab[hval]; - htp->h_tab[hval] = np; - /* Increase hash table size. */ - if (++htp->h_cnt > htp->h_size * 2) { - *htpp = savehash(htp); - if (parent == NULL) { - if (htp == hashtab) { - hashtab = *htpp; - } else { - fcachetab = *htpp; - } - } - else - parent->n_hash = *htpp; - htp = *htpp; - } - *fname = name; - *cp = c; - return (np); -} - -/* int - * match(dp, class, type) - * Does data record `dp' match the class and type? - * return value: - * boolean - */ -int -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)); - if (dp->d_class != class && class != C_ANY) - return (0); - if (dp->d_type != type && type != T_ANY) - return (0); - return (1); -} diff --git a/usr.sbin/named/db_reload.c b/usr.sbin/named/db_reload.c deleted file mode 100644 index 1b962a63fdc2..000000000000 --- a/usr.sbin/named/db_reload.c +++ /dev/null @@ -1,125 +0,0 @@ -#if !defined(lint) && !defined(SABER) -static char sccsid[] = "@(#)db_reload.c 4.22 (Berkeley) 3/21/91"; -static char rcsid[] = "$Id: db_reload.c,v 4.9.1.4 1994/07/02 16:28:11 vixie Exp $"; -#endif /* not lint */ - -/* - * ++Copyright++ 1986, 1988 - * - - * Copyright (c) 1986, 1988 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - - * Portions Copyright (c) 1993 by Digital Equipment Corporation. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies, and that - * the name of Digital Equipment Corporation not be used in advertising or - * publicity pertaining to distribution of the document or software without - * specific, written prior permission. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT - * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - * - - * --Copyright-- - */ - -#include <sys/param.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/nameser.h> -#include <stdio.h> -#include <syslog.h> - -#include "named.h" - -/* - * Flush and reload data base. - */ -void -db_reload() -{ - dprintf(3, (ddt, "reload()\n")); - syslog(LOG_NOTICE, "reloading nameserver\n"); - - qflush(); - sqflush(NULL); - getnetconf(); -#ifdef FORCED_RELOAD - reloading = 1; /* to force transfer if secondary and backing up */ -#endif - ns_init(bootfile); - time(&resettime); -#ifdef FORCED_RELOAD - reloading = 0; - if (!needmaint) - sched_maint(); -#endif /* FORCED_RELOAD */ - - dprintf(1, (ddt, "Ready to answer queries.\n")); - syslog(LOG_NOTICE, "Ready to answer queries.\n"); -} - -#if 0 -/* someday we'll need this.. (untested since before 1990) */ -void -db_free(htp) - struct hashbuf *htp; -{ - register struct databuf *dp, *nextdp; - register struct namebuf *np, *nextnp; - struct namebuf **npp, **nppend; - - npp = htp->h_tab; - nppend = npp + htp->h_size; - while (npp < nppend) { - for (np = *npp++; np != NULL; np = nextnp) { - if (np->n_hash != NULL) - db_free(np->n_hash); - (void) free((char *)np->n_dname); - for (dp = np->n_data; dp != NULL; ) { - nextdp = dp->d_next; - (void) free((char *)dp); - dp = nextdp; - } - nextnp = np->n_next; - free((char *)np); - } - } - (void) free((char *)htp); -} -#endif diff --git a/usr.sbin/named/db_save.c b/usr.sbin/named/db_save.c deleted file mode 100644 index cd1639d6ec76..000000000000 --- a/usr.sbin/named/db_save.c +++ /dev/null @@ -1,214 +0,0 @@ -#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 4.9.1.7 1994/07/22 08:42:39 vixie Exp $"; -#endif /* not lint */ - -/* - * ++Copyright++ 1986 - * - - * Copyright (c) 1986 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - - * Portions Copyright (c) 1993 by Digital Equipment Corporation. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies, and that - * the name of Digital Equipment Corporation not be used in advertising or - * publicity pertaining to distribution of the document or software without - * specific, written prior permission. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT - * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - * - - * --Copyright-- - */ - -/* - * Buffer allocation and deallocation routines. - */ - -#include <sys/param.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/nameser.h> -#include <syslog.h> -#include <stdio.h> - -#include "named.h" - -/* - * Allocate a name buffer & save name. - */ -struct namebuf * -savename(name) - char *name; -{ - 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; - return (np); -} - -/* - * Allocate a data buffer & save data. - */ -struct databuf * -#ifdef DMALLOC -savedata_tagged(file, line, class, type, ttl, data, size) - char *file; - int line; -#else -savedata(class, type, ttl, data, size) -#endif - int class, type; - u_int32_t ttl; - u_char *data; - int size; -{ - register struct databuf *dp; - - if (type == T_NS) - dp = (struct databuf *) -#ifdef DMALLOC - dmalloc(file, line, -#else - malloc( -#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); - } - dp->d_next = NULL; - dp->d_type = type; - dp->d_class = class; - dp->d_ttl = ttl; - dp->d_size = size; - dp->d_mark = 0; - dp->d_flags = 0; - dp->d_cred = 0; - dp->d_clev = 0; -#ifdef NCACHE - dp->d_rcode = NOERROR; -#endif -#ifdef STATS - dp->d_ns = NULL; -#endif - dp->d_nstime = 0; - bcopy(data, dp->d_data, dp->d_size); - return (dp); -} - -int hashsizes[] = { /* hashtable sizes */ - 2, - 11, - 113, - 337, - 977, - 2053, - 4073, - 8011, - 16001, - 0 -}; - -/* - * Allocate a data buffer & save data. - */ -struct hashbuf * -savehash(oldhtp) - register struct hashbuf *oldhtp; -{ - register struct hashbuf *htp; - register struct namebuf *np, *nnp, **hp; - register int n; - int newsize; - - if (oldhtp == NULL) - newsize = hashsizes[0]; - else { - for (n = 0; newsize = hashsizes[n++]; ) - if (oldhtp->h_size == newsize) { - newsize = hashsizes[n]; - break; - } - if (newsize == 0) - newsize = oldhtp->h_size * 2 + 1; - } - dprintf(4, (ddt, "savehash GROWING to %d\n", newsize)); - htp = (struct hashbuf *) malloc((unsigned)HASHSIZE(newsize)); - if (htp == NULL) { - syslog(LOG_ERR, "savehash: %m"); - exit(1); - } - htp->h_size = newsize; - bzero((char *) htp->h_tab, newsize * sizeof(struct namebuf *)); - if (oldhtp == NULL) { - 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)); - htp->h_cnt = oldhtp->h_cnt; - for (n = 0; n < oldhtp->h_size; n++) { - for (np = oldhtp->h_tab[n]; np != NULL; np = nnp) { - nnp = np->n_next; - hp = &htp->h_tab[np->n_hashval % htp->h_size]; - np->n_next = *hp; - *hp = np; - } - } - free((char *) oldhtp); - return (htp); -} diff --git a/usr.sbin/named/db_secure.c b/usr.sbin/named/db_secure.c deleted file mode 100644 index b3eb73148560..000000000000 --- a/usr.sbin/named/db_secure.c +++ /dev/null @@ -1,170 +0,0 @@ -#ifndef LINT -static char rcsid[] = "$Id: db_secure.c,v 1.6 1994/07/23 23:23:56 vixie Exp $"; -#endif - -/* this file was contributed by Gregory Neil Shapiro of WPI in August 1993 */ - -#include <stdio.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/nameser.h> -#include <arpa/inet.h> -#include <syslog.h> - -#include "named.h" - -#ifdef SECURE_ZONES - -#ifndef SECURE_ZONE_RR -#define SECURE_ZONE_RR "secure_zone" -#endif -#ifndef MASK_SEP -#define MASK_SEP ':' -#endif - -int -build_secure_netlist(zp) - struct zoneinfo *zp; -{ - struct netinfo *ntp = NULL, **netlistp, **end; - char buf[BUFSIZ]; - struct hashbuf *htp; - struct namebuf *snp; - struct databuf *dp; - char *fname, *dname, dnbuf[MAXDNAME]; - int errs = 0, securezone = 0; - - if (zp->secure_nets) { - free_netlist(&zp->secure_nets); - } - netlistp = &zp->secure_nets; - end = netlistp; - strcat(strcat(strcpy(dnbuf, SECURE_ZONE_RR), "."), zp->z_origin); - - dname = dnbuf; - htp = hashtab; - if ((snp = nlookup(dname, &htp, &fname, 0)) == NULL) { - dprintf(1, (ddt, - "build_secure_netlist(%s): FAIL on nlookup %s\n", - zp->z_origin, dname)); - zp->secure_nets=NULL; - return(0); - } - /* A parent's RR's aren't valid */ - if (strcasecmp(snp->n_dname, SECURE_ZONE_RR)) { - zp->secure_nets=NULL; - return(0); - } - /* 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)) { - continue; - } - bzero(buf, sizeof(buf)); - bcopy(dp->d_data+1, buf, dp->d_size-1); - maskptr=strchr(buf, MASK_SEP); - if (maskptr) { - *maskptr++ = 0; - } - dprintf(3, (ddt, - "build_secure_netlist(%s): Found secure zone %s\n", - zp->z_origin, buf)); - if (ntp == NULL) { - ntp = (struct netinfo *)malloc(sizeof(struct netinfo)); - if (!ntp) { - dprintf(1, (ddt, - "build_secure_netlist (%s): malloc fail\n", - zp->z_origin)); - syslog(LOG_ERR, - "build_secure_netlist (%s): Out of Memory", - zp->z_origin); - if (!securezone) { - zp->secure_nets=NULL; - } - 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, - "build_secure_netlist (%s): Bad address: %s", - zp->z_origin, buf); - errs++; - continue; - } - if (maskptr && *maskptr) { - if (*maskptr == 'h' || *maskptr == 'H') { - ntp->mask = (u_int32_t)-1; - } else { - if (!inet_aton(maskptr, - (struct in_addr *)&ntp->mask)) { - dprintf(1, (ddt, - "build_secure_netlist (%s): Bad mask: %s\n", - zp->z_origin, maskptr)); - syslog(LOG_ERR, - "build_secure_netlist (%s): Bad mask: %s", - zp->z_origin, maskptr); - errs++; - continue; - } - } - } else { - 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)", - zp->z_origin, - inet_ntoa(ntp->my_addr), - ntp->mask); - errs++; - } - ntp->next = NULL; - ntp->addr = ntp->my_addr.s_addr & ntp->mask; - - /* 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, - "build_secure_netlist (%s): duplicate address %s\n", - zp->z_origin, inet_ntoa(ntp->my_addr)); - errs++; - continue; - } - *end = ntp; - end = &ntp->next; - ntp = NULL; - securezone++; - } - if (ntp) { - free((char *)ntp); - } - if (!securezone) { - 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, " %s", inet_ntoa(ntp->my_addr)); - fprintf(ddt, " next x%x\n", ntp->next); - } - } -#endif - return(errs); -} -#endif /*SECURE_ZONES*/ diff --git a/usr.sbin/named/db_update.c b/usr.sbin/named/db_update.c deleted file mode 100644 index 93244930d561..000000000000 --- a/usr.sbin/named/db_update.c +++ /dev/null @@ -1,638 +0,0 @@ -#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 4.9.1.19 1994/07/23 23:23:56 vixie Exp $"; -#endif /* not lint */ - -/* - * ++Copyright++ 1986, 1990 - * - - * Copyright (c) 1986, 1990 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - - * Portions Copyright (c) 1993 by Digital Equipment Corporation. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies, and that - * the name of Digital Equipment Corporation not be used in advertising or - * publicity pertaining to distribution of the document or software without - * specific, written prior permission. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT - * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - * - - * --Copyright-- - */ - -#include <stdio.h> -#include <syslog.h> - -#include <sys/param.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <arpa/nameser.h> - -#include "named.h" - -static void fixttl __P((struct databuf *)); -static int db_cmp __P((struct databuf *, - struct databuf *)); - -/* int - * isRefByNS(name, htp) - * recurse through all of `htp' looking for NS RR's that refer to `name'. - * returns: - * nonzero if at least one such NS RR exists - * cautions: - * this is very expensive; probably you only want to use on fcachetab. - */ -static int -isRefByNS(name, htp) - char name[]; - struct hashbuf *htp; -{ - register struct namebuf *np; - register struct databuf *dp; - - 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) && -#ifdef NCACHE - (!dp->d_rcode) && -#endif - !strcasecmp(name, (char *)dp->d_data)) { - return (1); - } - } - if (np->n_hash && isRefByNS(name, np->n_hash)) { - return (1); - } - } - return (0); -} - - -/* int - * findMyZone(struct namebuf *np) - * surf the zone cuts and find this zone the hard way - * return value: - * zone number or DB_Z_CACHE if it's outside a zone - * interesting cases: - * DEC.COM SOA (primary) - * CRL.DEC.COM NS (in primary) - * if you start at CRL.. here, you find the DEC.COM zone - * if you start at NS.CRL.. here, you're in the cache - * DEC.COM SOA (primary) - * CRL.DEC.COM NS (in primary) - * CRL.DEC.COM SOA (secondary) - * CRL.DEC.COM NS (in secondary) - * if you start at CRL.. here, you find the CRL.DEC.COM zone - * if you start at NS.CRL.. here, you're in the CRL.. zone - */ -int -findMyZone(np, class) - struct namebuf *np; - register int class; -{ - for (; np; np = np->n_parent) { - register struct databuf *dp; - - /* if we encounter an SOA, we're in its zone (which can be - * the cache or an authoritative zone, depending). - */ - for (dp = np->n_data; dp; dp = dp->d_next) - if (match(dp, class, T_SOA)) - return (dp->d_zone); - - /* if we find an NS at some node without having seen an SOA - * (above), then we're out in the cache somewhere. - */ - for (dp = np->n_data; dp; dp = dp->d_next) - if (match(dp, class, T_NS)) - return (DB_Z_CACHE); - } - - /* getting all the way to the root without finding an NS or SOA - * probably means that we are in deep dip, but we'll treat it as - * being in the cache. (XXX?) - */ - return (DB_Z_CACHE); -} - - -/* int - * db_update(name, odp, newdp, flags, htp) - * update data base node at `name'. `flags' controls the action. - * side effects: - * inverse query tables modified, if we're using them. - * return value: - * OK - success - * NONAME - name doesn't exist - * AUTH - you can't do that - * DATAEXISTS - there's something there and DB_NODATA was specified - * NODATA - there's no data, and (DB_DELETE or DB_MEXIST) was spec'd - * - * Policy: How to add data if one more RR is -ve data - * - * NEND NOERROR_NODATA - * NXD NXDOMAIN - * - * match - * old - * Data NEND NXD - * Data Merge Data Data - * new NEND NEND NEND NEND - * NXD NXD NXD NXD - * - * no match - * old - * Data NEND NXD - * Data Merge Merge Data - * new NEND Merge Merge NEND - * NXD NXD NXD NXD - * - */ -/* XXX: this code calls nlookup, which can create namebuf's. if this code - * has to exit with a fatal error, it should scan from the new np upward - * and for each node which has no children and no data it should remove - * the namebuf. design notes: (1) there's no harm in doing this even if - * success occurred; (2) stopping on the first nonremovable np is optimal; - * the code for removal should be taken out of remove_zone() and made - * general enough for this use, and for remove_zone()'s continued use. - * vix, 21jul94 - */ -int -db_update(name, odp, newdp, flags, htp) - char name[]; - struct databuf *odp, *newdp; - int flags; - struct hashbuf *htp; -{ - register struct databuf *dp, *pdp; - register struct namebuf *np; - int zn, isHintNS; - char *fname; - - dprintf(3, (ddt, "db_update(%s, 0x%x, 0x%x, 0%o, 0x%x)%s\n", - name, odp, newdp, flags, 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) { - int foundRR = 0; - - /* don't generate the warning if we've done so recently or - * 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)) { - foundRR++; - 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); - return (AUTH); - } - - /* some special checks for root NS' A RR's */ - isHintNS = isRefByNS(name, fcachetab); - 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, - "upgrading credibility for A RR (%s)\n", - name)); - /* XXX: should copy NS RR's, but we really just want - * to prevent deprecation later so this will do. - */ - newdp->d_cred = DB_C_ANSWER; - newdp->d_clev = 0; - } - } - - /* Reflect certain updates in hint cache also... */ - /* Don't stick data we are authoritative for in hints. */ - if (!(flags & DB_NOHINTS) && - (odp != NULL) && - (htp != fcachetab) && - (odp->d_zone <= 0) && - !(odp->d_flags & DB_F_HINT) && -#ifdef NCACHE - (!newdp || !newdp->d_rcode) && -#endif - ((name[0] == '\0' && odp->d_type == T_NS) || - (odp->d_type == T_A && isHintNS) - ) - ) - { - dprintf(3, (ddt, "db_update: hint '%s' %d\n", - name, odp->d_ttl)); - dp = savedata(odp->d_class, odp->d_type, odp->d_ttl, - odp->d_data, odp->d_size); - dp->d_zone = DB_Z_CACHE; - dp->d_flags = DB_F_HINT; - dp->d_cred = DB_C_CACHE; - dp->d_clev = 0; - if (db_update(name, - dp, dp, - (flags|DB_NOHINTS), - fcachetab) - != OK) { - dprintf(3, (ddt, "db_update: hint %x freed\n", dp)); - (void) free((char *)dp); - } - } - - if (odp != NULL) { - int foundRR = 0; - - pdp = NULL; - for (dp = np->n_data; dp != NULL; ) { - if (!match(dp, odp->d_class, odp->d_type)) { - /* {class,type} doesn't match. these are - * the aggregation cases. - */ - if ((dp->d_type == T_CNAME || - odp->d_type == T_CNAME) && - odp->d_class == dp->d_class && - odp->d_mark == dp->d_mark && -#ifdef NCACHE - /* neither the odp nor the new dp are - * negatively cached records... - */ - !dp->d_rcode && - !odp->d_rcode && -#endif /*NCACHE*/ - zones[odp->d_zone].z_type != Z_CACHE) { - syslog(LOG_ERR, - "%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) - goto skip; - - /* XXX: - * The next three clauses do not deal - * correctly with glue records. mpa. - */ - - /* if the new data is authorative - * remove any data for this domain with - * the same class that isn't as credable - */ - if (newdp->d_cred == DB_C_ZONE && - newdp->d_cred > dp->d_cred) - /* better credibility and the old datum - * was not from a zone file. remove - * the old datum. - */ - goto delete; - - /* if we have authoritative data for a - * node, don't add in other data. - */ - if (dp->d_cred == DB_C_ZONE && - newdp->d_cred < dp->d_cred) - return (AUTH); - - /* if the new data is authoritative but - * 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); -#ifdef NCACHE - /* process NXDOMAIN */ - /* policy */ - if (newdp->d_rcode == NXDOMAIN) { - if (dp->d_cred < DB_C_AUTH) - goto delete; - else - return (DATAEXISTS); - } - - if (dp->d_rcode == NXDOMAIN) - goto delete; - - /* process NOERROR_NODATA */ - /* NO PROCESSING REQUIRED */ -#endif /*NCACHE*/ - goto skip; - } /*if {class,type} did not match*/ - - /* {type,class} did match. this is the replace case. - */ - dprintf(5, (ddt, - "db_update: flags = %#x, sizes = %d, %d (cmp %d)\n", - flags, odp->d_size, dp->d_size, - db_cmp(dp, odp))); - if (newdp) { - dprintf(4, (ddt, - "credibility for %s is %d(%d) from [%s].%d, is %d(%d) in cache\n", - *name? name : ".", - newdp->d_cred, - newdp->d_clev, - inet_ntoa(from_addr.sin_addr), - 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. - */ - goto delete; - } - if (newdp->d_cred < dp->d_cred) { - /* credibility is worse. ignore it. */ - return (AUTH); - } - if (newdp->d_cred == DB_C_ZONE && - newdp->d_cred == dp->d_cred && - newdp->d_clev < dp->d_clev) - return (AUTH); - - /* credibility is the same. - * let it aggregate in the normal way. - */ -#ifdef NCACHE - /* - * if the new or old RR is -ve, delete old. - */ - if (dp->d_rcode || newdp->d_rcode) { - /* XXX: how can a zone rr be neg? */ - if (dp->d_cred != DB_C_ZONE) - goto delete; - else - return (DATAEXISTS); - } -#endif - /* - * Some RR types should not be aggregated. - */ - if (dp->d_type == T_SOA) - goto delete; - if (dp->d_type == T_WKS && - !bcmp(dp->d_data, newdp->d_data, INT16SZ)) - goto delete; - } - if ((flags & DB_NODATA) && !db_cmp(dp, odp)) { - /* refresh ttl if cache entry */ - if (dp->d_zone == 0) { - if (odp->d_zone != 0) { /* XXX */ - /* changing cache->auth */ - dp->d_zone = odp->d_zone; - dp->d_ttl = odp->d_ttl; - dprintf(4, (ddt, - "db_update: cache entry now in auth zone\n" - )); - return (DATAEXISTS); - } - fixttl(odp); - 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, - dp->d_ttl - tt.tv_sec)); - } - return (DATAEXISTS); - } - /* - * If the old databuf has some data, check that the - * data matches that in the new databuf (so UPDATED - * will delete only the matching RR) - */ - if (odp->d_size > 0) - if (db_cmp(dp, odp)) - goto skip; - foundRR = 1; - if (flags & DB_DELETE) { - delete: dp = rm_datum(dp, np, pdp); - } else { - skip: pdp = dp; - dp = dp->d_next; - } - } - if (!foundRR) { - if (flags & DB_DELETE) - return (NODATA); - if (flags & DB_MEXIST) - return (NODATA); - } - } - if (newdp == NULL) - return (OK); - /* XXX: empty nodes bypass credibility checks above; should check - * 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)); -#ifdef INVQ - if (!(newdp->d_flags & DB_F_HINT)) - addinv(np, newdp); /* modify inverse query tables */ -#endif - -#ifdef STATS - if (!newdp->d_zone && !(newdp->d_flags & DB_F_HINT)) - newdp->d_ns = nameserFind(from_addr.sin_addr, NS_F_INSERT); -#endif - - /* Add to end of list, generally preserving order */ - newdp->d_next = NULL; - if ((dp = np->n_data) == NULL) { -#ifdef DATUMREFCNT - newdp->d_rcnt = 1; -#endif - np->n_data = newdp; - return (OK); - } - while (dp->d_next != NULL) { - if ((flags & DB_NODATA) && !db_cmp(dp, newdp)) - return (DATAEXISTS); - dp = dp->d_next; - } - if ((flags & DB_NODATA) && !db_cmp(dp, newdp)) - return (DATAEXISTS); -#ifdef DATUMREFCNT - newdp->d_rcnt = 1; -#endif - dp->d_next = newdp; - return (OK); -} - -static void -fixttl(dp) - register struct databuf *dp; -{ - if (dp->d_zone == 0 && !(dp->d_flags & DB_F_HINT)) { - if (dp->d_ttl <= tt.tv_sec) - return; - else if (dp->d_ttl < tt.tv_sec+min_cache_ttl) - dp->d_ttl = tt.tv_sec+min_cache_ttl; - else if (dp->d_ttl > tt.tv_sec+max_cache_ttl) - dp->d_ttl = tt.tv_sec+max_cache_ttl; - } - return; -} - -/* - * Compare type, class and data from databufs for equivalence. - * Must be case insensitive for some domain names. - * Return 0 if equivalent, nonzero otherwise. - */ -static int -db_cmp(dp1, dp2) - register struct databuf *dp1, *dp2; -{ - register u_char *cp1, *cp2; - int len; - - if (dp1->d_type != dp2->d_type || dp1->d_class != dp2->d_class) - return (1); - if (dp1->d_size != dp2->d_size) - return (1); - if (dp1->d_mark != dp2->d_mark) - return (1); /* old and new RR's are distinct */ -#ifdef NCACHE - if (dp1->d_rcode && dp2->d_rcode) - return ((dp1->d_rcode == dp1->d_rcode)?0:1); - if (dp1->d_rcode || dp2->d_rcode) - return (1); -#endif - - switch (dp1->d_type) { - - case T_A: - case T_UID: - case T_GID: - case T_WKS: - case T_NULL: - case T_NSAP: -#ifdef ALLOW_T_UNSPEC - case T_UNSPEC: -#endif - return (bcmp(dp1->d_data, dp2->d_data, dp1->d_size)); - - case T_NS: - case T_CNAME: - case T_PTR: - case T_MB: - case T_MG: - case T_MR: - case T_UINFO: - return (strcasecmp((char *)dp1->d_data, (char *)dp2->d_data)); - - case T_HINFO: - case T_ISDN: - cp1 = dp1->d_data; - cp2 = dp2->d_data; - len = *cp1; - if (strncasecmp((char *)++cp1, (char *)++cp2, len)) - return (1); - cp1 += len; - cp2 += len; - len = *cp1; - return (strncasecmp((char *)++cp1, (char *)++cp2, len)); - - case T_SOA: - case T_MINFO: - case T_RP: - if (strcasecmp((char *)dp1->d_data, (char *)dp2->d_data)) - return (1); - cp1 = dp1->d_data + strlen((char *)dp1->d_data) + 1; - cp2 = dp2->d_data + strlen((char *)dp2->d_data) + 1; - if (dp1->d_type != T_SOA) - return (strcasecmp((char *)cp1, (char *)cp2)); - if (strcasecmp((char *)cp1, (char *)cp2)) - return (1); - cp1 += strlen((char *)cp1) + 1; - cp2 += strlen((char *)cp2) + 1; - return (bcmp(cp1, cp2, INT32SZ * 5)); - - case T_MX: - case T_AFSDB: - case T_RT: - cp1 = dp1->d_data; - cp2 = dp2->d_data; - if (*cp1++ != *cp2++ || *cp1++ != *cp2++) /* cmp prio */ - return (1); - return (strcasecmp((char *)cp1, (char *)cp2)); - - case T_TXT: - case T_X25: - if (dp1->d_size != dp2->d_size) - return (1); - return (bcmp(dp1->d_data, dp2->d_data, dp1->d_size)); - - default: - return (1); - } -} diff --git a/usr.sbin/named/dmalloc.c b/usr.sbin/named/dmalloc.c deleted file mode 100644 index 4373024a889f..000000000000 --- a/usr.sbin/named/dmalloc.c +++ /dev/null @@ -1,312 +0,0 @@ -/* dmalloc - debugging layer on top of malloc - * vix 25mar92 [fixed bug in round-up calcs in alloc()] - * vix 24mar92 [added size calcs, improved printout] - * vix 22mar92 [original work] - * - * $Id: dmalloc.c,v 4.9.1.3 1994/07/02 16:28:11 vixie Exp $ - */ - -/* - * ++Copyright++ 1993 - * - - * Copyright (c) 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - - * Portions Copyright (c) 1993 by Digital Equipment Corporation. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies, and that - * the name of Digital Equipment Corporation not be used in advertising or - * publicity pertaining to distribution of the document or software without - * specific, written prior permission. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT - * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - * - - * --Copyright-- - */ - -#include <stdio.h> -#include <signal.h> -#include "../conf/portability.h" -#include "../conf/options.h" - -#ifdef DMALLOC - -#define TRUE 1 -#define FALSE 0 -typedef unsigned bool; - -#define MAX_MEMORY 65536 /* must fit in typeof(datum.size) */ -#define MAX_CALLERS 256 /* must be **2 */ - -typedef struct caller { - struct caller *next; - struct filenam *file; - struct calltab *frees; - unsigned line; - unsigned calls; - unsigned blocks; - unsigned bytes; -} caller; - -typedef struct filenam { - struct filenam *next; - char *name; -} filenam; - -typedef struct calltab { - struct caller *callers[MAX_CALLERS]; -} calltab; - -typedef struct datum { - unsigned size; /* size of malloc'd item */ - unsigned caller; /* offset into memory[] */ - /* user data follows */ -} datum; - -static char memory[MAX_MEMORY]; -static char *nextmem = memory; -static char *alloc(size) unsigned size; { - char *thismem = nextmem; - int oddness = (size % sizeof(char*)); - if (oddness) - size += (sizeof(char*) - oddness); - nextmem += size; - if (nextmem >= &memory[MAX_MEMORY]) { - fprintf(stderr, "dmalloc.alloc: out of mem\n"); - kill(0, SIGBUS); - } - return thismem; - } - -static filenam *Files; -static calltab Callers; - -/*--------------------------------------------------- imports - */ - -#undef malloc -#undef calloc -#undef realloc -#undef free - -char *malloc(), *calloc(), *realloc(); - -#if defined(sun) -int free(); -#else -void free(); -#endif - -/*--------------------------------------------------- private - */ - -#define STR_EQ(l,r) (((l)[0] == (r)[0]) && !strcmp(l, r)) - -static filenam * -findFile(file, addflag) - char *file; - bool addflag; -{ - filenam *f; - - for (f = Files; f; f = f->next) - if (STR_EQ(file, f->name)) - return f; - if (!addflag) - return NULL; - f = (filenam*) alloc(sizeof(filenam)); - f->next = Files; - Files = f; - f->name = alloc(strlen(file) + 1); - strcpy(f->name, file); - return f; -} - -static caller * -findCaller(ctab, file, line, addflag) - calltab *ctab; - char *file; - unsigned line; - bool addflag; -{ - unsigned hash = line & (MAX_CALLERS - 1); - caller *c; - - for (c = ctab->callers[hash]; c; c = c->next) - if ((c->line == line) && STR_EQ(c->file->name, file)) - return c; - if (!addflag) - return NULL; - c = (caller*) alloc(sizeof(caller)); - c->next = ctab->callers[hash]; - c->file = findFile(file, TRUE); - c->line = line; - c->calls = 0; - c->frees = (calltab *) alloc(sizeof(calltab)); - ctab->callers[hash] = c; - return c; -} - -/*--------------------------------------------------- public - */ - -char * -dmalloc(file, line, size) - char *file; - unsigned line; - unsigned size; -{ - caller *c; - datum *d; - - c = findCaller(&Callers, file, line, TRUE); - d = (datum *) malloc(sizeof(datum) + size); - d->size = size; - d->caller = ((char *)c) - memory; - c->calls++; - c->blocks++; - c->bytes += size; - return (char *) (d+1); -} - -void -dfree(file, line, ptr) - char *file; - unsigned line; - char *ptr; -{ - caller *c, *a; - datum *d; - - d = (datum *) ptr; d--; - a = (caller *) (memory + d->caller); - a->bytes -= d->size; - a->blocks--; - c = findCaller(a->frees, file, line, TRUE); - c->calls++; - free((char*) d); -} - -char * -dcalloc(file, line, nelems, elsize) - char *file; - unsigned line; - unsigned nelems, elsize; -{ - unsigned size = (nelems * elsize); - char *ptr; - - ptr = dmalloc(file, line, size); - bzero(ptr, size); - return ptr; -} - -char * -drealloc(file, line, ptr, size) - char *file; - unsigned line; - char *ptr; - unsigned size; -{ - caller *c, *a; - datum *d; - - d = (datum *) ptr; d--; - /* fix up stats from allocation */ - a = (caller *) (memory + d->caller); - a->bytes -= d->size; - a->blocks--; - /* we are a "freer" of this allocation */ - c = findCaller(a->frees, file, line, TRUE); - c->calls++; - /* get new allocation and stat it */ - c = findCaller(&Callers, file, line, TRUE); - d = (datum *) realloc((char *) d, sizeof(datum) + size); - d->size = size; - d->caller = ((char *)c) - memory; - c->calls++; - c->blocks++; - c->bytes += size; - return (char *) (d+1); -} - -static void -dmalloccallers(outf, prefix, ctab) - FILE *outf; - char *prefix; - calltab *ctab; -{ - /* this bizarre logic is to print all of a file's entries together */ - filenam *f; - - for (f = Files; f; f = f->next) { - int i; - - for (i = MAX_CALLERS-1; i >= 0; i--) { - caller *c; - - for (c = ctab->callers[i]; c; c = c->next) { - if (f != c->file) - continue; - fprintf(outf, "%s\"%s\":%u calls=%u", - prefix, c->file->name, c->line, - c->calls); - if (c->blocks || c->bytes) - fprintf(outf, " blocks=%u bytes=%u", - c->blocks, c->bytes); - fputc('\n', outf); - if (c->frees) - dmalloccallers(outf, - "\t\t", c->frees); - } - } - } -} - -void -dmallocstats(outf) - FILE *outf; -{ - fprintf(outf, "dallocstats [ private mem used=%u, avail=%u ]\n", - nextmem - memory, &memory[MAX_MEMORY] - nextmem); - dmalloccallers(outf, "\t", &Callers); -} - -#endif /*DMALLOC*/ diff --git a/usr.sbin/named/dmalloc.h b/usr.sbin/named/dmalloc.h deleted file mode 100644 index 54e68f9887a2..000000000000 --- a/usr.sbin/named/dmalloc.h +++ /dev/null @@ -1,68 +0,0 @@ -/* dmalloc - debugging layer on top of malloc - * vix 22mar92 [written] - * - * $Id: dmalloc.h,v 4.9.1.2 1993/09/08 00:01:17 vixie Exp $ - */ - -/* - * ++Copyright++ - * - - * Copyright (c) - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - - * Portions Copyright (c) 1993 by Digital Equipment Corporation. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies, and that - * the name of Digital Equipment Corporation not be used in advertising or - * publicity pertaining to distribution of the document or software without - * specific, written prior permission. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT - * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - * - - * --Copyright-- - */ - -#define malloc(s) dmalloc(__FILE__, __LINE__, s) -#define free(p) dfree(__FILE__, __LINE__, p) -#define calloc(n, s) dcalloc(__FILE__, __LINE__, n, s) -#define realloc(p, s) drealloc(__FILE__, __LINE__, p, s) - -char *dmalloc(), *dcalloc(), *drealloc(); -void dfree(), dmallocstats(); diff --git a/usr.sbin/named/named.h b/usr.sbin/named/named.h deleted file mode 100644 index 4e597d7a89e0..000000000000 --- a/usr.sbin/named/named.h +++ /dev/null @@ -1,19 +0,0 @@ -/* named.h - include the local definitions in the right order - * vix 28aug93 [original] - * - * $Id: named.h,v 1.1 1993/09/08 04:57:40 vixie Exp $ - */ - -#include "../conf/portability.h" -#include "../conf/options.h" - -#include "pathnames.h" - -#include "ns_defs.h" -#include "db_defs.h" - -#include "ns_glob.h" -#include "db_glob.h" - -#include "ns_func.h" -#include "db_func.h" diff --git a/usr.sbin/named/ns_defs.h b/usr.sbin/named/ns_defs.h deleted file mode 100644 index bb9f18fbacb1..000000000000 --- a/usr.sbin/named/ns_defs.h +++ /dev/null @@ -1,368 +0,0 @@ -/* - * from ns.h 4.33 (Berkeley) 8/23/90 - * $Id: ns_defs.h,v 1.12 1994/07/23 23:23:56 vixie Exp $ - */ - -/* - * ++Copyright++ 1986 - * - - * Copyright (c) 1986 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - - * Portions Copyright (c) 1993 by Digital Equipment Corporation. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies, and that - * the name of Digital Equipment Corporation not be used in advertising or - * publicity pertaining to distribution of the document or software without - * specific, written prior permission. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT - * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - * - - * --Copyright-- - */ - -/* - * Global definitions for the name server. - */ - -/* - * Effort has been expended here to make all structure members 32 bits or - * larger land on 32-bit boundaries; smaller structure members have been - * deliberately shuffled and smaller integer sizes chosen where possible - * to make sure this happens. This is all meant to avoid structure member - * padding which can cost a _lot_ of memory when you have hundreds of - * thousands of entries in your cache. - */ - -/* - * Timeout time should be around 1 minute or so. Using the - * the current simplistic backoff strategy, the sequence - * retrys after 4, 8, and 16 seconds. With 3 servers, this - * dies out in a little more than a minute. - * (sequence RETRYBASE, 2*RETRYBASE, 4*RETRYBASE... for MAXRETRY) - */ -#define MINROOTS 2 /* min number of root hints */ -#define NSMAX 16 /* max number of NS addrs to try ([0..255]) */ -#define RETRYBASE 4 /* base time between retries */ -#define MAXCLASS 255 /* XXX - may belong elsewhere */ -#define MAXRETRY 3 /* max number of retries per addr */ -#define MAXCNAMES 8 /* max # of CNAMES tried per addr */ -#define MAXQUERIES 20 /* max # of queries to be made */ -#define MAXQSERIAL 4 /* max # of outstanding QSERIAL's */ - /* (prevent "recursive" loops) */ -#define INIT_REFRESH 600 /* retry time for initial secondary */ - /* contact (10 minutes) */ -#define NADDRECS 20 /* max addt'l rr's per resp */ - -#define XFER_TIMER 120 /* named-xfer's connect timeout */ -#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 ALPHA 0.7 /* How much to preserve of old response time */ -#define BETA 1.2 /* How much to penalize response time on failure */ -#define GAMMA 0.98 /* How much to decay unused response times */ - - /* sequence-space arithmetic */ -#define SEQ_GT(a,b) ((int32_t)((a)-(b)) > 0) - -/* these fields are ordered to maintain word-alignment; - * be careful about changing them. - */ -struct zoneinfo { - char *z_origin; /* root domain name of zone */ - time_t z_time; /* time for next refresh */ - time_t z_lastupdate; /* time of last refresh */ - u_int32_t z_refresh; /* refresh interval */ - u_int32_t z_retry; /* refresh retry interval */ - u_int32_t z_expire; /* expiration time for cached info */ - u_int32_t z_minimum; /* minimum TTL value */ - u_int32_t z_serial; /* changes if zone modified */ - char *z_source; /* source location of data */ - time_t z_ftime; /* modification time of source file */ - struct in_addr z_xaddr; /* override server for next xfer */ - struct in_addr z_addr[NSMAX]; /* list of master servers for zone */ - u_char z_addrcnt; /* number of entries in z_addr[] */ - u_char z_type; /* type of zone; see below */ - u_int16_t z_flags; /* state bits; see below */ - pid_t z_xferpid; /* xfer child pid */ - int z_class; /* class of zone */ -#ifdef SECURE_ZONES - struct netinfo *secure_nets; /* list of secure networks for zone */ -#endif -}; - - /* zone types (z_type) */ -#define Z_NIL 0 /* zone slot not in use */ -#define Z_PRIMARY 1 -#define Z_SECONDARY 2 -#define Z_CACHE 3 -#define Z_STUB 4 - - /* zone state bits (16 bits) */ -#define Z_AUTH 0x0001 /* zone is authoritative */ -#define Z_NEED_XFER 0x0002 /* waiting to do xfer */ -#define Z_XFER_RUNNING 0x0004 /* asynch. xfer is running */ -#define Z_NEED_RELOAD 0x0008 /* waiting to do reload */ -#define Z_SYSLOGGED 0x0010 /* have logged timeout */ -#define Z_QSERIAL 0x0020 /* sysquery()'ing for serial number */ -#define Z_FOUND 0x0040 /* found in boot file when reloading */ -#define Z_INCLUDE 0x0080 /* set if include used in file */ -#define Z_DB_BAD 0x0100 /* errors when loading file */ -#define Z_TMP_FILE 0x0200 /* backup file for xfer is temporary */ -#ifdef ALLOW_UPDATES -#define Z_DYNAMIC 0x0400 /* allow dynamic updates */ -#define Z_DYNADDONLY 0x0800 /* dynamic mode: add new data only */ -#define Z_CHANGED 0x1000 /* zone has changed */ -#endif /* ALLOW_UPDATES */ - - /* named_xfer exit codes */ -#define XFER_UPTODATE 0 /* zone is up-to-date */ -#define XFER_SUCCESS 1 /* performed transfer successfully */ -#define XFER_TIMEOUT 2 /* no server reachable/xfer timeout */ -#define XFER_FAIL 3 /* other failure, has been logged */ - -#include <sys/time.h> - -/* XXX - "struct qserv" is deprecated in favor of "struct nameser" */ -struct qserv { - struct sockaddr_in - ns_addr; /* address of NS */ - struct databuf *ns; /* databuf for NS record */ - struct databuf *nsdata; /* databuf for server address */ - struct timeval stime; /* time first query started */ - int nretry; /* # of times addr retried */ -}; - -/* - * Structure for recording info on forwarded or generated queries. - */ -struct qinfo { - u_int16_t q_id; /* id of query */ - u_int16_t q_nsid; /* id of forwarded query */ - struct sockaddr_in - q_from; /* requestor's address */ - u_char *q_msg, /* the message */ - *q_cmsg; /* the cname message */ - int16_t q_msglen, /* len of message */ - q_cmsglen; /* len of cname message */ - int16_t q_dfd; /* UDP file descriptor */ - struct fwdinfo *q_fwd; /* last forwarder used */ - time_t q_time; /* time to retry */ - time_t q_expire; /* time to expire */ - struct qinfo *q_next; /* rexmit list (sorted by time) */ - struct qinfo *q_link; /* storage list (random order) */ - struct databuf *q_usedns[NSMAX]; /* databuf for NS that we've tried */ - struct qserv q_addr[NSMAX]; /* addresses of NS's */ -#ifdef notyet - struct nameser *q_ns[NSMAX]; /* name servers */ -#endif - u_char q_naddr; /* number of addr's in q_addr */ - u_char q_curaddr; /* last addr sent to */ - u_char q_nusedns; /* number of elements in q_usedns[] */ - u_int8_t q_flags; /* see below */ - int16_t q_cname; /* # of cnames found */ - int16_t q_nqueries; /* # of queries required */ - struct qstream *q_stream; /* TCP stream, null if UDP */ - 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 */ -}; - - /* q_flags bits (8 bits) */ -#define Q_SYSTEM 0x01 /* is a system query */ -#define Q_PRIMING 0x02 /* generated during priming phase */ -#define Q_ZSERIAL 0x04 /* getting zone serial for xfer test */ - -#define Q_NEXTADDR(qp,n) \ - (((qp)->q_fwd == (struct fwdinfo *)0) ? \ - &(qp)->q_addr[n].ns_addr : &(qp)->q_fwd->fwdaddr) - -#define RETRY_TIMEOUT 45 -#define QINFO_NULL ((struct qinfo *)0) - -/* - * Return codes from ns_forw: - */ -#define FW_OK 0 -#define FW_DUP 1 -#define FW_NOSERVER 2 -#define FW_SERVFAIL 3 - -struct qstream { - int s_rfd; /* stream file descriptor */ - int s_size; /* expected amount of data to recive */ - int s_bufsize; /* amount of data recived in s_buf */ - u_char *s_buf; /* buffer of received data */ - u_char *s_bufp; /* pointer into s_buf of recived data*/ - struct qstream *s_next; /* next stream */ - struct sockaddr_in - s_from; /* address query came from */ - u_int32_t s_time; /* time stamp of last transaction */ - int s_refcnt; /* number of outstanding queries */ - u_int16_t s_tempsize; /* temporary for size from net */ -}; -#define QSTREAM_NULL ((struct qstream *)0) - -struct qdatagram { - int dq_dfd; /* datagram file descriptor */ - time_t dq_gen; /* generation number */ - struct qdatagram - *dq_next; /* next datagram */ - struct in_addr dq_addr; /* interface address */ -}; -#define QDATAGRAM_NULL ((struct qdatagram *)0) - -struct netinfo { - struct netinfo *next; - u_int32_t addr; - u_int32_t mask; - struct in_addr my_addr; -}; - -#define ALLOW_NETS 0x0001 -#define ALLOW_HOSTS 0x0002 -#define ALLOW_ALL (ALLOW_NETS | ALLOW_HOSTS) - -struct fwdinfo { - struct fwdinfo *next; - struct sockaddr_in - fwdaddr; -}; - -enum nameserStats { nssRcvdQ, /* sent us a query */ - nssRcvdR, /* sent us an answer */ - nssRcvdIQ, /* sent us an inverse query */ - nssRcvdNXD, /* sent us a negative response */ - nssRcvdFwdQ, /* sent us a query we had to fwd */ - nssRcvdFwdR, /* sent us a response we had to fwd */ - nssRcvdDupQ, /* sent us a retry */ - nssRcvdDupR, /* sent us an extra answer */ - nssRcvdFail, /* sent us a SERVFAIL */ - nssRcvdFErr, /* sent us a FORMERR */ - nssRcvdErr, /* sent us some other error */ - nssRcvdTCP, /* sent us a query using TCP */ - nssRcvdAXFR, /* sent us an AXFR */ - nssRcvdLDel, /* sent us a lame delegation */ - nssRcvdOpts, /* sent us some IP options */ - nssSentSysQ, /* sent them a sysquery */ - nssSentAns, /* sent them an answer */ - nssSentFwdQ, /* fwdd a query to them */ - nssSentFwdR, /* fwdd a response to them */ - nssSentDupQ, /* sent them a retry */ - nssSentFail, /* sent them a SERVFAIL */ - nssSentFErr, /* sent them a FORMERR */ - nssSendtoErr, /* error in sendto(2) */ - nssLast }; - -struct nameser { - struct in_addr addr; /* key */ - u_long stats[nssLast]; /* statistics */ -#ifdef notyet - u_int32_t rtt; /* round trip time */ - /* XXX - need to add more stuff from "struct qserv", and use our rtt */ - u_int16_t flags; /* see below */ -#endif - u_int8_t xfers; /* #/xfers running right now */ -}; - - -#ifdef NCACHE -#define NOERROR_NODATA 6 /* only used internally by the server, used for - * -ve $ing non-existence of records. 6 is not - * a code used as yet anyway. anant@isi.edu - */ -#define NTTL 600 /* ttl for negative data: 10 minutes? */ -#endif /*NCACHE*/ - -#define VQEXPIRY 900 /* a VQ entry expires in 15*60 = 900 seconds */ - -#ifdef VALIDATE - -#define INVALID 0 -#define VALID_NO_CACHE 1 -#define VALID_CACHE 2 -#define MAXNAMECACHE 100 -#define MAXVQ 100 /* Max number of elements in TO_Validate queue */ - -struct _nameaddr { - struct in_addr ns_addr; - char *nsname; -}; -typedef struct _nameaddr NAMEADDR; - -struct _to_validate { - int16_t class; /* Name Class */ - int16_t type; /* RR type */ - char *data; /* RR data */ - char *dname; /* Name */ - time_t time; /* time at which inserted in queue */ - struct _to_validate - *next, - *prev; -}; -typedef struct _to_validate TO_Validate; - -#endif /*VALIDATE*/ - - -#ifdef DEBUG -# define dprintf(lev, args) ((debug >= lev) && fprintf args) -#else -# define dprintf(lev, args) -#endif - - -#ifdef INIT - error "INIT already defined, check system include files" -#endif -#ifdef DECL - error "DECL already defined, check system include files" -#endif - -#ifdef MAIN_PROGRAM -#define INIT(x) = x -#define DECL -#else -#define INIT(x) -#define DECL extern -#endif diff --git a/usr.sbin/named/ns_forw.c b/usr.sbin/named/ns_forw.c deleted file mode 100644 index 574596460ada..000000000000 --- a/usr.sbin/named/ns_forw.c +++ /dev/null @@ -1,909 +0,0 @@ -#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 4.9.1.17 1994/07/23 23:23:56 vixie Exp $"; -#endif /* not lint */ - -/* - * ++Copyright++ 1986 - * - - * Copyright (c) 1986 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - - * Portions Copyright (c) 1993 by Digital Equipment Corporation. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies, and that - * the name of Digital Equipment Corporation not be used in advertising or - * publicity pertaining to distribution of the document or software without - * specific, written prior permission. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT - * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - * - - * --Copyright-- - */ - -#include <sys/param.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <arpa/nameser.h> - -#include <syslog.h> -#include <resolv.h> -#include <stdio.h> -#include <errno.h> - -#include "named.h" - -/* - * Forward the query to get the answer since its not in the database. - * Returns FW_OK if a request struct is allocated and the query sent. - * Returns FW_DUP if this is a duplicate of a pending request. - * Returns FW_NOSERVER if there were no addresses for the nameservers. - * Returns FW_SERVFAIL on malloc error or if asked to do something - * dangerous, such as fwd to ourselves or fwd to the host that asked us. - * - * (no action is taken on errors and qpp is not filled in.) - */ -int -ns_forw(nsp, msg, msglen, fp, qsp, dfd, qpp, dname, np) - struct databuf *nsp[]; - u_char *msg; - int msglen; - struct sockaddr_in *fp; - struct qstream *qsp; - int dfd; - struct qinfo **qpp; - char *dname; - struct namebuf *np; -{ - register struct qinfo *qp; - struct sockaddr_in *nsa; - HEADER *hp; - u_int16_t id; - int n; - - dprintf(3, (ddt, "ns_forw()\n")); - - hp = (HEADER *) msg; - id = hp->id; - /* Look at them all */ - for (qp = qhead; 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 && - bcmp((char *)qp->q_msg+2, msg+2, msglen-2) == 0) || - (qp->q_cmsglen == msglen && - bcmp((char *)qp->q_cmsg+2, msg+2, msglen-2) == 0))) { - dprintf(3, (ddt, - "forw: dropped DUP id=%d\n", ntohs(id))); - nameserIncr(fp->sin_addr, nssRcvdDupQ); - return (FW_DUP); - } - } - - qp = qnew(); -#ifdef LAME_DELEGATION - getname(np, qp->q_domain, sizeof qp->q_domain); -#endif - qp->q_from = *fp; /* nslookup wants to know this */ - if ((n = nslookup(nsp, qp, dname, "ns_forw")) < 0) { - dprintf(2, (ddt, "forw: nslookup reports danger\n")); - qfree(qp); - return (FW_SERVFAIL); - } else if (n == 0 && !(forward_only && fwdtab)) { - dprintf(2, (ddt, "forw: no nameservers found\n")); - qfree(qp); - return (FW_NOSERVER); - } - qp->q_stream = qsp; - qp->q_curaddr = 0; - qp->q_fwd = fwdtab; - 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->ancount = 0; - hp->nscount = 0; - hp->arcount = 0; - if ((qp->q_msg = (u_char *)malloc((unsigned)msglen)) == NULL) { - syslog(LOG_ERR, "forw: %m"); - qfree(qp); - return (FW_SERVFAIL); - } - bcopy(msg, qp->q_msg, qp->q_msglen = msglen); - if (!qp->q_fwd) { - hp->rd = 0; - qp->q_addr[0].stime = tt; - } - -#ifdef SLAVE_FORWARD - if (forward_only) - schedretry(qp, (time_t)slave_retry); - else -#endif /* SLAVE_FORWARD */ - schedretry(qp, qp->q_fwd ?(2*RETRYBASE) :retrytime(qp)); - - nsa = Q_NEXTADDR(qp, 0); - dprintf(1, (ddt, - "forw: forw -> [%s].%d ds=%d nsid=%d id=%d %dms retry %dsec\n", - inet_ntoa(nsa->sin_addr), - ntohs(nsa->sin_port), ds, - ntohs(qp->q_nsid), ntohs(qp->q_id), - (qp->q_addr[0].nsdata != NULL) - ? qp->q_addr[0].nsdata->d_nstime - : -1, - qp->q_time - tt.tv_sec)); -#ifdef DEBUG - if (debug >= 10) - fp_query(msg, ddt); -#endif - if (sendto(ds, 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", - inet_ntoa(nsa->sin_addr), ntohs(nsa->sin_port)); - nameserIncr(nsa->sin_addr, nssSendtoErr); - } - nameserIncr(fp->sin_addr, nssRcvdFwdQ); - nameserIncr(nsa->sin_addr, nssSentFwdQ); - if (qpp) - *qpp = qp; - hp->rd = 1; - return (0); -} - -/* struct qdatagram * - * aIsUs(addr) - * scan the datagramq (our list of interface addresses) for "addr" - * returns: - * pointer to qdatagram entry or NULL if no match is found - * notes: - * INADDR_ANY ([0.0.0.0]) is on the datagramq, so it's considered "us" - * author: - * Paul Vixie (DECWRL) April 1991 - */ -struct qdatagram * -aIsUs(addr) - struct in_addr addr; -{ - struct qdatagram *dqp; - - for (dqp = datagramq; dqp != QDATAGRAM_NULL; dqp = dqp->dq_next) { - if (addr.s_addr == dqp->dq_addr.s_addr) { - return dqp; - } - } - return NULL; -} - -/* haveComplained(tag1, tag2) - * check to see if we have complained about (tag1,tag2) recently - * (note that these are declared as pointers but are never deref'd) - * returns: - * boolean: have we complained recently? - * side-effects: - * outdated complaint records removed from our static list - * author: - * Paul Vixie (DECWRL) April 1991 - */ -int -haveComplained(tag1, tag2) - char *tag1, *tag2; -{ - struct complaint { - char *tag1, *tag2; - time_t expire; - struct complaint *next; - }; - static struct complaint *List = NULL; - struct complaint *cur, *next, *prev; - int r = 0; - - for (cur = List, prev = NULL; cur; prev = cur, cur = next) { - next = cur->next; - if (tt.tv_sec > cur->expire) { - if (prev) - prev->next = next; - else - List = next; - free((char*) cur); - cur = prev; - } else if ((tag1 == cur->tag1) && (tag2 == cur->tag2)) { - r++; - } - } - if (!r) { - cur = (struct complaint *)malloc(sizeof(struct complaint)); - cur->tag1 = tag1; - cur->tag2 = tag2; - cur->expire = tt.tv_sec + INIT_REFRESH; /* "10 minutes" */ - cur->next = NULL; - if (prev) - prev->next = cur; - else - List = cur; - } - return r; -} - -/* void - * nslookupComplain(sysloginfo, queryname, complaint, dname, a_rr) - * Issue a complaint about a dangerous situation found by nslookup(). - * params: - * sysloginfo is a string identifying the complainant. - * queryname is the domain name associated with the problem. - * complaint is a string describing what is wrong. - * dname and a_rr are the problematic other name server. - */ -void -nslookupComplain(sysloginfo, queryname, complaint, dname, a_rr) - char *sysloginfo, *queryname, *complaint, *dname; - register struct databuf *a_rr; -{ - dprintf(2, (ddt, "NS '%s' %s\n", dname, complaint)); - if (sysloginfo && queryname && !haveComplained(queryname, complaint)) - { - char buf[512]; - - /* 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 - )); - syslog(LOG_INFO, buf); - } -} - -/* - * nslookup(nsp, qp, syslogdname, sysloginfo) - * Lookup the address for each nameserver in `nsp' and add it to - * the list saved in the qinfo structure pointed to by `qp'. - * Omits information about nameservers that we shouldn't ask. - * Detects the following dangerous operations: - * One of the A records for one of the nameservers in nsp - * refers to the address of one of our own interfaces; - * One of the A records refers to the nameserver port on - * the host that asked us this question. - * returns: the number of addresses added, or -1 if a dangerous operation - * is detected. - * side effects: - * if a dangerous situation is detected and (syslogdname && sysloginfo), - * calls syslog. - */ -int -nslookup(nsp, qp, syslogdname, sysloginfo) - struct databuf *nsp[]; - register struct qinfo *qp; - char *syslogdname; - char *sysloginfo; -{ - register struct namebuf *np; - register struct databuf *dp, *nsdp; - register struct qserv *qs; - register int n; - register unsigned int i; - struct hashbuf *tmphtp; - char *dname, *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)); - - 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)); - - /* don't put in servers we have tried */ - for (i = 0; i < qp->q_nusedns; i++) { - if (qp->q_usedns[i] == nsdp) { - dprintf(2, (ddt, - "skipping used NS w/name %s\n", - nsdp->d_data)); - goto skipserver; - } - } - - 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)); - continue; - } - found_arr = 0; - oldn = n; - - /* look for name server addresses */ - for (dp = np->n_data; dp != NULL; dp = dp->d_next) { - struct in_addr nsa; - - 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) - 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) && - (dp->d_ttl < (curtime+900)) && - !(dp->d_flags & DB_F_HINT) ) - { - dprintf(3, (ddt, - "nslookup: stale entry '%s'\n", - np->n_dname)); - /* Cache invalidate the NS RR's */ - if (dp->d_ttl < curtime) - delete_all(np, class, T_A); - n = oldn; - break; - } -#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, - syslogdname, sysloginfo); -#endif /*VALIDATE*/ - - found_arr++; - nsa = *(struct in_addr *)dp->d_data; - /* don't put in duplicates */ - qs = qp->q_addr; - for (i = 0; i < n; i++, qs++) - if (qs->ns_addr.sin_addr.s_addr == nsa.s_addr) - goto skipaddr; - qs->ns_addr.sin_family = AF_INET; - qs->ns_addr.sin_port = ns_port; - qs->ns_addr.sin_addr = nsa; - qs->ns = nsdp; - qs->nsdata = dp; - qs->nretry = 0; - /* - * if we are being asked to fwd a query whose - * nameserver list includes our own name/address(es), - * then we have detected a lame delegation and rather - * than melt down the network and hose down the other - * servers (who will hose us in return), we'll return - * -1 here which will cause SERVFAIL to be sent to - * the client's resolver which will hopefully then - * shut up. - * - * (originally done in nsContainsUs by vix@dec mar92; - * moved into nslookup by apb@und jan1993) - */ - if (aIsUs(nsa)) { - static char *complaint = "contains our address"; - nslookupComplain(sysloginfo, syslogdname, - complaint, dname, dp); - return (-1); - } - /* - * If we want to forward to a host that asked us - * this question then either we or they are sick - * (unless they asked from some port other than - * their nameserver port). (apb@und jan1993) - */ - if (bcmp((char *)&qp->q_from, (char *)&qs->ns_addr, - sizeof(qp->q_from)) == 0) - { - static char *complaint = "forwarding loop"; - nslookupComplain(sysloginfo, syslogdname, - complaint, dname, dp); - return (-1); - } - /* - * Don't forward queries to bogus servers. Note - * that this is unlike the previous tests, which - * are fatal to the query. Here we just skip the - * server, which is only fatal if it's the last - * server. Note also that we antialias here -- all - * A RR's of a server are considered the same server, - * and if any of them is bogus we skip the whole - * server. Those of you using multiple A RR's to - * load-balance your servers will (rightfully) lose - * here. But (unfortunately) only if they are bogus. - */ - if (addr_on_netlist(nsa, boglist)) - goto skipserver; - - n++; - if (n >= NSMAX) - goto out; - skipaddr: ; - } - dprintf(8, (ddt, "nslookup: %d ns addrs\n", n)); - if (found_arr == 0 && !(qp->q_flags & Q_SYSTEM)) - (void) sysquery(dname, class, T_A, NULL, 0); -skipserver: ; - } -out: - dprintf(3, (ddt, "nslookup: %d ns addrs total\n", n)); - qp->q_naddr = n; -#ifdef DATUMREFCNT - /* must be run before the sort */ - for (i = naddr ; i < n ; i++) { - qp->q_addr[i].nsdata->d_rcnt++; - qp->q_addr[i].ns->d_rcnt++; - } -#endif - if (n > 1) { - qsort((char *)qp->q_addr, n, sizeof(struct qserv), - (int (*)__P((const void *, const void *)))qcomp); - } - return (n - naddr); -} - -/* - * qcomp - compare two NS addresses, and return a negative, zero, or - * positive value depending on whether the first NS address is - * "better than", "equally good as", or "inferior to" the second - * NS address. - * - * How "goodness" is defined (for the purposes of this routine): - * - If the estimated round trip times differ by an amount deemed significant - * then the one with the smaller estimate is preferred; else - * - If we can determine which one is topologically closer then the - * closer one is preferred; else - * - The one with the smaller estimated round trip time is preferred - * (zero is returned if the two estimates are identical). - * - * How "topological closeness" is defined (for the purposes of this routine): - * Ideally, named could consult some magic map of the Internet and - * determine the length of the path to an arbitrary destination. Sadly, - * no such magic map exists. However, named does have a little bit of - * topological information in the form of the sortlist (which includes - * the directly connected subnet(s), the directly connected net(s), and - * any additional nets that the administrator has added using the "sortlist" - * directive in the bootfile. Thus, if only one of the addresses matches - * something in the sortlist then it is considered to be topologically - * closer. If both match, but match different entries in the sortlist, - * then the one that matches the entry closer to the beginning of the - * sorlist is considered to be topologically closer. In all other cases, - * topological closeness is ignored because it's either indeterminate or - * equal. - * - * How times are compared: - * Both times are rounded to the closest multiple of the NOISE constant - * defined below and then compared. If the rounded values are equal - * then the difference in the times is deemed insignificant. Rounding - * is used instead of merely taking the absolute value of the difference - * because doing the latter would make the ordering defined by this - * routine be incomplete in the mathematical sense (e.g. A > B and - * B > C would not imply A > C). The mathematics are important in - * practice to avoid core dumps in qsort(). - * - * XXX: this doesn't solve the European root nameserver problem very well. - * XXX: we should detect and mark as inferior nameservers that give bogus - * answers - * - * (this was originally vixie's stuff but almquist fixed fatal bugs in it - * and wrote the above documentation) - */ - -/* - * RTT delta deemed to be significant, in milliseconds. With the current - * definition of RTTROUND it must be a power of 2. - */ -#define NOISE 128 /* milliseconds; 0.128 seconds */ - -#define sign(x) (((x) < 0) ? -1 : ((x) > 0) ? 1 : 0) -#define RTTROUND(rtt) (((rtt) + (NOISE >> 1)) & ~(NOISE - 1)) - -int -qcomp(qs1, qs2) - struct qserv *qs1, *qs2; -{ - int pos1, pos2, pdiff; - u_long rtt1, rtt2; - long tdiff; - - if ((!qs1->nsdata) || (!qs2->nsdata)) - return 0; - rtt1 = qs1->nsdata->d_nstime; - rtt2 = qs2->nsdata->d_nstime; - - dprintf(10, (ddt, "qcomp(%s, %s) %lu (%lu) - %lu (%lu) = %lu", - inet_ntoa(qs1->ns_addr.sin_addr), - inet_ntoa(qs2->ns_addr.sin_addr), - rtt1, RTTROUND(rtt1), rtt2, RTTROUND(rtt2), - rtt1 - rtt2)); - if (RTTROUND(rtt1) == RTTROUND(rtt2)) { - pos1 = position_on_netlist(qs1->ns_addr.sin_addr, nettab); - pos2 = position_on_netlist(qs2->ns_addr.sin_addr, nettab); - pdiff = pos1 - pos2; - dprintf(10, (ddt, ", pos1=%d, pos2=%d\n", pos1, pos2)); - if (pdiff) - return (pdiff); - } else { - dprintf(10, (ddt, "\n")); - } - tdiff = rtt1 - rtt2; - return (sign(tdiff)); -} -#undef sign -#undef RTTROUND - -/* - * Arrange that forwarded query (qp) is retried after t seconds. - * Query list will be sorted after z_time is updated. - */ -void -schedretry(qp, t) - struct qinfo *qp; - time_t t; -{ - register struct qinfo *qp1, *qp2; - -#ifdef DEBUG - if (debug > 3) { - fprintf(ddt,"schedretry(0x%x, %ld sec)\n", qp, (long)t); - if (qp->q_time) - fprintf(ddt, - "WARNING: schedretry(%#x, %d) q_time already %d\n", - qp, t, qp->q_time); - } -#endif - t += (u_long) tt.tv_sec; - qp->q_time = t; - - if ((qp1 = retryqp) == NULL) { - retryqp = qp; - qp->q_next = NULL; - return; - } - if (t < qp1->q_time) { - qp->q_next = qp1; - retryqp = qp; - return; - } - while ((qp2 = qp1->q_next) != NULL && qp2->q_time < t) - qp1 = qp2; - qp1->q_next = qp; - qp->q_next = qp2; -} - -/* - * Unsched is called to remove a forwarded query entry. - */ -void -unsched(qp) - struct qinfo *qp; -{ - register struct qinfo *np; - - dprintf(3, (ddt, "unsched(%#x, %d )\n", qp, ntohs(qp->q_id))); - if (retryqp == qp) { - retryqp = qp->q_next; - } else { - for (np=retryqp; np->q_next != QINFO_NULL; np = np->q_next) { - if (np->q_next != qp) - continue; - np->q_next = qp->q_next; /* dequeue */ - break; - } - } - qp->q_next = QINFO_NULL; /* sanity check */ - qp->q_time = 0; -} - -/* - * Retry is called to retransmit query 'qp'. - */ -void -retry(qp) - register struct qinfo *qp; -{ - register int n; - register HEADER *hp; - struct sockaddr_in *nsa; - - dprintf(3, (ddt, "retry(x%x) id=%d\n", qp, ntohs(qp->q_id))); - - if (qp->q_msg == NULL) { /* XXX - why? */ - qremove(qp); - return; - } - - 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)); - if (qp->q_stream) /* return failure code on stream */ - goto fail; - qremove(qp); - return; - } - - /* try next address */ - n = qp->q_curaddr; - if (qp->q_fwd) { - qp->q_fwd = qp->q_fwd->next; - if (qp->q_fwd) - goto found; - /* out of forwarders, try direct queries */ - } else - ++qp->q_addr[n].nretry; - if (!forward_only) { - do { - if (++n >= (int)qp->q_naddr) - n = 0; - if (qp->q_addr[n].nretry < MAXRETRY) - goto found; - } while (n != qp->q_curaddr); - } -fail: - /* - * Give up. Can't reach destination. - */ - hp = (HEADER *)(qp->q_cmsg ? qp->q_cmsg : qp->q_msg); - if (qp->q_flags & Q_PRIMING) { - /* Can't give up priming */ - unsched(qp); - schedretry(qp, (time_t)60*60); /* 1 hour */ - hp->rcode = NOERROR; /* Lets be safe, reset the query */ - hp->qr = hp->aa = 0; - qp->q_fwd = fwdtab; - for (n = 0; n < (int)qp->q_naddr; n++) - qp->q_addr[n].nretry = 0; - return; - } - dprintf(5, (ddt, "give up\n")); - n = ((HEADER *)qp->q_cmsg ? qp->q_cmsglen : qp->q_msglen); - hp->id = qp->q_id; - hp->qr = 1; - hp->ra = 1; - hp->rd = 1; - hp->rcode = SERVFAIL; -#ifdef DEBUG - if (debug >= 10) - fp_query(qp->q_msg, 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))); - } - nameserIncr(qp->q_from.sin_addr, nssSentFail); - qremove(qp); - return; - -found: - if (qp->q_fwd == 0 && qp->q_addr[n].nretry == 0) - qp->q_addr[n].stime = tt; - qp->q_curaddr = n; - hp = (HEADER *)qp->q_msg; - hp->rd = (qp->q_fwd ? 1 : 0); - nsa = Q_NEXTADDR(qp, n); - dprintf(1, (ddt, - "%s(addr=%d n=%d) -> [%s].%d ds=%d nsid=%d id=%d %dms\n", - (qp->q_fwd ? "reforw" : "resend"), - n, qp->q_addr[n].nretry, - inet_ntoa(nsa->sin_addr), - ntohs(nsa->sin_port), ds, - ntohs(qp->q_nsid), ntohs(qp->q_id), - (qp->q_addr[n].nsdata != 0) - ? qp->q_addr[n].nsdata->d_nstime - : (-1))); -#ifdef DEBUG - if (debug >= 10) - fp_query(qp->q_msg, ddt); -#endif - /* NOSTRICT */ - if (sendto(ds, 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)); - } - hp->rd = 1; /* leave set to 1 for dup detection */ - nameserIncr(nsa->sin_addr, nssSentDupQ); - unsched(qp); -#ifdef SLAVE_FORWARD - if(forward_only) - schedretry(qp, (time_t)slave_retry); - else -#endif /* SLAVE_FORWARD */ - schedretry(qp, qp->q_fwd ? (2*RETRYBASE) : retrytime(qp)); -} - -/* - * Compute retry time for the next server for a query. - * Use a minimum time of RETRYBASE (4 sec.) or twice the estimated - * service time; * back off exponentially on retries, but place a 45-sec. - * ceiling on retry times for now. (This is because we don't hold a reference - * on servers or their addresses, and we have to finish before they time out.) - */ -time_t -retrytime(qp) - struct qinfo *qp; -{ - time_t t, u, v; - struct qserv *ns = &qp->q_addr[qp->q_curaddr]; - - if (ns->nsdata != NULL) - t = (time_t) MAX(RETRYBASE, 2 * ns->nsdata->d_nstime / 1000); - else - t = (time_t) RETRYBASE; - u = t << ns->nretry; - v = MIN(u, RETRY_TIMEOUT); /* max. retry timeout for now */ - dprintf(3, (ddt, "retrytime: nstime%ldms t%ld nretry%ld u%ld : v%ld\n", - ns->nsdata ?(long)(ns->nsdata->d_nstime / 1000) :(long)-1, - (long)t, (long)ns->nretry, (long)u, (long)v)); - return (v); -} - -void -qflush() -{ - while (qhead) - qremove(qhead); - qhead = QINFO_NULL; -} - -void -qremove(qp) - register struct qinfo *qp; -{ - dprintf(3, (ddt, "qremove(x%x)\n", qp)); - - if (qp->q_flags & Q_ZSERIAL) - qserial_answer(qp, 0); - unsched(qp); - qfree(qp); -} - -#if defined(__STDC__) || defined(__GNUC__) -struct qinfo * -qfindid(u_int16_t id) -#else -struct qinfo * -qfindid(id) - register u_int16_t id; -#endif -{ - register struct qinfo *qp; - - dprintf(3, (ddt, "qfindid(%d)\n", ntohs(id))); - for (qp = qhead; qp!=QINFO_NULL; qp = qp->q_link) { - if (qp->q_nsid == id) - return(qp); - } - dprintf(5, (ddt, "qp not found\n")); - return (NULL); -} - -struct qinfo * -#ifdef DMALLOC -qnew_tagged(file, line) - char *file; - int line; -#else -qnew() -#endif -{ - register struct qinfo *qp; - - if ((qp = (struct qinfo *) -#ifdef DMALLOC - dcalloc(file, line, -#else - calloc( -#endif - 1, sizeof(struct qinfo))) == 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; - return (qp); -} - -void -qfree(qp) - struct qinfo *qp; -{ - register struct qinfo *np; - register struct databuf *dp; -#ifdef DATUMREFCNT - 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 - if (qp->q_msg) - free(qp->q_msg); - if (qp->q_cmsg) - free(qp->q_cmsg); -#ifdef DATUMREFCNT - for (i = 0 ; i < (int)qp->q_naddr ; i++) { - dp = qp->q_addr[i].ns; - if (dp) - if (--(dp->d_rcnt)) { - dprintf(3, (ddt, "qfree: ns %s rcnt %d\n", - dp->d_data, - dp->d_rcnt)); - } else { - dprintf(3, (ddt, "qfree: ns %s rcnt %d delayed\n", - dp->d_data, - dp->d_rcnt)); - free((char*)dp); - } - dp = qp->q_addr[i].nsdata; - if (dp) - if ((--(dp->d_rcnt))) { - dprintf(3, (ddt, "qfree: nsdata %08.8X rcnt %d\n", - *(int32_t *)(dp->d_data), - dp->d_rcnt)); - } else { - dprintf(3, (ddt, "qfree: nsdata %08.8X rcnt %d delayed\n", - *(int32_t *)(dp->d_data), - dp->d_rcnt)); - free((char*)dp); - } - } -#endif - if( qhead == qp ) { - qhead = qp->q_link; - } else { - for( np=qhead; np->q_link != QINFO_NULL; np = np->q_link ) { - if( np->q_link != qp ) continue; - np->q_link = qp->q_link; /* dequeue */ - break; - } - } - free((char *)qp); -} diff --git a/usr.sbin/named/ns_func.h b/usr.sbin/named/ns_func.h deleted file mode 100644 index eaff3bfe11fb..000000000000 --- a/usr.sbin/named/ns_func.h +++ /dev/null @@ -1,140 +0,0 @@ -/* 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 $ - */ - -/* ++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, - struct databuf **, int, u_int)), - send_msg __P((u_char *, int, struct qinfo *)), - findns __P((struct namebuf **, int, - struct databuf **, int *, int)), - finddata __P((struct namebuf *, int, int, HEADER *, - char **, int *, int *)), - wanted __P((struct databuf *, int, int)), - add_data __P((struct namebuf *, - struct databuf **, - u_char *, int)); -/* --from ns_resp.c-- */ - -/* ++from ns_req.c++ */ -extern void ns_req __P((u_char *, int, int, - struct qstream *, - struct sockaddr_in *, - int)); -extern int stale __P((struct databuf *)), - make_rr __P((char *, struct databuf *, - u_char *, int, int)), - doaddinfo __P((HEADER *, u_char *, int)), - doaddauth __P((HEADER *, u_char *, int, - struct namebuf *, - struct databuf *)); -/* --from ns_req.c-- */ - -/* ++from ns_forw.c++ */ -extern time_t retrytime __P((struct qinfo *)); -extern int ns_forw __P((struct databuf *nsp[], - u_char *msg, - int msglen, - struct sockaddr_in *fp, - struct qstream *qsp, - int dfd, - struct qinfo **qpp, - char *dname, - struct namebuf *np)), - haveComplained __P((char *, char *)), - nslookup __P((struct databuf *nsp[], - struct qinfo *qp, - char *syslogdname, - 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 *)), - schedretry __P((struct qinfo *, time_t)), - unsched __P((struct qinfo *)), - retry __P((struct qinfo *)), - qflush __P((void)), - qremove __P((struct qinfo *)), - qfree __P((struct qinfo *)); -extern struct qinfo *qfindid __P((u_int16_t)), -#ifdef DMALLOC - *qnew_tagged __P((void)); -# define qnew() qnew_tagged(__FILE__, __LINE__) -#else - *qnew(); -#endif -/* --from ns_forw.c-- */ - -/* ++from ns_main.c++ */ -extern u_int32_t net_mask __P((struct in_addr)); -extern void sqrm __P((struct qstream *)), - sqflush __P((struct qstream *allbut)), - dqflush __P((time_t gen)), - sq_done __P((struct qstream *)), - ns_setproctitle __P((char *, int)), - getnetconf __P((void)); -extern struct netinfo *findnetinfo __P((struct in_addr)); -/* --from ns_main.c-- */ - -/* ++from ns_maint.c++ */ -extern void ns_maint __P((void)), - sched_maint __P((void)), -#ifdef CLEANCACHE - remove_zone __P((struct hashbuf *, int, int)), -#else - remove_zone __P((struct hashbuf *, int)), -#endif - loadxfer __P((void)), - qserial_answer __P((struct qinfo *, u_int32_t)); -extern SIG_FN endxfer __P((void)); -#ifdef DEBUG -extern void printzoneinfo __P((int)); -#endif -/* --from ns_maint.c-- */ - -/* ++from ns_sort.c++ */ -extern struct netinfo *local __P((struct sockaddr_in *)); -extern void sort_response __P((u_char *, int, - struct netinfo *, - u_char *)); -/* --from ns_sort.c-- */ - -/* ++from ns_init.c++ */ -extern void ns_init __P((char *)); -/* --from ns_init.c-- */ - -/* ++from ns_ncache.c++ */ -extern void cache_n_resp __P((u_char *, int)); -/* --from ns_ncache.c-- */ - -/* ++from ns_stats.c++ */ -extern void ns_stats __P((void)); -extern void qtypeIncr __P((int qtype)); -extern struct nameser *nameserFind __P((struct in_addr addr, int flags)); -#define NS_F_INSERT 0x0001 -extern void nameserIncr __P((struct in_addr addr, - enum nameserStats which)); -/* --from ns_stats.c-- */ - -/* ++from ns_validate.c++ */ -extern int -#ifdef NCACHE - validate __P((char *, struct sockaddr_in *, - int, int, char *, int, int)), -#else - validate __P((char *, struct sockaddr_in *, - int, int, char *, int)), -#endif - 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 *, - char *, char *)); -/* --from ns_validate.c-- */ diff --git a/usr.sbin/named/ns_glob.h b/usr.sbin/named/ns_glob.h deleted file mode 100644 index 993d14d01385..000000000000 --- a/usr.sbin/named/ns_glob.h +++ /dev/null @@ -1,245 +0,0 @@ -/* - * from ns.h 4.33 (Berkeley) 8/23/90 - * $Id: ns_glob.h,v 1.7 1994/06/11 22:04:46 vixie Exp $ - */ - -/* - * ++Copyright++ 1986 - * - - * Copyright (c) 1986 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - - * Portions Copyright (c) 1993 by Digital Equipment Corporation. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies, and that - * the name of Digital Equipment Corporation not be used in advertising or - * publicity pertaining to distribution of the document or software without - * specific, written prior permission. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT - * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - * - - * --Copyright-- - */ - -/* - * Global variables for the name server. - */ - -#ifdef DEBUG -DECL int debug INIT(0); -DECL FILE *ddt INIT(NULL); -#endif - - /* list of open streams */ -DECL struct qstream *streamq INIT(QSTREAM_NULL); - - /* list of datagram interfaces */ -DECL struct qdatagram *datagramq INIT(QDATAGRAM_NULL); - - /* often set to the current time */ -DECL struct timeval tt; - - /* head of allocated queries */ -DECL struct qinfo *qhead 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); - - /* listening TCP socket */ -DECL int vs INIT(-1); - - /* received SIGHUP, need to reload db */ -DECL int needreload INIT(0); - - /* need to call ns_maint()*/ -DECL int needmaint INIT(0); - - /* how often does ns_maint() need to be called, in seconds? */ - /* (beware: this is also the upper bound on named_xfer real time) */ -DECL int maint_interval INIT(15*60); - - /* need to reload secondary zone(s) */ -DECL int needzoneload INIT(0); - - /* need to dump database */ -DECL int needToDoadump INIT(0); - - /* need to checkpoint cache */ -DECL int needToChkpt INIT(0); - - /* need to dump statistics */ -DECL int needStatsDump INIT(0); - -#ifdef ALLOW_UPDATES - /* need to exit (may need to doadump - * first, if database has changed since - * it was last dumped/booted). Gets - * set by shutdown signal handler - * (onintr) - */ -DECL int needToExit INIT(0); -#endif /* ALLOW_UPDATES */ - -#ifdef QRYLOG - /* is query logging turned on? */ -DECL int qrylog INIT(0); -#endif /*QRYLOG*/ - - /* is this a root server that should therefore not recurse? */ -DECL int NoRecurse INIT(0); - -/* - * We keep a list of favored networks headed by nettab. - * There are three (possibly empty) parts to this list, in this order: - * 1. directly attached (sub)nets. - * 2. logical networks for directly attached subnetted networks. - * 3. networks from the sort list. - * The value (*elocal) points at the first entry in the second part of the - * list, if any, while (*enettab) points at the first entry in the sort list. - */ -DECL struct netinfo *nettab INIT(NULL); -DECL struct netinfo **elocal INIT(&nettab); -DECL struct netinfo **enettab INIT(&nettab); - -#ifdef XFRNETS - /* list of nets we're willing to zone transfer to */ -DECL struct netinfo *xfrnets INIT(NULL); -#endif - -#ifdef BOGUSNS - /* list of bogus nameservers */ -DECL struct netinfo *boglist INIT(NULL); -#endif - - /* loopback net */ -DECL struct netinfo netloop; - - /* port to which we send queries */ -DECL u_int16_t ns_port; - - /* Source addr of last packet */ -DECL struct sockaddr_in from_addr; - - /* Source addr size of last packet */ -DECL int from_len; - - /* Used by ns_stats */ -DECL time_t boottime, - resettime; - - /* next query to retry */ -DECL struct qinfo *retryqp INIT(NULL); - - /* default boot file */ -#ifdef BOOTFILE -DECL char *bootfile INIT(BOOTFILE); -#else -DECL char *bootfile INIT(_PATH_BOOT); -#endif - - /* default debug output file */ -#ifdef DEBUGFILE -DECL char *debugfile INIT(DEBUGFILE); -#else -DECL char *debugfile INIT(_PATH_DEBUG); -#endif - -#ifdef WANT_PIDFILE - /* file to store current named PID */ -#ifdef PIDFILE -DECL char *PidFile INIT(PIDFILE); -#else -DECL char *PidFile INIT(_PATH_PIDFILE); -#endif -#endif /*WANT_PIDFILE*/ - - /* zone information */ -DECL struct zoneinfo *zones INIT(NULL); - - /* number of zones in use */ -DECL int nzones INIT(0); - - /* true on slave server */ -DECL int forward_only INIT(0); - - /* set if we need a priming */ -DECL int needs_prime_cache INIT(0); - - /* is cache being primed */ -DECL int priming INIT(0); - - /* ptrs to dnames in msg for dn_comp */ -DECL u_char *dnptrs[40]; - - /* number of names in addinfo */ -DECL int addcount; - - /* name of cache file */ -DECL char *cache_file; - -#ifdef LOCALDOM - /* our local domain (deprecated in favor of resolv.conf) */ -DECL char *localdomain; -#endif - -#ifdef SLAVE_FORWARD - /* retry time when a slave */ -DECL int slave_retry INIT(4); -#endif - -#ifdef STATSFILE -DECL char *statsfile INIT(STATSFILE); -#else -DECL char *statsfile INIT(_PATH_STATS); -#endif - -DECL 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); diff --git a/usr.sbin/named/ns_init.c b/usr.sbin/named/ns_init.c deleted file mode 100644 index 82c2071ed2d6..000000000000 --- a/usr.sbin/named/ns_init.c +++ /dev/null @@ -1,808 +0,0 @@ -#if !defined(lint) && !defined(SABER) -static char sccsid[] = "@(#)ns_init.c 4.38 (Berkeley) 3/21/91"; -static char rcsid[] = "$Id:"; -#endif /* not lint */ - -/* - * ++Copyright++ 1986, 1990 - * - - * Copyright (c) 1986, 1990 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - - * Portions Copyright (c) 1993 by Digital Equipment Corporation. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies, and that - * the name of Digital Equipment Corporation not be used in advertising or - * publicity pertaining to distribution of the document or software without - * specific, written prior permission. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT - * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - * - - * --Copyright-- - */ - -#include <sys/param.h> -#include <sys/socket.h> -#include <sys/stat.h> -#include <netinet/in.h> -#include <arpa/nameser.h> -#include <arpa/inet.h> -#include <syslog.h> -#include <signal.h> -#include <resolv.h> -#include <stdio.h> -#include <errno.h> -#include <ctype.h> - -#include "named.h" - -#undef nsaddr - -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)); - -static struct zoneinfo *find_zone __P((char *, int, int)); - -/* - * Read boot file for configuration info. - */ -void -ns_init(bootfile) - char *bootfile; -{ - register struct zoneinfo *zp; - static int loads = 0; /* number of times loaded */ - - dprintf(1, (ddt, "\nns_init(%s)\n", bootfile)); - gettime(&tt); - - if (loads == 0) { - if ((zones = - (struct zoneinfo *)calloc(64, sizeof(struct zoneinfo))) - == NULL) { - syslog(LOG_ERR, - "Not enough memory to allocate initial zones array"); - exit(1); - } - nzones = 1; /* zone zero is cache data */ - /* allocate cache hash table, formerly the root hash table. */ - hashtab = savehash((struct hashbuf *)NULL); - - /* allocate root-hints/file-cache hash table */ - fcachetab = savehash((struct hashbuf *)NULL); - /* init zone data */ - zones[0].z_type = Z_CACHE; - } else { - /* Mark previous zones as not yet found in boot file. */ - for (zp = &zones[1]; zp < &zones[nzones]; zp++) - zp->z_flags &= ~Z_FOUND; -#ifdef LOCALDOM - if (localdomain) { - free(localdomain); - localdomain = NULL; - } -#endif - free_forwarders(); - free_netlist(enettab); -#ifdef XFRNETS - free_netlist(&xfrnets); -#endif -#ifdef BOGUSNS - free_netlist(&boglist); -#endif - forward_only = 0; - } - - dprintf(3, (ddt, "\n content of zones before loading \n")); -#ifdef DEBUG - if (debug >= 3) { - content_zone(nzones - 1); - } -#endif - boot_read(bootfile); - - /* erase all old zones that were not found */ - for (zp = &zones[1]; zp < &zones[nzones]; zp++) { - if (zp->z_type && (zp->z_flags & Z_FOUND) == 0) { -#ifdef CLEANCACHE - remove_zone(hashtab, zp - zones, 1); -#else - remove_zone(hashtab, zp - zones); -#endif -#ifdef SECURE_ZONES - free_netlist(&zp->secure_nets); -#endif - syslog(LOG_NOTICE, "Zone \"%s\" was removed", zp->z_origin); - free(zp->z_origin); - free(zp->z_source); - bzero((char *) zp, sizeof(*zp)); - } - } - dprintf(2, (ddt,"\n content of zones after loading\n")); - -#ifdef DEBUG - if (debug >= 2) { - content_zone(nzones-1); - } -#endif - - /* - * Schedule calls to ns_maint(). - */ - if (!needmaint) - sched_maint(); - dprintf(1, (ddt, "exit ns_init()%s\n", - needmaint ? ", need maintenance immediately" : "")); - loads++; -} - -/* - * Read the actual boot file. - * Set up to recurse. - */ -static void -boot_read(bootfile) - char *bootfile; -{ - register struct zoneinfo *zp; - char buf[BUFSIZ], obuf[BUFSIZ], *source; - FILE *fp; - int type; - int class; -#ifdef GEN_AXFR - char *class_p; -#endif - struct stat f_time; - static int tmpnum = 0; /* unique number for tmp zone files */ -#ifdef ALLOW_UPDATES - char *cp, *flag; -#endif - int slineno; /* Saved global line number. */ - int i; - - if ((fp = fopen(bootfile, "r")) == NULL) { - syslog(LOG_ERR, "%s: %m", bootfile); - exit(1); - } - - slineno = lineno; - lineno = 0; - - while (!feof(fp) && !ferror(fp)) { - if (!getword(buf, sizeof(buf), fp)) - continue; - /* read named.boot keyword and process args */ - if (strcasecmp(buf, "directory") == 0) { - (void) getword(buf, sizeof(buf), fp); - if (chdir(buf) < 0) { - syslog(LOG_CRIT, "directory %s: %m\n", - buf); - exit(1); - } - continue; - } else if (strcasecmp(buf, "sortlist") == 0) { - get_netlist(fp, enettab, ALLOW_NETS, buf); - continue; - } else if (strcasecmp(buf, "max-fetch") == 0) { - max_xfers_running = getnum(fp, bootfile, 0); - 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) { - get_netlist(fp, &boglist, ALLOW_HOSTS, buf); - continue; -#endif -#ifdef XFRNETS - } else if ((strcasecmp(buf, "tcplist") == 0) || - (strcasecmp(buf, "xfrnets") == 0)) { - get_netlist(fp, &xfrnets, ALLOW_NETS, buf); - continue; -#endif -#ifdef LOCALDOM - } 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, '/')) - class = get_class(class_p+1); -#endif - } else if (strncasecmp(buf, "primary", 7) == 0) { - type = Z_PRIMARY; - class = C_IN; -#ifdef GEN_AXFR - if (class_p = strchr(buf, '/')) - class = get_class(class_p+1); -#endif - } else if (strncasecmp(buf, "secondary", 9) == 0) { - type = Z_SECONDARY; - class = C_IN; -#ifdef GEN_AXFR - if (class_p = strchr(buf, '/')) - class = get_class(class_p+1); -#endif -#ifdef STUBS - } else if (strncasecmp(buf, "stub", 4) == 0) { - type = Z_STUB; - class = C_IN; -#ifdef GEN_AXFR - if (class_p = strchr(buf, '/')) - class = get_class(class_p+1); -#endif -#endif - } else { - syslog(LOG_ERR, "%s: line %d: unknown field '%s'\n", - bootfile, lineno+1, buf); - endline(fp); - continue; - } - - /* - * read zone origin - */ - if (!getword(obuf, sizeof(obuf), fp)) { - syslog(LOG_ERR, "%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); - while ((--i >= 0) && (obuf[i] == '.')) - obuf[i] = '\0'; - dprintf(1, (ddt, "zone origin %s", obuf[0]?obuf:".")); - /* - * read source file or host address - */ - if (!getword(buf, sizeof(buf), fp)) { - syslog(LOG_ERR, "%s: line %d: missing %s\n", - bootfile, lineno, -#ifdef STUBS - (type == Z_SECONDARY || type == Z_STUB) -#else - (type == Z_SECONDARY) -#endif - ?"host address" - :"source file"); - continue; - } - - /* 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 - */ - if (nzones % 64 == 0) { - dprintf(1, (ddt, - "Reallocating zones structure\n")); - /* - * Realloc() not used since it might damage zones - * if an error occurs - */ - zp = (struct zoneinfo *) - malloc((64 + nzones) - * sizeof(struct zoneinfo)); - if (zp == (struct zoneinfo *)0) { - syslog(LOG_ERR, - "no memory for more zones"); - dprintf(1, (ddt, - "Out of memory for new zones\n" - ) - ); - endline(fp); - continue; - } - bcopy((char *)zones, (char *)zp, - nzones * sizeof(struct zoneinfo)); - bzero((char *)&zp[nzones], - 64 * sizeof(struct zoneinfo)); - free(zones); - zones = zp; - } - zp = &zones[nzones++]; - gotzone: - zp->z_origin = savestr(obuf); - gotcache: - zp->z_type = type; - zp->z_class = class; - } - zp->z_addrcnt = 0; - - switch (type) { - case Z_CACHE: - source = savestr(buf); - dprintf(1, (ddt, ", source = %s\n", source)); - zp->z_refresh = 0; /* by default, no dumping */ - if (getword(buf, sizeof(buf), fp)) { -#ifdef notyet - zp->z_refresh = atoi(buf); - if (zp->z_refresh <= 0) { - syslog(LOG_ERR, - "%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); -#endif - endline(fp); - } - /* - * If we've loaded this file, and the file has - * not been modified and contains no $include, - * then there's no need to reload. - */ - if (zp->z_source && - !strcmp(source, zp->z_source) && - !(zp->z_flags & Z_INCLUDE) && - stat(zp->z_source, &f_time) != -1 && - zp->z_ftime == f_time.st_mtime) { - dprintf(1, (ddt, "cache is up to date\n")); - if (source != cache_file) - free(source); - break; /* zone is already up to date */ - } - - /* file has changed, or hasn't been loaded yet */ - if (zp->z_source) { - free(zp->z_source); -#ifdef CLEANCACHE - remove_zone(fcachetab, 0, 1); -#else - remove_zone(fcachetab, 0); -#endif - } - zp->z_source = source; - dprintf(1, (ddt, "reloading zone\n")); - (void) db_load(zp->z_source, zp->z_origin, zp, 0); - break; - - case Z_PRIMARY: - source = savestr(buf); -#ifdef ALLOW_UPDATES - if (getword(buf, sizeof(buf), fp)) { - endline(fp); - flag = buf; - while (flag) { - cp = strchr(flag, ','); - if (cp) - *cp++ = 0; - if (strcasecmp(flag, "dynamic") == 0) - zp->z_flags |= Z_DYNAMIC; - else if (strcasecmp(flag, "addonly") == 0) - zp->z_flags |= Z_DYNADDONLY; - else { - syslog(LOG_ERR, - "%s: line %d: bad flag '%s'\n", - bootfile, lineno, flag); - } - flag = cp; - } - } -#else /*ALLOW_UPDATES*/ - endline(fp); -#endif - - dprintf(1, (ddt, ", source = %s\n", source)); - /* - * If we've loaded this file, and the file has - * not been modified and contains no $include, - * then there's no need to reload. - */ - if (zp->z_source && - !strcmp(source, zp->z_source) && - !(zp->z_flags & Z_INCLUDE) && - stat(zp->z_source, &f_time) != -1 && - zp->z_ftime == f_time.st_mtime) { - dprintf(1, (ddt, "zone is up to date\n")); - free(source); - break; /* zone is already up to date */ - } - if (zp->z_source) { - free(zp->z_source); -#ifdef CLEANCACHE - remove_zone(hashtab, zp - zones, 1); -#else - remove_zone(hashtab, zp - zones); -#endif - } - zp->z_source = source; - zp->z_flags &= ~Z_AUTH; - dprintf(1, (ddt, "reloading zone\n")); - if (db_load(zp->z_source, zp->z_origin, zp, 0) == 0) - zp->z_flags |= Z_AUTH; -#ifdef ALLOW_UPDATES - /* Guarantee calls to ns_maint() */ - zp->z_refresh = maint_interval; -#else - zp->z_refresh = 0; /* no maintenance needed */ - zp->z_time = 0; -#endif - break; - - case Z_SECONDARY: -#ifdef STUBS - case Z_STUB: -#endif - source = NULL; - dprintf(1, (ddt, "\n\taddrs: ")); - do { - if (!inet_aton(buf, - &zp->z_addr[zp->z_addrcnt]) - ) { - source = savestr(buf); - endline(fp); - break; - } - dprintf(1, (ddt, "%s, ", buf)); - if ((int)++zp->z_addrcnt > NSMAX - 1) { - zp->z_addrcnt = NSMAX - 1; - dprintf(1, (ddt, - "\nns.h NSMAX reached\n")); - } - } while (getword(buf, sizeof(buf), fp)); - dprintf(1, (ddt, "addrcnt = %d\n", zp->z_addrcnt)); - if (!source) { - /* - * We will always transfer this zone again - * after a reload. - */ - sprintf(buf, "/%s/NsTmp%d.%d", _PATH_TMPDIR, - getpid(), tmpnum++); - source = savestr(buf); - zp->z_flags |= Z_TMP_FILE; - } else - zp->z_flags &= ~Z_TMP_FILE; - /* - * If we had a backup file name, and it was changed, - * free old zone and start over. If we don't have - * current zone contents, try again now in case - * we have a new server on the list. - */ - if (zp->z_source && - (strcmp(source, zp->z_source) || - (stat(zp->z_source, &f_time) == -1 || - (zp->z_ftime != f_time.st_mtime)))) { - dprintf(1, (ddt, "backup file changed\n")); - free(zp->z_source); - zp->z_source = NULL; - zp->z_flags &= ~Z_AUTH; - zp->z_serial = 0; /* force xfer */ -#ifdef CLEANCACHE - remove_zone(hashtab, zp - zones, 1); -#else - remove_zone(hashtab, zp - zones); -#endif - } - if (zp->z_source) - free(source); - else - zp->z_source = source; - if (!(zp->z_flags & Z_AUTH)) - zoneinit(zp); -#ifdef FORCED_RELOAD - else { - /* - ** Force secondary to try transfer right away - ** after SIGHUP. - */ - if (reloading) { - zp->z_time = tt.tv_sec; - needmaint = 1; - } - } -#endif /* FORCED_RELOAD */ - break; - - } - 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; - 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)); - } - (void) my_fclose(fp); - lineno = slineno; -} - -static void -zoneinit(zp) - register struct zoneinfo *zp; -{ - struct stat sb; - - /* - * Try to load zone from backup file, - * if one was specified and it exists. - * If not, or if the data are out of date, - * we will refresh the zone from a primary - * immediately. - */ - if (!zp->z_source) - return; - if (stat(zp->z_source, &sb) == -1 || - db_load(zp->z_source, zp->z_origin, zp, 0) != 0) { - /* - * Set zone to be refreshed immediately. - */ - zp->z_refresh = INIT_REFRESH; - zp->z_retry = INIT_REFRESH; - zp->z_time = tt.tv_sec; - needmaint = 1; - } else { - zp->z_flags |= Z_AUTH; - } -} - -#ifdef ALLOW_UPDATES -/* - * Look for the authoritative zone with the longest matching RHS of dname - * and return its zone # or zero if not found. - */ -int -findzone(dname, class) - char *dname; - int class; -{ - char *dZoneName, *zoneName; - int dZoneNameLen, zoneNameLen; - int maxMatchLen = 0; - int maxMatchZoneNum = 0; - int zoneNum; - - dprintf(4, (ddt, "findzone(dname=%s, class=%d)\n", dname, class)); -#ifdef DEBUG - if (debug >= 5) { - fprintf(ddt, "zone dump:\n"); - for (zoneNum = 1; zoneNum < nzones; zoneNum++) - printzoneinfo(zoneNum); - } -#endif - - dZoneName = strchr(dname, '.'); - if (dZoneName == NULL) - dZoneName = ""; /* root */ - else - dZoneName++; /* There is a '.' in dname, so use remainder of - string as the zone name */ - dZoneNameLen = strlen(dZoneName); - for (zoneNum = 1; zoneNum < nzones; zoneNum++) { - zoneName = (zones[zoneNum]).z_origin; - zoneNameLen = strlen(zoneName); - /* The zone name may or may not end with a '.' */ - if (zoneName[zoneNameLen - 1] == '.') - zoneNameLen--; - if (dZoneNameLen != zoneNameLen) - continue; - dprintf(5, (ddt, "about to strncasecmp('%s', '%s', %d)\n", - dZoneName, zoneName, dZoneNameLen)); - if (strncasecmp(dZoneName, zoneName, dZoneNameLen) == 0) { - dprintf(5, (ddt, "match\n")); - /* - * See if this is as long a match as any so far. - * Check if "<=" instead of just "<" so that if - * root domain (whose name length is 0) matches, - * we use it's zone number instead of just 0 - */ - if (maxMatchLen <= zoneNameLen) { - maxMatchZoneNum = zoneNum; - maxMatchLen = zoneNameLen; - } - } else { - dprintf(5, (ddt, "no match\n")); - } - } - dprintf(4, (ddt, "findzone: returning %d\n", maxMatchZoneNum)); - return (maxMatchZoneNum); -} -#endif /* ALLOW_UPDATES */ - -static void -get_forwarders(fp) - FILE *fp; -{ - char buf[BUFSIZ]; - register struct fwdinfo *fip = NULL, *ftp = NULL; - -#ifdef SLAVE_FORWARD - int forward_count = 0; -#endif - - dprintf(1, (ddt, "forwarders ")); - - /* on mulitple forwarder lines, move to end of the list */ -#ifdef SLAVE_FORWARD - if (fwdtab != NULL){ - forward_count++; - for (fip = fwdtab; fip->next != NULL; fip = fip->next) - forward_count++; - } -#else - if (fwdtab != NULL) { - for (fip = fwdtab; fip->next != NULL; fip = fip->next) { - ; - } - } -#endif /* SLAVE_FORWARD */ - - while (getword(buf, sizeof(buf), fp)) { - if (strlen(buf) == 0) - break; - dprintf(1, (ddt," %s",buf)); - if (ftp == NULL) - ftp = (struct fwdinfo *)malloc(sizeof(struct fwdinfo)); - if (inet_aton(buf, &ftp->fwdaddr.sin_addr)) { - ftp->fwdaddr.sin_port = ns_port; - ftp->fwdaddr.sin_family = AF_INET; - } else { - syslog(LOG_ERR, "'%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, - "Forwarder '%s' ignored, my address", - buf); - dprintf(1, (ddt, " (ignored, my address)")); - continue; - } -#endif /* FWD_LOOP */ - ftp->next = NULL; - if (fwdtab == NULL) - fwdtab = ftp; /* First time only */ - else - fip->next = ftp; - fip = ftp; - ftp = NULL; -#ifdef SLAVE_FORWARD - forward_count++; -#endif /* SLAVE_FORWARD */ - } - if (ftp) - free((char *)ftp); - -#ifdef SLAVE_FORWARD - /* - ** Set the slave retry time to 60 seconds total divided - ** between each forwarder - */ - if (forward_count != 0) { - slave_retry = (int) (60 / forward_count); - if(slave_retry <= 0) - slave_retry = 1; - } -#endif - - dprintf(1, (ddt, "\n")); -#ifdef DEBUG - if (debug > 2) { - for (ftp = fwdtab; ftp != NULL; ftp = ftp->next) { - fprintf(ddt,"ftp x%x [%s] next x%x\n", - ftp, - inet_ntoa(ftp->fwdaddr.sin_addr), - ftp->next); - } - } -#endif -} - -static void -free_forwarders() -{ - register struct fwdinfo *ftp, *fnext; - - for (ftp = fwdtab; ftp != NULL; ftp = fnext) { - fnext = ftp->next; - free((char *)ftp); - } - fwdtab = NULL; -} - -static struct zoneinfo * -find_zone(name, type, class) - char *name; - int type, class; -{ - register struct zoneinfo *zp; - - for (zp = &zones[1]; zp < &zones[nzones]; zp++) { - if (zp->z_type == type && zp->z_class == class && - strcasecmp(name, zp->z_origin) == 0) { - dprintf(2, (ddt, ", old zone (%d)", zp - zones)); - return (zp); - } - } - dprintf(2, (ddt, ", new zone")); - return NULL; -} - -#ifdef DEBUG -/* prints out the content of zones */ -static void -content_zone(end) - int end; -{ - int i; - - for (i = 1; i <= end; i++) { - printzoneinfo(i); - } -} -#endif diff --git a/usr.sbin/named/ns_main.c b/usr.sbin/named/ns_main.c deleted file mode 100644 index 8b04a49caa79..000000000000 --- a/usr.sbin/named/ns_main.c +++ /dev/null @@ -1,1581 +0,0 @@ -#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 4.9.1.19 1994/07/23 23:23:56 vixie Exp $"; -#endif /* not lint */ - -/* - * ++Copyright++ 1986, 1989, 1990 - * - - * Copyright (c) 1986, 1989, 1990 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - - * Portions Copyright (c) 1993 by Digital Equipment Corporation. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies, and that - * the name of Digital Equipment Corporation not be used in advertising or - * publicity pertaining to distribution of the document or software without - * specific, written prior permission. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT - * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - * - - * --Copyright-- - */ - -#if !defined(lint) && !defined(SABER) -char copyright[] = -"@(#) Copyright (c) 1986, 1989, 1990 The Regents of the University of California.\n\ - portions Copyright (c) 1993 Digital Equipment Corporation\n\ - portions Copyright (c) 1993 Berkeley Network Software Consortium\n\ - All rights reserved.\n"; -#endif /* not lint */ - -/* - * Internet Name server (see rfc883 & others). - */ - -#include <sys/param.h> -#include <sys/file.h> -#include <sys/stat.h> -#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 - * would need to be included before socket.h - */ -#endif -#include <sys/ioctl.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <net/if.h> -#include <arpa/nameser.h> -#include <arpa/inet.h> -#include <fcntl.h> -#include <stdio.h> -#include <syslog.h> -#include <errno.h> -#include <signal.h> -#include <netdb.h> -#include <resolv.h> -#if defined(SVR4) -# include <sys/sockio.h> -#endif - -#define MAIN_PROGRAM -#include "named.h" -#undef MAIN_PROGRAM - -#undef nsaddr - - /* UDP receive, TCP send buffer size */ -static const int rbufsize = 8 * 1024; - -static struct sockaddr_in nsaddr; -static u_int16_t local_ns_port; /* our service port */ -static fd_set mask; /* open descriptors */ -static char **Argv = NULL; -static char *LastArg = NULL; /* end of argv */ - -static struct qstream *sqadd __P((void)); -static void sq_query __P((struct qstream *)), - opensocket __P((struct qdatagram *)), -#ifdef DEBUG - printnetinfo __P((struct netinfo *)), -#endif - setdebug __P((int)); -static int sq_here __P((struct qstream *)); - -static SIG_FN onintr __P(()), - maint_alarm __P(()), - setdumpflg __P(()), - onhup __P(()), -#if defined(QRYLOG) && defined(SIGWINCH) - setQrylogFlg __P(()), -#endif - setIncrDbgFlg __P(()), - setNoDbgFlg __P(()), -#ifdef SIGSYS - sigprof __P(()), -#endif /* SIGSYS */ - setchkptflg __P(()), - setstatsflg __P(()); - -static void -usage() -{ - fprintf(stderr, -"Usage: named [-d #] [-q] [-r] [-p port[/localport]] [[-b] bootfile]\n"); - exit(1); -} - -/*ARGSUSED*/ -void -main(argc, argv, envp) - int argc; - char *argv[], *envp[]; -{ - register int n, udpcnt; - register char *arg; - register struct qstream *sp; - register struct qdatagram *dqp; - struct qstream *nextsp; - int nfds; - const int on = 1; - int len; - int rfd, size; - time_t lasttime, maxctime; - u_char buf[BUFSIZ]; -#ifndef SYSV - struct sigvec vec; -#endif - fd_set tmpmask; - struct timeval t, *tp; - struct qstream *candidate = QSTREAM_NULL; - char **argp; -#ifdef PID_FIX - char oldpid[10]; -#endif -#ifdef WANT_PIDFILE - FILE *fp; /* file descriptor for pid file */ -#endif -#ifdef IP_OPTIONS - u_char ip_opts[50]; /* arbitrary size */ -#endif - - local_ns_port = ns_port = htons(NAMESERVER_PORT); - - /* - ** Save start and extent of argv for ns_setproctitle(). - */ - - Argv = argp = argv; - while (*argp) - argp++; - LastArg = argp[-1] + strlen(argp[-1]); - - (void) umask(022); - /* XXX - should use getopt here */ - while (--argc > 0) { - arg = *++argv; - if (*arg == '-') { - while (*++arg) - switch (*arg) { - case 'b': - if (--argc <= 0) - usage(); - bootfile = savestr(*++argv); - break; - - case 'd': - ++argv; - - if (*argv != 0) { - if (**argv == '-') { - argv--; - break; - } -#ifdef DEBUG - debug = atoi(*argv); -#endif - --argc; - } -#ifdef DEBUG - if (debug <= 0) - debug = 1; - setdebug(1); -#endif - break; - - case 'p': - /* use nonstandard port number. - * usage: -p remote/local - * remote is the port number to which - * we send queries. local is the port - * on which we listen for queries. - * local defaults to same as remote. - */ - if (--argc <= 0) - usage(); - ns_port = htons((u_int16_t) - atoi(*++argv)); - { - char *p = strchr(*argv, '/'); - if (p) { - local_ns_port = - htons((u_int16_t) - atoi(p+1)); - } else { - local_ns_port = ns_port; - } - } - break; - -#ifdef QRYLOG - case 'q': - qrylog = 1; - break; -#endif - - case 'r': - NoRecurse = 1; - break; - - default: - usage(); - } - } else - bootfile = savestr(*argv); - } - -#ifdef DEBUG - if (!debug) -#endif - for (n = getdtablesize() - 1; n > 2; n--) - (void) close(n); /* don't use my_close() here */ -#ifdef DEBUG - else { - fprintf(ddt, "Debug turned ON, Level %d\n",debug); - fprintf(ddt, "Version = %s\n", Version); - fprintf(ddt, "bootfile = %s\n", bootfile); - } -#endif - - n = 0; -#if defined(DEBUG) && defined(LOG_PERROR) - if (debug) - n = LOG_PERROR; -#endif -#ifdef LOG_DAEMON - openlog("named", LOG_PID|LOG_CONS|LOG_NDELAY|n, LOGFAC); -#else - openlog("named", LOG_PID); -#endif - -#ifdef WANT_PIDFILE - /* tuck my process id away */ -#ifdef PID_FIX - fp = fopen(PidFile, "r+"); - if (fp != NULL) { - (void) fgets(oldpid, sizeof(oldpid), fp); - (void) rewind(fp); - fprintf(fp, "%d\n", getpid()); - (void) my_fclose(fp); - } -#else /*PID_FIX*/ - fp = fopen(PidFile, "w"); - if (fp != NULL) { - fprintf(fp, "%d\n", getpid()); - (void) my_fclose(fp); - } -#endif /*PID_FIX*/ -#endif /*WANT_PIDFILE*/ - - syslog(LOG_NOTICE, "starting. %s", Version); - - _res.options &= ~(RES_DEFNAMES | RES_DNSRCH | RES_RECURSE); - - nsaddr.sin_family = AF_INET; - nsaddr.sin_addr.s_addr = INADDR_ANY; - nsaddr.sin_port = local_ns_port; - - /* - ** Open stream port. - */ - for (n = 0; ; n++) { - if ((vs = socket(AF_INET, SOCK_STREAM, 0)) < 0) { - syslog(LOG_ERR, "socket(SOCK_STREAM): %m"); - exit(1); - } - if (setsockopt(vs, SOL_SOCKET, SO_REUSEADDR, (char *)&on, - sizeof(on)) != 0) - { - syslog(LOG_ERR, "setsockopt(vs, reuseaddr): %m"); - (void) my_close(vs); - continue; - } - if (bind(vs, (struct sockaddr *)&nsaddr, sizeof(nsaddr)) == 0) - break; - - if (errno != EADDRINUSE || n > 4) { - if (errno == EADDRINUSE) { - syslog(LOG_ERR, - "There may be a name server already running"); - syslog(LOG_ERR, "exiting"); - } else { - syslog(LOG_ERR, "bind(vs, [%s].%d): %m", - inet_ntoa(nsaddr.sin_addr), - ntohs(nsaddr.sin_port)); - } -#if defined(WANT_PIDFILE) && defined(PID_FIX) - /* put old pid back */ - if (atoi(oldpid) && (fp = fopen(PidFile, "w"))) { - fprintf(fp, "%s", oldpid); - (void) my_fclose(fp); - _exit(1); - } -#endif /*WANT_PIDFILE && PID_FIX*/ - exit(1); - } else { /* Retry opening the socket a few times */ - my_close(vs); - sleep(1); - } - } - if (listen(vs, 5) != 0) { - syslog(LOG_ERR, "listen(vs, 5): %m"); - exit(1); - } - - /* - * named would be terminated if one of these is sent and no handler - */ - (void) signal(SIGINT, setdumpflg); - (void) signal(SIGQUIT, setchkptflg); - (void) signal(SIGIOT, setstatsflg); -#if defined(SIGUSR1) && defined(SIGUSR2) - (void) signal(SIGUSR1, setIncrDbgFlg); - (void) signal(SIGUSR2, setNoDbgFlg); -#else /* SIGUSR1&&SIGUSR2 */ - (void) signal(SIGEMT, setIncrDbgFlg); - (void) signal(SIGFPE, setNoDbgFlg); -#endif /* SIGUSR1&&SIGUSR2 */ - -#if defined(SIGWINCH) && defined(QRYLOG) - (void) signal(SIGWINCH, setQrylogFlg); -#endif - - /* - * Get list of local addresses and set up datagram sockets. - */ - getnetconf(); - - /* - ** Initialize and load database. - */ - gettime(&tt); - buildservicelist(); - buildprotolist(); - ns_init(bootfile); -#ifdef DEBUG - if (debug) { - fprintf(ddt, "Network and sort list:\n"); - printnetinfo(nettab); - } -#endif - - time(&boottime); - resettime = boottime; - - (void) signal(SIGHUP, onhup); -#if defined(SIGXFSZ) - (void) signal(SIGXFSZ, onhup); /* wierd DEC Hesiodism, harmless */ -#endif -#if defined(SYSV) - (void) signal(SIGCLD, endxfer); - (void) signal(SIGALRM, maint_alarm); -#else - bzero((char *)&vec, sizeof(vec)); - vec.sv_handler = maint_alarm; - vec.sv_mask = sigmask(SIGCHLD); - (void) sigvec(SIGALRM, &vec, (struct sigvec *)NULL); - - vec.sv_handler = endxfer; - vec.sv_mask = sigmask(SIGALRM); - (void) sigvec(SIGCHLD, &vec, (struct sigvec *)NULL); -#endif /* SYSV */ - (void) signal(SIGPIPE, SIG_IGN); -#ifdef SIGSYS - (void) signal(SIGSYS, sigprof); -#endif /* SIGSYS */ - -#ifdef ALLOW_UPDATES - /* Catch SIGTERM so we can dump the database upon shutdown if it - has changed since it was last dumped/booted */ - (void) signal(SIGTERM, onintr); -#endif - - dprintf(1, (ddt, "database initialized\n")); - t.tv_usec = 0; - - /* - * Fork and go into background now that - * we've done any slow initialization - * and are ready to answer queries. - */ -#ifdef USE_SETSID - if ( -#ifdef DEBUG - !debug || -#endif - !isatty(0)) { - if (fork() > 0) - exit(0); - setsid(); -#ifdef DEBUG - if (!debug) -#endif - { - n = open(_PATH_DEVNULL, O_RDONLY); - (void) dup2(n, 0); - (void) dup2(n, 1); - (void) dup2(n, 2); - if (n > 2) - (void) my_close(n); - } - } -#else -#ifdef DEBUG - if (!debug) -#endif - { -#ifdef HAVE_DAEMON - daemon(1, 0); -#else - switch (fork()) { - case -1: - syslog(LOG_ERR, "fork: %m"); - exit(1); - /*FALLTHROUGH*/ - case 0: - /* child */ - break; - default: - /* parent */ - exit(0); - } - n = open(_PATH_DEVNULL, O_RDONLY); - (void) dup2(n, 0); - (void) dup2(n, 1); - (void) dup2(n, 2); - if (n > 2) - (void) my_close(n); -#ifdef SYSV - setpgrp(); -#else - { - struct itimerval ival; - - /* - * The open below may hang on pseudo ttys if the person - * who starts named logs out before this point. - * - * needmaint may get set inapropriately if the open - * hangs, but all that will happen is we will see that - * no maintenance is required. - */ - bzero((char *)&ival, sizeof(ival)); - ival.it_value.tv_sec = 120; - (void) setitimer(ITIMER_REAL, &ival, - (struct itimerval *)NULL); - n = open(_PATH_TTY, O_RDWR); - ival.it_value.tv_sec = 0; - (void) setitimer(ITIMER_REAL, &ival, - (struct itimerval *)NULL); - if (n > 0) { - (void) ioctl(n, TIOCNOTTY, (char *)NULL); - (void) my_close(n); - } - } -#endif /* SYSV */ -#endif /* HAVE_DAEMON */ - } -#endif /* USE_SETSID */ -#ifdef WANT_PIDFILE - /* tuck my process id away again */ - fp = fopen(PidFile, "w"); - if (fp != NULL) { - fprintf(fp, "%d\n", getpid()); - (void) my_fclose(fp); - } -#endif - - syslog(LOG_NOTICE, "Ready to answer queries.\n"); - prime_cache(); - nfds = getdtablesize(); /* get the number of file descriptors */ - if (nfds > FD_SETSIZE) { - nfds = FD_SETSIZE; /* Bulletproofing */ - syslog(LOG_ERR, "Return from getdtablesize() > FD_SETSIZE"); - } - FD_ZERO(&mask); - FD_SET(vs, &mask); - for (dqp = datagramq; dqp != QDATAGRAM_NULL; dqp = dqp->dq_next) - FD_SET(dqp->dq_dfd, &mask); - for (;;) { -#ifdef DEBUG - if (ddt && debug == 0) { - fprintf(ddt,"Debug turned OFF\n"); - (void) my_fclose(ddt); - ddt = 0; - } -#endif -#ifdef ALLOW_UPDATES - if (needToExit) { - struct zoneinfo *zp; - sigblock(~0); /* - * Block all blockable signals - * to ensure a consistant - * state during final dump - */ - dprintf(1, (ddt, "Received shutdown signal\n")); - for (zp = zones; zp < &zones[nzones]; zp++) { - if (zp->z_flags & Z_CHANGED) - zonedump(zp); - } - exit(0); - } -#endif /* ALLOW_UPDATES */ - if (needreload) { - needreload = 0; - db_reload(); - } - if (needStatsDump) { - needStatsDump = 0; - ns_stats(); - } - if (needzoneload) { - needzoneload = 0; - loadxfer(); - } - if (needmaint) { - needmaint = 0; - ns_maint(); - } - if(needToChkpt) { - needToChkpt = 0; - doachkpt(); - } - if(needToDoadump) { - needToDoadump = 0; - doadump(); - } - /* - ** Wait until a query arrives - */ - if (retryqp != NULL) { - gettime(&tt); - /* - ** The tv_sec field might be unsigned - ** and thus cannot be negative. - */ - if ((int32_t) retryqp->q_time <= tt.tv_sec) { - retry(retryqp); - continue; - } - t.tv_sec = (int32_t) retryqp->q_time - tt.tv_sec; - tp = &t; - } else - 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) - continue; - - for (dqp = datagramq; - dqp != QDATAGRAM_NULL; - dqp = dqp->dq_next) { - if (FD_ISSET(dqp->dq_dfd, &tmpmask)) - for (udpcnt = 0; udpcnt < 25; udpcnt++) { /*XXX*/ - from_len = sizeof(from_addr); - if ((n = recvfrom(dqp->dq_dfd, buf, sizeof(buf), 0, - (struct sockaddr *)&from_addr, &from_len)) < 0) - { - if ((n < 0) && (errno == PORT_WOULDBLK)) - break; - syslog(LOG_WARNING, "recvfrom: %m"); - break; - } - if (n == 0) - break; - gettime(&tt); - dprintf(1, (ddt, - "\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))); -#ifdef DEBUG - if (debug >= 10) - fp_query(buf, ddt); -#endif - /* - * Consult database to get the answer. - */ - gettime(&tt); - ns_req(buf, n, PACKETSZ, QSTREAM_NULL, &from_addr, - dqp->dq_dfd); - } - } - /* - ** Process stream connection. - ** - ** Note that a "continue" in here takes us back to the select() - ** which, if our accept() failed, will bring us back here. - */ - if (FD_ISSET(vs, &tmpmask)) { - from_len = sizeof(from_addr); - rfd = accept(vs, - (struct sockaddr *)&from_addr, - &from_len); - if (rfd < 0 && errno == EINTR) - continue; - if (rfd < 0 && errno == EMFILE && streamq) { - maxctime = 0; - candidate = NULL; - for (sp = streamq; sp; sp = nextsp) { - nextsp = sp->s_next; - if (sp->s_refcnt) - continue; - gettime(&tt); - lasttime = tt.tv_sec - sp->s_time; - if (lasttime >= VQEXPIRY) - sqrm(sp); - else if (lasttime > maxctime) { - candidate = sp; - maxctime = lasttime; - } - } - if (candidate) - sqrm(candidate); - continue; - } - if (rfd < 0) { - syslog(LOG_WARNING, "accept: %m"); - continue; - } - if ((n = fcntl(rfd, F_GETFL, 0)) < 0) { - syslog(LOG_ERR, "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"); - (void) my_close(rfd); - continue; - } -#if defined(IP_OPTIONS) - len = sizeof ip_opts; - if (getsockopt(rfd, IPPROTO_IP, IP_OPTIONS, - (char *)ip_opts, &len) < 0) { - syslog(LOG_ERR, - "getsockopt(rfd, IP_OPTIONS): %m"); - (void) my_close(rfd); - continue; - } - if (len != 0) { - nameserIncr(from_addr.sin_addr, nssRcvdOpts); - if (!haveComplained((char*) - from_addr.sin_addr.s_addr, - "rcvd ip options")) { - syslog(LOG_NOTICE, - "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, - "setsockopt(!IP_OPTIONS): %m"); - (void) my_close(rfd); - continue; - } - } -#endif - if (setsockopt(rfd, SOL_SOCKET, SO_KEEPALIVE, - (char *)&on, sizeof(on)) < 0) { - syslog(LOG_ERR, - "setsockopt(rfd, KEEPALIVE): %m"); - (void) my_close(rfd); - continue; - } - if ((sp = sqadd()) == QSTREAM_NULL) { - (void) my_close(rfd); - continue; - } - sp->s_rfd = rfd; /* stream file descriptor */ - sp->s_size = -1; /* amount of data to receive */ - gettime(&tt); - sp->s_time = tt.tv_sec; /* last transaction time */ - sp->s_from = from_addr; /* address to respond to */ - sp->s_bufp = (u_char *)&sp->s_tempsize; - FD_SET(rfd, &mask); - FD_SET(rfd, &tmpmask); - dprintf(1, (ddt, - "\nTCP connection from [%s].%d (fd %d)\n", - inet_ntoa(sp->s_from.sin_addr), - ntohs(sp->s_from.sin_port), rfd)); - } - if (streamq) { - dprintf(3, (ddt, "streamq = 0x%x\n",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)); - dprintf(5, (ddt, - "\tbufsize %d buf x%x bufp x%x\n", - sp->s_bufsize, sp->s_buf, sp->s_bufp)); - if (sp->s_size < 0) { - size = INT16SZ - - (sp->s_bufp - (u_char *)&sp->s_tempsize); - while (size > 0 && - (n = read(sp->s_rfd, sp->s_bufp, size)) > 0 - ) { - sp->s_bufp += n; - size -= n; - } - if ((n < 0) && (errno == PORT_WOULDBLK)) - continue; - if (n <= 0) { - sqrm(sp); - continue; - } - if ((sp->s_bufp - (u_char *)&sp->s_tempsize) == - INT16SZ) { - sp->s_size = htons(sp->s_tempsize); - if (sp->s_bufsize == 0) { - if ( (sp->s_buf = (u_char *) - malloc(rbufsize)) - == NULL) { - sp->s_buf = buf; - sp->s_size = sizeof(buf); - } else { - sp->s_bufsize = rbufsize; - } - } - if (sp->s_size > sp->s_bufsize && - sp->s_bufsize != 0 - ) { - sp->s_buf = (u_char *) - realloc((char *)sp->s_buf, - (unsigned)sp->s_size); - if (sp->s_buf == NULL) { - sp->s_buf = buf; - sp->s_bufsize = 0; - sp->s_size = sizeof(buf); - } else { - sp->s_bufsize = sp->s_size; - } - } - sp->s_bufp = sp->s_buf; - } - } - gettime(&tt); - sp->s_time = tt.tv_sec; - while (sp->s_size > 0 && - (n = read(sp->s_rfd, - sp->s_bufp, - sp->s_size) - ) > 0 - ) { - sp->s_bufp += n; - sp->s_size -= n; - } - /* - * we don't have enough memory for the query. - * if we have a query id, then we will send an - * error back to the user. - */ - if (sp->s_bufsize == 0 && - (sp->s_bufp - sp->s_buf > INT16SZ)) { - HEADER *hp; - - hp = (HEADER *)sp->s_buf; - hp->qr = 1; - hp->ra = 1; - hp->ancount = 0; - hp->qdcount = 0; - hp->nscount = 0; - hp->arcount = 0; - hp->rcode = SERVFAIL; - (void) writemsg(sp->s_rfd, sp->s_buf, - HFIXEDSZ); - continue; - } - if ((n == -1) && (errno == PORT_WOULDBLK)) - continue; - if (n <= 0) { - sqrm(sp); - continue; - } - /* - * Consult database to get the answer. - */ - if (sp->s_size == 0) { - nameserIncr(sp->s_from.sin_addr, nssRcvdTCP); - sq_query(sp); - ns_req(sp->s_buf, - sp->s_bufp - sp->s_buf, - sp->s_bufsize, sp, - &sp->s_from, -1); - /* ns_req() can call sqrm() - check for it */ - if (sq_here(sp)) { - sp->s_bufp = (u_char *)&sp->s_tempsize; - sp->s_size = -1; - } - continue; - } - } - } - /* NOTREACHED */ -} - -void -getnetconf() -{ - register struct netinfo *ntp; - struct netinfo *ontp; - struct ifconf ifc; - struct ifreq ifreq, *ifr; - struct qdatagram *dqp; - static int first = 1; - char buf[BUFSIZ], *cp, *cplim; - u_int32_t nm; - time_t my_generation = time(NULL); - - ifc.ifc_len = sizeof(buf); - ifc.ifc_buf = buf; - if (ioctl(vs, SIOCGIFCONF, (char *)&ifc) < 0) { - syslog(LOG_ERR, "get interface configuration: %m - exiting"); - exit(1); - } - ntp = NULL; -#if defined(AF_LINK) && !defined(RISCOS_BSD) -#define my_max(a, b) (a > b ? a : b) -#define my_size(p) my_max((p).sa_len, sizeof(p)) -#else -#define my_size(p) (sizeof (p)) -#endif - 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)) { -#undef my_size - ifr = (struct ifreq *)cp; - if (ifr->ifr_addr.sa_family != AF_INET || - ((struct sockaddr_in *) - &ifr->ifr_addr)->sin_addr.s_addr == 0) { - continue; - } - ifreq = *ifr; - /* - * Don't test IFF_UP, packets may still be received at this - * address if any other interface is up. - */ -#if !defined(BSD) || (BSD < 199103) - if (ioctl(vs, SIOCGIFADDR, (char *)&ifreq) < 0) { - syslog(LOG_ERR, "get interface addr: %m"); - continue; - } -#endif - dprintf(1, (ddt, "considering [%s]\n", - inet_ntoa(((struct sockaddr_in *) - &ifreq.ifr_addr)->sin_addr))); - /* build datagram queue */ - /* - * look for an already existing source interface address. - * This happens mostly when reinitializing. Also, if - * the machine has multiple point to point interfaces, then - * the local address may appear more than once. - */ - if (dqp = aIsUs(((struct sockaddr_in *)&ifreq.ifr_addr) - ->sin_addr)) { - dprintf(1, (ddt, - "dup interface address %s on %s\n", - inet_ntoa(((struct sockaddr_in *) - &ifreq.ifr_addr)->sin_addr), - ifreq.ifr_name)); - dqp->dq_gen = my_generation; - continue; - } - - /* - * Skip over address 0.0.0.0 since this will conflict - * with binding to wildcard address later. Interfaces - * which are not completely configured can have this addr. - */ - if (((struct sockaddr_in *)&ifreq.ifr_addr)->sin_addr.s_addr - == 0x00000000) { /* XXX */ - dprintf(1, (ddt, "skipping address 0.0.0.0 on %s\n", - ifreq.ifr_name)); - continue; - } - if ((dqp = (struct qdatagram *) - calloc(1, sizeof(struct qdatagram)) - ) == NULL) { - syslog(LOG_ERR, "getnetconf: malloc: %m"); - exit(12); - } - dqp->dq_next = datagramq; - datagramq = dqp; - dqp->dq_addr = ((struct sockaddr_in *) - &ifreq.ifr_addr)->sin_addr; - dqp->dq_gen = my_generation; - opensocket(dqp); - dprintf(1, (ddt, "listening [%s]\n", - inet_ntoa(((struct sockaddr_in *) - &ifreq.ifr_addr)->sin_addr))); - - /* - * Add interface to list of directly-attached (sub)nets - * for use in sorting addresses. - */ - if (ntp == NULL) { - ntp = (struct netinfo *)malloc(sizeof(struct netinfo)); - } - ntp->my_addr = ((struct sockaddr_in *) - &ifreq.ifr_addr)->sin_addr; -#ifdef SIOCGIFNETMASK - if (ioctl(vs, SIOCGIFNETMASK, (char *)&ifreq) < 0) { - syslog(LOG_ERR, "get netmask: %m"); - ntp->mask = net_mask(ntp->my_addr); - } else - ntp->mask = ((struct sockaddr_in *) - &ifreq.ifr_addr)->sin_addr.s_addr; -#else - /* 4.2 does not support subnets */ - ntp->mask = net_mask(ntp->my_addr); -#endif - if (ioctl(vs, SIOCGIFFLAGS, (char *)&ifreq) < 0) { - syslog(LOG_ERR, "get interface flags: %m"); - continue; - } -#ifdef IFF_LOOPBACK - if (ifreq.ifr_flags & IFF_LOOPBACK) -#else - /* test against 127.0.0.1 (yuck!!) */ - if (ntp->my_addr.s_addr == inet_addr("127.0.0.1")) /* XXX */ -#endif - { - if (netloop.my_addr.s_addr == 0) { - netloop.my_addr = ntp->my_addr; - netloop.mask = 0xffffffff; - netloop.addr = ntp->my_addr.s_addr; - dprintf(1, (ddt, "loopback address: x%lx\n", - netloop.my_addr.s_addr)); - } - continue; - } else if ((ifreq.ifr_flags & IFF_POINTOPOINT)) { - if (ioctl(vs, SIOCGIFDSTADDR, (char *)&ifreq) < 0) { - syslog(LOG_ERR, "get dst addr: %m"); - continue; - } - ntp->mask = 0xffffffff; - ntp->addr = ((struct sockaddr_in *) - &ifreq.ifr_addr)->sin_addr.s_addr; - } else { - ntp->addr = ntp->mask & ntp->my_addr.s_addr; - } - /* - * Place on end of list of locally-attached (sub)nets, - * but before logical nets for subnetted nets. - */ - ntp->next = *elocal; - *elocal = ntp; - if (elocal == enettab) - enettab = &ntp->next; - elocal = &ntp->next; - ntp = NULL; - } - if (ntp) - free((char *)ntp); - - /* - * now go through the datagramq and delete anything that - * does not have the current generation number. this is - * how we catch interfaces that go away or change their - * addresses. note that 0.0.0.0 is the wildcard element - * and should never be deleted by this code. - * - * XXX - need to update enettab/elocal as well. - */ - dqflush(my_generation); - - /* - * Create separate qdatagram structure for socket - * wildcard address. - */ - if (first) { - if (!(dqp = (struct qdatagram *)calloc(1, sizeof(*dqp)))) { - syslog(LOG_ERR, "getnetconf: malloc: %m"); - exit(12); - } - dqp->dq_next = datagramq; - datagramq = dqp; - dqp->dq_addr.s_addr = INADDR_ANY; - opensocket(dqp); - ds = dqp->dq_dfd; - } - - /* - * Compute logical networks to which we're connected - * based on attached subnets; - * used for sorting based on network configuration. - */ - for (ntp = nettab; ntp != NULL; ntp = ntp->next) { - nm = net_mask(ntp->my_addr); - if (nm != ntp->mask) { - if (findnetinfo(ntp->my_addr)) - continue; - ontp = (struct netinfo *) - malloc(sizeof(struct netinfo)); - if (ontp == NULL) { - syslog(LOG_ERR, "getnetconf: malloc: %m"); - exit(12); - } - ontp->my_addr = ntp->my_addr; - ontp->mask = nm; - ontp->addr = ontp->my_addr.s_addr & nm; - ontp->next = *enettab; - *enettab = ontp; - enettab = &ontp->next; - } - } - first = 0; -} - -/* - * Find netinfo structure for logical network implied by address "addr", - * if it's on list of local/favored networks. - */ -struct netinfo * -findnetinfo(addr) - struct in_addr addr; -{ - register struct netinfo *ntp; - u_int32_t net, mask; - - mask = net_mask(addr); - net = addr.s_addr & mask; - for (ntp = nettab; ntp != NULL; ntp = ntp->next) - if (ntp->addr == net && ntp->mask == mask) - return (ntp); - return ((struct netinfo *) NULL); -} - -#ifdef DEBUG -static void -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)); - } -} -#endif - -static void -opensocket(dqp) - register struct qdatagram *dqp; -{ - int n, m; - int on = 1; - - /* - * Open datagram sockets bound to interface address. - */ - if ((dqp->dq_dfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { - syslog(LOG_ERR, "socket(SOCK_DGRAM): %m - exiting"); - exit(1); - } - dprintf(1, (ddt, "dqp->dq_addr %s d_dfd %d\n", - inet_ntoa(dqp->dq_addr), dqp->dq_dfd)); - if (setsockopt(dqp->dq_dfd, SOL_SOCKET, SO_REUSEADDR, - (char *)&on, sizeof(on)) != 0) - { - syslog(LOG_ERR, "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) - && (m == sizeof(n)) - && (n < rbufsize)) { - (void) setsockopt(dqp->dq_dfd, SOL_SOCKET, SO_RCVBUF, - (char *)&rbufsize, sizeof(rbufsize)); - } -#endif /* SO_RCVBUF */ - if ((n = fcntl(dqp->dq_dfd, F_GETFL, 0)) < 0) { - syslog(LOG_ERR, "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"); - /* XXX press on regardless, but this really is a problem. */ - } - /* - * NOTE: Some versions of SunOS have problems with the following - * call to bind. Bind still seems to function on these systems - * if you comment out the exit inside the if. This may cause - * Suns with multiple interfaces to reply strangely. - */ - 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", - dqp->dq_dfd, inet_ntoa(nsaddr.sin_addr), - ntohs(nsaddr.sin_port)); -#if !defined(sun) - exit(1); -#endif - } -} - -/* -** Set flag saying to reload database upon receiving SIGHUP. -** Must make sure that someone isn't walking through a data -** structure at the time. -*/ - -static SIG_FN -onhup() -{ - int save_errno = errno; -#if defined(SYSV) - (void)signal(SIGHUP, onhup); -#endif /* SYSV */ - needreload = 1; - errno = save_errno; -} - -/* -** Set flag saying to call ns_maint() -** Must make sure that someone isn't walking through a data -** structure at the time. -*/ - -static SIG_FN -maint_alarm() -{ - int save_errno = errno; -#if defined(SYSV) - (void)signal(SIGALRM, maint_alarm); -#endif /* SYSV */ - needmaint = 1; - errno = save_errno; -} - - -#ifdef ALLOW_UPDATES -/* - * Signal handler to schedule shutdown. Just set flag, to ensure a consistent - * state during dump. - */ -static SIG_FN -onintr() -{ - needToExit = 1; -} -#endif /* ALLOW_UPDATES */ - -/* - * 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 - * (due to updates), and to avoid long disk I/O delays at signal-handler - * level - */ -static SIG_FN -setdumpflg() -{ - int save_errno = errno; -#if defined(SYSV) - (void)signal(SIGINT, setdumpflg); -#endif /* SYSV */ - needToDoadump = 1; - errno = save_errno; -} - -/* -** Turn on or off debuging by open or closeing the debug file -*/ - -static void -setdebug(code) - int code; -{ -#if defined(lint) && !defined(DEBUG) - code = code; -#endif -#ifdef DEBUG - - if (code) { - int n; - - ddt = freopen(debugfile, "w+", stderr); - if ( ddt == NULL) { - syslog(LOG_WARNING, "can't open debug file %s: %m", - debugfile); - debug = 0; - } else { -#if defined(SYSV) - setvbuf(ddt, NULL, _IOLBF, BUFSIZ); -#else - setlinebuf(ddt); -#endif - if ((n = fcntl(fileno(ddt), F_GETFL, 0)) < 0) { - syslog(LOG_WARNING, - "fcntl(ddt, F_GETFL): %m"); - } else { - (void) fcntl(fileno(ddt), F_SETFL, n|O_APPEND); - } - } - } else - debug = 0; - /* delay closing ddt, we might interrupt someone */ -#endif -} - -/* -** Catch a special signal and set debug level. -** -** If debuging is off then turn on debuging else increment the level. -** -** Handy for looking in on long running name servers. -*/ - -static SIG_FN -setIncrDbgFlg() -{ - int save_errno = errno; -#if defined(SYSV) - (void)signal(SIGUSR1, setIncrDbgFlg); -#endif /* SYSV */ -#ifdef DEBUG - if (debug == 0) { - debug++; - setdebug(1); - } else { - debug++; - } - if (debug) - fprintf(ddt, "Debug turned ON, Level %d\n", debug); -#endif - errno = save_errno; -} - -/* -** Catch a special signal to turn off debugging -*/ - -static SIG_FN -setNoDbgFlg() -{ - int save_errno = errno; -#if defined(SYSV) - (void)signal(SIGUSR2, setNoDbgFlg); -#endif /* SYSV */ - setdebug(0); - errno = save_errno; -} - -#if defined(QRYLOG) && defined(SIGWINCH) -/* -** Set flag for query logging -*/ -static SIG_FN -setQrylogFlg() -{ - int save_errno = errno; -#if defined(SYSV) - (void)signal(SIGWINCH, setQrylogFlg); -#endif /* SYSV */ - qrylog = !qrylog; - syslog(LOG_NOTICE, "query log %s\n", qrylog ?"on" :"off"); - errno = save_errno; -} -#endif /*QRYLOG && SIGWINCH*/ - -/* -** Set flag for statistics dump -*/ -static SIG_FN -setstatsflg() -{ - int save_errno = errno; -#if defined(SYSV) - (void)signal(SIGIOT, setstatsflg); -#endif /* SYSV */ - needStatsDump = 1; - errno = save_errno; -} - -static SIG_FN -setchkptflg() -{ - int save_errno = errno; -#if defined(SYSV) - (void)signal(SIGQUIT, setchkptflg); -#endif /* SYSV */ - needToChkpt = 1; - errno = save_errno; -} - -/* -** Catch a special signal SIGSYS -** -** this is setup to fork and exit to drop to /usr/tmp/gmon.out -** and keep the server running -*/ - -#ifdef SIGSYS -static SIG_FN -sigprof() -{ - int save_errno = errno; -#if defined(SYSV) - (void)signal(SIGSYS, sigprof); -#endif /* SYSV */ - dprintf(1, (ddt, "sigprof()\n")); - if (fork() == 0) - { - (void) chdir(_PATH_TMPDIR); - exit(1); - } - errno = save_errno; -} -#endif /* SIGSYS */ - -/* -** Routines for managing stream queue -*/ - -static struct qstream * -sqadd() -{ - register struct qstream *sqp; - - if (!(sqp = (struct qstream *)calloc(1, sizeof(struct qstream)))) { - syslog(LOG_ERR, "sqadd: calloc: %m"); - return (QSTREAM_NULL); - } - dprintf(3, (ddt, "sqadd(x%x)\n", sqp)); - - sqp->s_next = streamq; - streamq = sqp; - return (sqp); -} - -/* sqrm(qp) - * remove stream queue structure `qp'. - * no current queries may refer to this stream when it is removed. - * side effects: - * memory is deallocated. sockets are closed. lists are relinked. - */ -void -sqrm(qp) - register struct qstream *qp; -{ - register struct qstream *qsp; - - dprintf(2, (ddt, "sqrm(%#x, %d ) rfcnt=%d\n", - qp, qp->s_rfd, qp->s_refcnt)); - - if (qp->s_bufsize != 0) - free(qp->s_buf); - FD_CLR(qp->s_rfd, &mask); - (void) my_close(qp->s_rfd); - if (qp == streamq) { - streamq = qp->s_next; - } else { - for (qsp = streamq; - qsp && (qsp->s_next != qp); - qsp = qsp->s_next) - ; - if (qsp) { - qsp->s_next = qp->s_next; - } - } - free((char *)qp); -} - -/* void - * sqflush(allbut) - * call sqrm() on all open streams except `allbut' - * side effects: - * global list `streamq' modified - * idiocy: - * is N^2 due to the scan inside of sqrm() - */ -void -sqflush(allbut) - register struct qstream *allbut; -{ - register struct qstream *sp, *spnext; - - for (sp = streamq; sp != NULL; sp = spnext) { - spnext = sp->s_next; - if (sp != allbut) - sqrm(sp); - } -} - -/* void - * dqflush(gen) - * close/deallocate all the udp sockets, unless `gen' != (time_t)0 - * in which case all those not matching this generation will - * be deleted except the 0.0.0.0 element, and syslog() will - * be called whenever something is deleted. - * side effects: - * global list `datagramq' is modified - */ -void -dqflush(gen) - register time_t gen; -{ - register struct qdatagram *dqp, *pqp, *nqp; - - for (pqp = NULL, dqp = datagramq; - dqp != NULL; - pqp = dqp, dqp = nqp) { - nqp = dqp->dq_next; - if (gen != (time_t)0) { - if (dqp->dq_addr.s_addr == INADDR_ANY || - dqp->dq_gen == gen) - continue; - syslog(LOG_CRIT, "interface [%s] missing; deleting", - inet_ntoa(dqp->dq_addr)); - } - if (pqp != NULL) - pqp->dq_next = dqp->dq_next; - else - datagramq = dqp->dq_next; - free(dqp); - } -} - -/* int - * sq_here(sp) - * determine whether stream 'sp' is still on the streamq - * return: - * boolean: is it here? - */ -static int -sq_here(sp) - register struct qstream *sp; -{ - register struct qstream *t; - - for (t = streamq; t != NULL; t = t->s_next) - if (t == sp) - return (1); - return (0); -} - -/* - * Initiate query on stream; - * mark as referenced and stop selecting for input. - */ -static void -sq_query(sp) - register struct qstream *sp; -{ - sp->s_refcnt++; - FD_CLR(sp->s_rfd, &mask); -} - -/* - * Note that the current request on a stream has completed, - * and that we should continue looking for requests on the stream. - */ -void -sq_done(sp) - register struct qstream *sp; -{ - - sp->s_refcnt = 0; - sp->s_time = tt.tv_sec; - FD_SET(sp->s_rfd, &mask); -} - -void -ns_setproctitle(a, s) - char *a; - int s; -{ - int size; - register char *cp; - struct sockaddr_in sin; - char buf[80]; - - cp = Argv[0]; - size = sizeof(sin); - if (getpeername(s, (struct sockaddr *)&sin, &size) == 0) - (void) sprintf(buf, "-%s [%s]", a, inet_ntoa(sin.sin_addr)); - else { - syslog(LOG_DEBUG, "getpeername: %m"); - (void) sprintf(buf, "-%s", a); - } - (void) strncpy(cp, buf, LastArg - cp); - cp += strlen(cp); - while (cp < LastArg) - *cp++ = ' '; -} - -u_int32_t -net_mask(in) - struct in_addr in; -{ - register u_int32_t i = ntohl(in.s_addr); - - if (IN_CLASSA(i)) - return (htonl(IN_CLASSA_NET)); - else if (IN_CLASSB(i)) - return (htonl(IN_CLASSB_NET)); - else - return (htonl(IN_CLASSC_NET)); -} - -#if defined(BSD43_BSD43_NFS) -/* junk needed for old Sun NFS licensees */ -#undef dn_skipname -extern char *dn_skipname(); -char *(*hack_skipname)() = dn_skipname; -#endif diff --git a/usr.sbin/named/ns_maint.c b/usr.sbin/named/ns_maint.c deleted file mode 100644 index 927fde3fde58..000000000000 --- a/usr.sbin/named/ns_maint.c +++ /dev/null @@ -1,784 +0,0 @@ -#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 4.9.1.15 1994/06/11 22:04:46 vixie Exp $"; -#endif /* not lint */ - -/* - * ++Copyright++ 1986, 1988 - * - - * Copyright (c) 1986, 1988 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - - * Portions Copyright (c) 1993 by Digital Equipment Corporation. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies, and that - * the name of Digital Equipment Corporation not be used in advertising or - * publicity pertaining to distribution of the document or software without - * specific, written prior permission. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT - * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - * - - * --Copyright-- - */ - -#include <sys/param.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <arpa/nameser.h> -#include <sys/wait.h> -#include <stdio.h> -#include <syslog.h> -#include <signal.h> -#include <errno.h> -#include <sys/stat.h> - -#include "named.h" - -#ifdef USE_UTIME -# include <utime.h> -#endif - -static int xfers_running, /* # of xfers running */ - xfers_deferred, /* # of needed xfers not run yet */ - qserials_running, - alarm_pending, /* flag */ - nxfers __P((struct zoneinfo *, int)); - -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) - -#ifdef CLEANCACHE -static time_t cache_time; -#endif -/* - * Invoked at regular intervals by signal interrupt; refresh all secondary - * zones from primary name server and remove old cache entries. Also, - * ifdef'd ALLOW_UPDATES, dump database if it has changed since last - * dump/bootup. - */ -void -ns_maint() -{ - register struct zoneinfo *zp; - int zonenum; - - gettime(&tt); - - dprintf(1, (ddt, "\nns_maint(); now %s", ctime(&tt.tv_sec))); - - alarm_pending = 0; - for (zp = zones, zonenum = 0; zp < &zones[nzones]; zp++, zonenum++) { -#ifdef DEBUG - if (debug >= 2) - printzoneinfo(zonenum); -#endif - if (tt.tv_sec >= zp->z_time && zp->z_refresh > 0) { - switch (zp->z_type) { - - case Z_CACHE: - doachkpt(); - zp->z_time = tt.tv_sec + zp->z_refresh; - break; - - case Z_SECONDARY: -#ifdef STUBS - case Z_STUB: -#endif - if (zp->z_flags & - (Z_NEED_RELOAD|Z_NEED_XFER|Z_QSERIAL)) { - zp->z_time = tt.tv_sec + zp->z_refresh; - break; - } - if (zp->z_flags & Z_XFER_RUNNING) { - abortxfer(zp); - zp->z_time = tt.tv_sec + zp->z_retry; - break; - } - qserial_query(zp); - break; -#ifdef ALLOW_UPDATES - case Z_PRIMARY: - /* - * Checkpoint the zone if it has changed - * since we last checkpointed - */ - if (zp->z_flags & Z_CHANGED) { - zonedump(zp); - zp->z_time = tt.tv_sec + zp->z_refresh; - } - break; -#endif /* ALLOW_UPDATES */ - } - gettime(&tt); - } - } -#ifdef CLEANCACHE - remove_zone(hashtab, 0, 0); -#endif - if (!needmaint) - sched_maint(); - dprintf(1, (ddt, "exit ns_maint()\n")); -} - -/* - * Find when the next refresh needs to be and set - * interrupt time accordingly. - */ -void -sched_maint() -{ - register struct zoneinfo *zp; - struct itimerval ival; -#ifdef CLEANCACHE - time_t next_refresh = cache_time + 3600; -#else - time_t next_refresh = 0; -#endif - static time_t next_alarm; - - for (zp = zones; zp < &zones[nzones]; zp++) - if (zp->z_time != 0 && - (next_refresh == 0 || next_refresh > zp->z_time)) - next_refresh = zp->z_time; - /* - * Schedule the next call to ns_maint. - * Don't visit any sooner than maint_interval. - */ - bzero((char *)&ival, sizeof (ival)); - if (next_refresh != 0) { - if (next_refresh == next_alarm && alarm_pending) { - dprintf(1, (ddt, "sched_maint: no schedule change\n")); - return; - } - /* - * tv_sec can be an unsigned long, so we can't let - * it go negative. - */ - if (next_refresh < tt.tv_sec) - next_refresh = tt.tv_sec; - ival.it_value.tv_sec = next_refresh - tt.tv_sec; - if ((long) ival.it_value.tv_sec < maint_interval) - ival.it_value.tv_sec = maint_interval; - next_alarm = next_refresh; - 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)); -} - -/* - * Mark a zone "up to date" after named-xfer tells us this or we - * discover it through the qserial_*() logic. - */ -static void -markUpToDate(zp) - struct zoneinfo *zp; -{ - struct stat f_time; - - zp->z_flags &= ~Z_SYSLOGGED; - zp->z_lastupdate = tt.tv_sec; - zp->z_time = tt.tv_sec + zp->z_refresh; - /* - * Restore Z_AUTH in case expired, - * but only if there were no errors - * in the zone file. - */ - if ((zp->z_flags & Z_DB_BAD) == 0) - zp->z_flags |= Z_AUTH; - if (zp->z_source) { -#if defined(USE_UTIME) - struct utimbuf t; - - t.actime = tt.tv_sec; - t.modtime = tt.tv_sec; - (void) utime(zp->z_source, &t); -#else - struct timeval t[2]; - - t[0] = tt; - t[1] = tt; - (void) utimes(zp->z_source, t); -#endif /* USE_UTIME */ - } - /* we use "stat" to set zp->z_ftime instead of just - setting it to tt.tv_sec in order to avoid any - possible rounding problems in utimes(). */ - if (stat(zp->z_source, &f_time) != -1) - zp->z_ftime = f_time.st_mtime; - /* XXX log if stat fails? XXX */ -} - -/* - * Query for the serial number of a zone, so that - * we can check to see if we need to transfer it. - */ -static void -qserial_query(zp) - struct zoneinfo *zp; -{ - struct qinfo *qp; - - dprintf(1, (ddt, "qserial_query(%s)\n", zp->z_origin)); - - if (qserial_qfull()) - return; - - qp = sysquery(zp->z_origin, zp->z_class, T_SOA, - zp->z_addr, zp->z_addrcnt); - if (!qp) { - dprintf(1, (ddt, "qserial_query(%s) FAILED\n", 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; - qserials_running++; - dprintf(1, (ddt, "qserial_query(%s) QUEUED\n", zp->z_origin)); -} - -void -qserial_answer(qp, serial) - struct qinfo *qp; - u_int32_t serial; -{ - struct zoneinfo *zp = qp->q_zquery; - int was_qfull = qserial_qfull(); - - dprintf(1, (ddt, "qserial_answer(%s, %lu)\n", zp->z_origin, serial)); - zp->z_flags &= ~Z_QSERIAL; - qp->q_flags &= ~Q_ZSERIAL; /* keeps us from being called twice */ - qserials_running--; - if (serial == 0) { - /* an error occurred, or the query timed out. - */ -#ifdef GETSER_LOGGING - syslog(GETSER_LOGGING, "Err/TO getting serial# for \"%s\"", - zp->z_origin); -#endif /* GETSER_LOGGING */ - addxfer(zp); - } else if (SEQ_GT(serial, zp->z_serial) || !zp->z_serial) { - dprintf(1, (ddt, "qserial_answer: zone is out of date\n")); - zp->z_xaddr = from_addr.sin_addr; /* don't use qp->q_from */ - addxfer(zp); - } else if (SEQ_GT(zp->z_serial, serial)) { - if (!haveComplained((char*)zp, "went backward")) { - syslog(LOG_NOTICE, - "Zone \"%s\" (class %d) SOA serial# (%lu) rcvd from [%s] is < ours (%lu)\n", - zp->z_origin, zp->z_class, serial, - inet_ntoa(from_addr.sin_addr), - zp->z_serial); - } - } else { - dprintf(1, (ddt, "qserial_answer: zone serial is still OK\n")); - markUpToDate(zp); - } - done: - if (was_qfull) - needmaint = 1; -} - -/* - * Start an asynchronous zone transfer for a zone. - * Depends on current time being in tt. - * The caller must call sched_maint after startxfer. - */ -static void -startxfer(zp) - struct zoneinfo *zp; -{ - static char *argv[NSMAX + 20], argv_ns[NSMAX][MAXDNAME]; - int argc = 0, argc_ns = 0, pid, omask; - unsigned int cnt; - char debug_str[10]; - char serial_str[10]; - char port_str[10]; -#ifdef GEN_AXFR - char class_str[10]; -#endif - - dprintf(1, (ddt, "startxfer() %s\n", zp->z_origin)); - - argv[argc++] = "named-xfer"; - argv[argc++] = "-z"; - argv[argc++] = zp->z_origin; - argv[argc++] = "-f"; - argv[argc++] = zp->z_source; - argv[argc++] = "-s"; - sprintf(serial_str, "%lu", zp->z_serial); - argv[argc++] = serial_str; -#ifdef GEN_AXFR - argv[argc++] = "-C"; - sprintf(class_str, "%d", zp->z_class); - argv[argc++] = class_str; -#endif - if (zp->z_flags & Z_SYSLOGGED) - argv[argc++] = "-q"; - argv[argc++] = "-P"; - sprintf(port_str, "%d", ns_port); - argv[argc++] = port_str; -#ifdef STUBS - if (zp->z_type == Z_STUB) - argv[argc++] = "-S"; -#endif -#ifdef DEBUG - if (debug) { - argv[argc++] = "-d"; - sprintf(debug_str, "%d", debug); - argv[argc++] = debug_str; - argv[argc++] = "-l"; - argv[argc++] = _PATH_XFERDDT; - if (debug > 5) { - argv[argc++] = "-t"; - argv[argc++] = _PATH_XFERTRACE; - } - } -#endif - - if (zp->z_xaddr.s_addr != 0) { - /* address was specified by the qserial logic, use it */ - argv[argc++] = strcpy(argv_ns[argc_ns++], - inet_ntoa(zp->z_xaddr)); - } else { - /* - * Copy the server ip addresses into argv, after converting - * to ascii and saving the static inet_ntoa result - */ - for (cnt = 0; cnt < zp->z_addrcnt; cnt++) { - struct in_addr a; - - a = zp->z_addr[cnt]; - if (aIsUs(a) - && !haveComplained(zp->z_origin, - (char*)startxfer)) { - syslog(LOG_ERR, - "attempted to fetch zone %s from self (%s)", - zp->z_origin, inet_ntoa(a)); - continue; - } - argv[argc++] = strcpy(argv_ns[argc_ns++], - inet_ntoa(a)); - } - } - - argv[argc] = 0; - -#ifdef DEBUG -#ifdef ECHOARGS - if (debug) { - int i; - for (i = 0; i < argc; i++) - fprintf(ddt, "Arg %d=%s\n", i, argv[i]); - } -#endif /* ECHOARGS */ -#endif /* DEBUG */ - -#ifdef SYSV -#define vfork fork -#else - gettime(&tt); - omask = sigblock(sigmask(SIGCHLD)); -#endif - if ((pid = vfork()) == -1) { - syslog(LOG_ERR, "xfer vfork: %m"); -#ifndef SYSV - (void) sigsetmask(omask); -#endif - zp->z_time = tt.tv_sec + 10; - return; - } - - if (pid == 0) { - /* child */ - execv(_PATH_XFER, argv); - syslog(LOG_ERR, "can't exec %s: %m", _PATH_XFER); - _exit(XFER_FAIL); /* avoid duplicate buffer flushes */ - } - /* parent */ - dprintf(1, (ddt, "started xfer child %d\n", pid)); - zp->z_flags &= ~Z_NEED_XFER; - zp->z_flags |= Z_XFER_RUNNING; - zp->z_xferpid = pid; - xfers_running++; - zp->z_time = tt.tv_sec + MAX_XFER_TIME; -#ifndef SYSV - (void) sigsetmask(omask); -#endif -} - -#ifdef DEBUG -void -printzoneinfo(zonenum) -int zonenum; -{ - struct timeval tt; - struct zoneinfo *zp = &zones[zonenum]; - char *ZoneType; - - if (!debug) - return; - - 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 - fprintf(ddt, "origin ='%s'", zp->z_origin); -#ifdef GEN_AXFR - fprintf(ddt, ", class = %d", zp->z_class); -#endif - fprintf(ddt, ", type = %s", ZoneType); - 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); - 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, "; flags %x\n", zp->z_flags); -} -#endif /* DEBUG */ - -/* - * remove_zone (htp, zone) -- - * Delete all RR's in the zone "zone" under specified hash table. - */ -void -#ifdef CLEANCACHE -remove_zone(htp, zone, all) -#else -remove_zone(htp, zone) -#endif - register struct hashbuf *htp; - register int zone; -#ifdef CLEANCACHE - register int all; -#endif -{ - 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) { - for (pdp = NULL, dp = np->n_data; dp != NULL; ) { -#ifdef CLEANCACHE - if (dp->d_zone == zone && (all || stale(dp))) -#else - if (dp->d_zone == zone) -#endif - dp = rm_datum(dp, np, pdp); - else { - pdp = dp; - dp = dp->d_next; - } - } - - if (np->n_hash) { - /* call recursively to remove subdomains. */ -#ifdef CLEANCACHE - remove_zone(np->n_hash, zone, all); -#else - remove_zone(np->n_hash, zone); -#endif - - /* 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; - } - } -} - -/* - * Handle XFER limit for a nameserver. - */ -static int -nxfers(zp, delta) - struct zoneinfo *zp; - int delta; -{ - struct in_addr nsa; - struct nameser *nsp; - int ret; - - if (zp->z_xaddr.s_addr) - nsa = zp->z_xaddr; /* qserial overrode address */ - else if (!zp->z_addrcnt) - return (-1); - else - nsa = zp->z_addr[0]; /* first ns holds zone's xfer limit */ - - if (!(nsp = nameserFind(nsa, NS_F_INSERT))) - return (-1); /* probably ENOMEM */ - - ret = nsp->xfers; - if (delta < 0 && -delta > ret) - return (-1); /* taking more than we have */ - - nsp->xfers += delta; - return (ret); -} - -/* - * Abort an xfer that has taken too long. - */ -static void -abortxfer(zp) - struct zoneinfo *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; - (void) nxfers(zp, -1); - xfers_running--; -} - -/* - * SIGCHLD signal handler: process exit of xfer's. - * (Note: also called when outgoing transfer completes.) - */ -SIG_FN -endxfer() -{ - register struct zoneinfo *zp; - int exitstatus, pid, xfers, save_errno; -#if defined(sequent) - union wait status; -#else - int status; -#endif /* sequent */ - - save_errno = errno; - xfers = 0; - gettime(&tt); -#if defined(USE_WAITPID) - while ((pid = waitpid(-1, &status, WNOHANG)) > 0) { -#else /* USE_WAITPID */ - { - pid = wait(&status); -#endif /* USE_WAITPID */ - exitstatus = WIFEXITED(status) ?WEXITSTATUS(status) :0; - - for (zp = zones; zp < &zones[nzones]; zp++) { - if (zp->z_xferpid != pid) - continue; - xfers++; - xfers_running--; - (void) nxfers(zp, -1); - zp->z_xferpid = 0; - zp->z_flags &= ~Z_XFER_RUNNING; - dprintf(1, (ddt, - "\nendxfer: child %d zone %s returned status=%d termsig=%d\n", - pid, zp->z_origin, exitstatus, - WIFSIGNALED(status) ?WTERMSIG(status) :-1 - ) - ); - if (WIFSIGNALED(status)) { - if (WTERMSIG(status) != SIGKILL) { - syslog(LOG_NOTICE, - "named-xfer exited with signal %d\n", - WTERMSIG(status)); - } - zp->z_time = tt.tv_sec + zp->z_retry; - } else { - switch (exitstatus) { - case XFER_UPTODATE: - markUpToDate(zp); - break; - - case XFER_SUCCESS: - zp->z_flags |= Z_NEED_RELOAD; - zp->z_flags &= ~Z_SYSLOGGED; - needzoneload++; - 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", - zp->z_origin); - } - zp->z_time = tt.tv_sec + zp->z_retry; - break; - - default: - if (!(zp->z_flags & Z_SYSLOGGED)) { - zp->z_flags |= Z_SYSLOGGED; - syslog(LOG_NOTICE, - "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; - break; - } /*switch*/ - break; - } /*if/else*/ - } /*for*/ - } /*while*/ - tryxfer(); -#if defined(SYSV) - (void)signal(SIGCLD, endxfer); -#endif - errno = save_errno; -} - -/* - * Try to start some xfers - */ -static void -tryxfer() { - struct zoneinfo *zp; - - for (zp = zones; zp < &zones[nzones]; zp++) { - int xfers; - - if (!xfers_deferred || xfers_running >= max_xfers_running) - break; - - if ((xfers = nxfers(zp, 0)) != -1 && - xfers < MAX_XFERS_PERNS && - (zp->z_flags & Z_NEED_XFER)) { - nxfers(zp, 1); - xfers_deferred--; - startxfer(zp); - } - } - if (!needmaint) - sched_maint(); -} - -/* - * Reload zones whose transfers have completed. - */ -void -loadxfer() -{ - register struct zoneinfo *zp; - - gettime(&tt); - for (zp = zones; zp < &zones[nzones]; zp++) { - if (zp->z_flags & Z_NEED_RELOAD) { - dprintf(1, (ddt, "loadxfer() \"%s\"\n", - zp->z_origin[0] ? zp->z_origin : ".")); - zp->z_flags &= ~(Z_NEED_RELOAD|Z_AUTH); -#ifdef CLEANCACHE - remove_zone(hashtab, zp - zones, 1); -#else - remove_zone(hashtab, zp - zones); -#endif - if (db_load(zp->z_source, zp->z_origin, zp, 0) == 0) - 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) - sched_maint(); -} - -/* - * Add this zone to the set of those needing transfers. - */ -static void -addxfer(zp) - struct zoneinfo *zp; -{ - if (!(zp->z_flags & Z_NEED_XFER)) { - zp->z_flags |= Z_NEED_XFER; - xfers_deferred++; - tryxfer(); - } -} diff --git a/usr.sbin/named/ns_ncache.c b/usr.sbin/named/ns_ncache.c deleted file mode 100644 index 54083428f979..000000000000 --- a/usr.sbin/named/ns_ncache.c +++ /dev/null @@ -1,152 +0,0 @@ -/************************************************************************** - * ns_ncache.c - * author: anant kumar - * last modification: March 17, 1993 - * - * implements negative caching - */ - -#include <sys/param.h> -#include <sys/socket.h> -#include <sys/file.h> -#include <netinet/in.h> -#include <arpa/nameser.h> -#include <syslog.h> -#include <errno.h> -#include <stdio.h> -#include <resolv.h> - -#include "named.h" - -#ifdef NCACHE - -void -cache_n_resp(msg, msglen) - u_char *msg; - int msglen; -{ - register struct databuf *dp; - HEADER *hp; - u_char *cp; - char dname[MAXDNAME]; - int n; - int type, class; - int Vcode; - int flags; - - nameserIncr(from_addr.sin_addr, nssRcvdNXD); - - hp = (HEADER *)msg; - cp = msg+HFIXEDSZ; - - n = dn_expand(msg, msg + msglen, cp, dname, sizeof dname); - if (n < 0) { - dprintf(1, (ddt, "Query expand name failed:cache_n_resp\n")); - hp->rcode = FORMERR; - return; - } - cp += n; - GETSHORT(type, cp); - GETSHORT(class, cp); - dprintf(1, (ddt, - "ncache: dname %s, type %d, class %d\n", - dname, type, class)); - -#ifdef VALIDATE - Vcode = validate(dname, &from_addr, type, class, NULL, 0, - hp->rcode == NXDOMAIN ? NXDOMAIN : NOERROR_NODATA); - if (Vcode == INVALID || Vcode == VALID_NO_CACHE) { - /*Valid_no_cache should never occur but doesn't hurt to check*/ - return; - } -#endif -#ifdef RETURNSOA - if (hp->rcode==NXDOMAIN) { - u_int32_t ttl; - u_int16_t atype; - u_char * tp = cp; - u_char * cp1; - u_char data[BUFSIZ+MAXDNAME]; - int len = sizeof(data); - - /* store ther SOA record */ - if (!hp->nscount) { - dprintf(3, (ddt, "ncache: nscount == 0\n")); - return; - } - n = dn_skipname(tp, msg + msglen); - if (n < 0) { - dprintf(3, (ddt, "ncache: form error\n")); - return; - } - tp += n; - GETSHORT(atype,tp); /* type */ - if (atype != T_SOA) { - dprintf(3, (ddt, "ncache: type (%d) != T_SOA\n",atype)); - return; - } - tp += sizeof(u_int16_t); /* class */ - GETLONG(ttl,tp); /* ttl */ - tp += sizeof(u_int16_t); /* dlen */ - - if ((n = dn_expand(msg, msg + msglen, tp, data, len)) - < 0 ) { - dprintf(3, (ddt, "ncache: form error 2\n")); - return; - } /* origin */ - tp += n; - cp1 = data + (n = strlen(data) + 1); - len -= n; - if ((n = dn_expand(msg, msg + msglen, tp, cp1, len)) < 0 ) { - dprintf(3, (ddt, "ncache: form error 2\n")); - return; - } /* mail */ - tp += n; - n = strlen(cp1) + 1; - cp1 += n; - len -= n; - bcopy(tp, cp1, n = 5 * sizeof(u_int32_t)); - /* serial, refresh, retry, expire, min */ - cp1 += n; - len -= n; - /* store the zone of the soa record */ - if ((n = dn_expand(msg, msg + msglen, cp, cp1, len)) < 0 ) { - dprintf(3, (ddt, "ncache: form error 2\n")); - return; - } - n = strlen(cp1) + 1; - cp1 += n; - - dp = savedata(class, T_SOA, MIN(ttl,NTTL)+tt.tv_sec, data, - cp1 - data); - } else { -#endif - dp = savedata(class, type, NTTL+tt.tv_sec, NULL, 0); -#ifdef RETURNSOA - } -#endif - dp->d_zone = DB_Z_CACHE; - dp->d_cred = hp->aa ? DB_C_AUTH : DB_C_ANSWER; - dp->d_clev = 0; - if(hp->rcode == NXDOMAIN) { - dp->d_rcode = NXDOMAIN; - flags = DB_NODATA|DB_NOTAUTH|DB_NOHINTS; - } else { - dp->d_rcode = NOERROR_NODATA; - flags = DB_NOTAUTH|DB_NOHINTS; - } - - if ((n = db_update(dname,dp,dp,flags,hashtab)) != OK) { - dprintf(1, (ddt, - "db_update failed return value:%d, cache_n_resp()\n", - n)); - free((char *)dp); - 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)); - return; -} - -#endif /*NCACHE*/ diff --git a/usr.sbin/named/ns_req.c b/usr.sbin/named/ns_req.c deleted file mode 100644 index afc3fc5af271..000000000000 --- a/usr.sbin/named/ns_req.c +++ /dev/null @@ -1,1793 +0,0 @@ -#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 4.9.1.22 1994/07/23 23:23:56 vixie Exp $"; -#endif /* not lint */ - -/* - * ++Copyright++ 1986, 1988, 1990 - * - - * Copyright (c) 1986, 1988, 1990 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - - * Portions Copyright (c) 1993 by Digital Equipment Corporation. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies, and that - * the name of Digital Equipment Corporation not be used in advertising or - * publicity pertaining to distribution of the document or software without - * specific, written prior permission. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT - * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - * - - * --Copyright-- - */ - -#include <sys/param.h> -#include <sys/uio.h> -#include <sys/file.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/nameser.h> -#include <arpa/inet.h> -#include <fcntl.h> -#include <syslog.h> -#include <errno.h> -#include <stdio.h> -#include <resolv.h> - -#include "named.h" - -struct addinfo { - char *a_dname; /* domain name */ - u_int a_class; /* class for address */ -}; - -enum req_action { Finish, Refuse, Return }; - -static enum req_action req_query __P((HEADER *hp, u_char **cpp, u_char *eom, - struct qstream *qsp, - int *buflenp, int *msglenp, - 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)); -#endif - -static void fwritemsg __P((FILE *, u_char *, int)), - doaxfr __P((struct namebuf *, FILE *, - struct namebuf *, int)), - startxfr __P((struct qstream *, struct namebuf *, - u_char *, int, int, const char *)), - printSOAdata __P((struct databuf)); - -#ifdef ALLOW_UPDATES -static int InitDynUpdate __P((register HEADER *hp, - char *msg, - int msglen, - u_char *startcp, - struct sockaddr_in *from, - struct qstream *qsp, - int dfd)); -#endif - -static struct addinfo addinfo[NADDRECS]; -static void addname __P((char *, u_int16_t)); - -/* - * Process request using database; assemble and send response. - */ -void -ns_req(msg, msglen, buflen, qsp, from, dfd) - u_char *msg; - int msglen, buflen; - struct qstream *qsp; - struct sockaddr_in *from; - int dfd; -{ - register HEADER *hp = (HEADER *) msg; - u_char *cp, *eom; - enum req_action action; - -#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); - } -#endif - - /* - * XXX - this decision should be made by our caller, not by us. - */ - if (hp->qr) { - ns_resp(msg, msglen); - - /* Now is a safe time for housekeeping */ - if (needs_prime_cache) - prime_cache(); - - return; - } - - /* its a query and 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 - */ - hp->aa = hp->ra = 0; - - hp->rcode = NOERROR; - cp = msg + HFIXEDSZ; - eom = msg + msglen; - - dnptrs[0] = msg; - dnptrs[1] = NULL; - - free_addinfo(); /* sets addcount to zero */ - dnptrs[0] = NULL; - - switch (hp->opcode) { - case QUERY: - action = req_query(hp, &cp, eom, qsp, - &buflen, &msglen, - msg, dfd, from); - break; - -#ifdef INVQ - case IQUERY: - action = req_iquery(hp, &cp, eom, &buflen, msg, from); - break; -#endif - -#ifdef ALLOW_UPDATES -#define FORWARDED 1000 -/* - * In a sense the following constant should be defined in <arpa/nameser.h>, - * since it is returned here in place of a response code if the update was - * forwarded, and the response codes are defined in nameser.h. On the other - * hand, though, this constant is only seen in this file. The assumption - * 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) { - /* Return directly because InitDynUpdate - * forwarded the query to the primary, so we - * will send response later - */ - action = Return; - } else { - /* Either sucessful primary update or failure; - * return response code to client - */ - action = Finish; - } -#endif /* ALLOW_UPDATES */ - - case ZONEREF: - dprintf(1, (ddt, "Refresh Zone\n")); - /*FALLTHROUGH*/ - - default: - dprintf(1, (ddt, "ns_req: Opcode %d not implemented\n", - hp->opcode)); - /* XXX - should syslog, limited by haveComplained */ - hp->qdcount = 0; - hp->ancount = 0; - hp->nscount = 0; - hp->arcount = 0; - hp->rcode = NOTIMP; - action = Finish; - } - - /* - * vector via internal opcode. (yes, it was even uglier before.) - */ - switch (action) { - case Return: - return; - case Refuse: - hp->rcode = REFUSED; - /*FALLTHROUGH*/ - case Finish: - /* 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 */ - } - - /* - * 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->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), - (qsp == QSTREAM_NULL) ?dfd :qsp->s_rfd, - ntohs(hp->id), local(from) == NULL ? "Remote" : "Local")); -#ifdef DEBUG - if (debug >= 10) - fp_query(msg, ddt); -#endif - if (qsp == QSTREAM_NULL) { - if (sendto(dfd, 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)); - nameserIncr(from->sin_addr, nssSendtoErr); - } - nameserIncr(from->sin_addr, nssSentAns); - } else { - (void) writemsg(qsp->s_rfd, msg, cp - msg); - sq_done(qsp); - } - - if (needs_prime_cache) { - prime_cache(); /* Now is a safe time */ - } -} - -static enum req_action -req_query(hp, cpp, eom, qsp, buflenp, msglenp, msg, dfd, from) - HEADER *hp; - u_char **cpp; - u_char *eom; - struct qstream *qsp; - u_char *msg; - int *buflenp, *msglenp, dfd; - struct sockaddr_in *from; -{ - int n, class, type, count, foundname, founddata, omsglen, cname; - u_int16_t id; - u_char **dpp, *omsg, *answers; - char dnbuf[MAXDNAME], *dname, *fname; - struct hashbuf *htp; - struct databuf *nsp[NSMAX]; - struct namebuf *np; - struct qinfo *qp; - struct netinfo *lp; - - nameserIncr(from->sin_addr, nssRcvdQ); -#ifdef DATUMREFCNT - nsp[0] = NULL; -#endif - - dpp = dnptrs; - *dpp++ = msg; - *dpp = NULL; - - /* valid queries have one question and zero answers */ - if ((ntohs(hp->qdcount) != 1) - || hp->ancount - || hp->nscount - || hp->arcount) { - dprintf(1, (ddt, "FORMERR Query header counts wrong\n")); - hp->qdcount = 0; - hp->ancount = 0; - hp->nscount = 0; - hp->arcount = 0; - hp->rcode = FORMERR; - return (Finish); - } - - /* - * Get domain name, class, and type. - */ - if ((**cpp & INDIR_MASK) == 0) { - *dpp++ = *cpp; /* remember name for compression */ - } - *dpp = NULL; - 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); - if (*cpp > eom) { - dprintf(1, (ddt, "FORMERR Query message length short\n")); - hp->rcode = FORMERR; - return (Finish); - } - if (*cpp < eom) { - dprintf(6, (ddt,"message length > received message\n")); - *msglenp = *cpp - msg; - } - - qtypeIncr(type); - - /* - * Process query. - */ - if (type == T_AXFR) { - /* 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 : "."); - return (Refuse); - } - /* the position of this is subtle. */ - nameserIncr(from->sin_addr, nssRcvdAXFR); -#ifdef XFRNETS - if (xfrnets) { - /* if xfrnets was specified, peer address - * must be on it. should probably allow - * for negation some day. - */ - 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 : "."); - 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 : "."); - } - *buflenp -= *msglenp; - count = 0; - foundname = 0; - founddata = 0; - dname = dnbuf; - cname = 0; - -#ifdef QRYLOG - if (qrylog) { - syslog(LOG_INFO, "XX /%s/%s/%s", - inet_ntoa(from->sin_addr), - (dname[0] == '\0') ?"." :dname, - p_type(type)); - } -#endif /*QRYLOG*/ - -try_again: - dprintf(1, (ddt, "req: nlookup(%s) id %d type=%d\n", - dname, hp->id, type)); - htp = hashtab; /* lookup relative to root */ - if ((np = nlookup(dname, &htp, &fname, 0)) == NULL) - fname = ""; - dprintf(1, (ddt, "req: %s '%s' as '%s' (cname=%d)\n", - np == NULL ? "missed" : "found", - dname, fname, cname)); - -#ifdef LOCALDOM - /* - * if nlookup failed to find the name then - * see if there are any '.''s in the name - * if not then add local domain name to the - * name and try again. - */ - if (!np && localdomain && !strchr(dname, '.')) { - (void) strcat(dname, "."); - (void) strcat(dname, localdomain); - dprintf(1, (ddt,"req: nlookup(%s) type=%d\n", dname, type)); - htp = hashtab; - np = nlookup(dname, &htp, &fname, 0); - } -#endif /*LOCALDOM*/ - -#ifdef YPKLUDGE - /* Some braindamaged resolver software will not - recognize internet addresses in dot notation and - send out address queries for "names" such as - 128.93.8.1. This kludge will prevent those - from flooding higher level servers. - We simply claim to be authoritative and that - the domain doesn't exist. - Note that we could return the address but we - don't do that in order to encourage that broken - software is fixed. - */ - - if (!np && type == T_A && class == C_IN && dname) { - struct in_addr ina; - - if (inet_aton(dname, &ina)) { - hp->rcode = NXDOMAIN; - hp->aa = 1; - dprintf(3, (ddt, "ypkludge: hit as '%s'\n", dname)); - return (Finish); - } - } -#endif /*YPKLUDGE*/ - - if ((!np) || (fname != dname)) - goto fetchns; - -#ifdef SECURE_ZONES - if (np->n_data) { - struct zoneinfo *zp; - - zp = &zones[np->n_data->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)); - return (Refuse); - } - } -#endif - foundname++; - answers = *cpp; - 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 - */ - if (np->n_data != NULL && !stale(np->n_data)) { - if (np->n_data->d_rcode == NXDOMAIN) { -#ifdef RETURNSOA - 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->rcode = NXDOMAIN; - hp->nscount = htons((u_int16_t)count); - hp->aa = 1; - return (Finish); - } - else - goto fetchns; -#else - hp->rcode = NXDOMAIN; - hp->aa = 1; - return (Finish); -#endif - } - } - - /* if not NXDOMAIN, the NOERROR_NODATA record might be - * anywhere in the chain. have to go through the grind. - */ -#endif /*NCACHE*/ - - n = finddata(np, class, type, hp, &dname, buflenp, &count); - if (n == 0) { - /* NO data available. Refuse AXFR requests, or - * look for better servers for other requests. - */ - if (type == T_AXFR) { - dprintf(1, (ddt, "T_AXFR refused: no data\n")); - return (Refuse); - } else { - goto fetchns; - } - } - -#ifdef NCACHE - if (hp->rcode == NOERROR_NODATA) { - hp->rcode = NOERROR; - founddata = 1; - return (Finish); - } -#endif - - *cpp += n; - *buflenp -= n; - *msglenp += n; - hp->ancount += count; - if (fname != dname && type != T_CNAME && type != T_ANY) { - if (cname++ >= MAXCNAMES) { - dprintf(3, (ddt, - "resp: leaving, MAXCNAMES exceeded\n")); - hp->rcode = SERVFAIL; - return (Finish); - } - goto try_again; - } - founddata = 1; - dprintf(3, (ddt, - "req: foundname=%d, count=%d, founddata=%d, cname=%d\n", - foundname, count, founddata, cname)); - - if ((lp = local(from)) != NULL) - sort_response(answers, count, lp, *cpp); - if (type == T_AXFR) { - hp->ancount = htons(hp->ancount); - startxfr(qsp, np, msg, *cpp - msg, class, dname); - sqrm(qsp); - return (Return); - } - -#ifdef notdef - /* - * If we found an authoritative answer, - * we're done. - */ - if (hp->aa) - return (Finish); -#endif - -fetchns: - /* - * Look for name servers to refer to and fill in the authority - * section or record the address for forwarding the query - * (recursion desired). - */ -#ifdef DATUMREFCNT - free_nsp(nsp); -#endif - nsp[0] = NULL; - count = 0; - switch (findns(&np, class, nsp, &count, 0)) { - case NXDOMAIN: - if (!foundname) { - hp->rcode = NXDOMAIN; - } - dprintf(3, (ddt, "req: leaving (%s, rcode %d)\n", - dname, hp->rcode)); - if (class != C_ANY) { - hp->aa = 1; - /* XXX: should return SOA if founddata == 0, - * but old named's are confused by an SOA - * in the auth. section if there's no error. - */ - if (foundname == 0 && np) { - n = doaddauth(hp, *cpp, *buflenp, np, nsp[0]); - *cpp += n; - *buflenp -= n; -#ifdef ADDAUTH - } else if (hp->ancount) { - /* don't add NS records for NOERROR NODATA - as some severs can get confused */ -#ifdef DATUMREFCNT - free_nsp(nsp); -#endif - switch (findns(&np, class, nsp, &count, 1)) { - case NXDOMAIN: - case SERVFAIL: - break; - default: - if (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); - } - } -#endif /*ADDAUTH*/ - } - } -#ifdef DATUMREFCNT - free_nsp(nsp); -#endif - return (Finish); - - case SERVFAIL: - if (!founddata && !(forward_only && fwdtab)) { - hp->rcode = SERVFAIL; -#ifdef DATUMREFCNT - free_nsp(nsp); -#endif - return (Finish); - } - } - - /* - * If we successfully found the answer in the cache, - * or this is not a recursive query, or we are purposely - * never recursing, then add the nameserver references - * ("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); - } - *cpp += n; - *buflenp -= n; - hp->nscount = htons((u_int16_t)count); -#ifdef DATUMREFCNT - free_nsp(nsp); -#endif - return (Finish); - } - - /* - * At this point, we don't have the answer, but we do - * have some NS's to try. If the user would like us - * to recurse, create the initial query. If a cname - * is involved, we need to build a new query and save - * the old one in cmsg/cmsglen. - */ - 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"); - hp->rcode = SERVFAIL; -#ifdef DATUMREFCNT - free_nsp(nsp); -#endif - return (Finish); - } - id = hp->id; - 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 = ns_forw(nsp, msg, *msglenp, from, qsp, dfd, &qp, dname, np); - if (n != FW_OK && cname) - free(omsg); - switch (n) { - case FW_OK: - if (cname) { - qp->q_cname = cname; - qp->q_cmsg = omsg; - qp->q_cmsglen = omsglen; - qp->q_id = id; - } - break; - case FW_DUP: - break; /* Duplicate request dropped */ - case FW_NOSERVER: - /* - ** Don't go into an infinite loop if - ** the admin gave root NS records in the cache - ** file without giving address records - ** for the root servers. - */ - if (np) { - if (np->n_dname[0] == '\0') { - dprintf(1, (ddt, - "ns_req: no address for root NS\n" - )); - syslog(LOG_ERR, - "ns_req: no address for root server"); - hp->rcode = SERVFAIL; -#ifdef DATUMREFCNT - free_nsp(nsp); -#endif - return (Finish); - } -#ifdef VALIDATE - /* - * we need to kill all the NS records here as - * validate will fail as we are talking to the parent - * server - */ - delete_all(np, class, T_NS); -#endif - np = np->n_parent; - } - goto fetchns; /* Try again. */ - case FW_SERVFAIL: - hp->rcode = SERVFAIL; -#ifdef DATUMREFCNT - free_nsp(nsp); -#endif - return (Finish); - } -#ifdef DATUMREFCNT - free_nsp(nsp); -#endif - return (Return); -} - -#ifdef INVQ -static enum req_action -req_iquery(hp, cpp, eom, buflenp, msg, from) - HEADER *hp; - u_char **cpp, *eom; - int *buflenp; - u_char *msg; - struct sockaddr_in *from; -{ - register struct invbuf *ip; - int dlen, alen, i, 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); - - hp->ancount = htons(hp->ancount); - if ((hp->ancount != 1) - || hp->qdcount - || hp->nscount - || hp->arcount) { - dprintf(1, (ddt, "FORMERR IQuery header counts wrong\n")); - hp->qdcount = 0; - hp->ancount = 0; - hp->nscount = 0; - hp->arcount = 0; - hp->rcode = FORMERR; - return (Finish); - } - - /* - * Skip domain name, get class, and type. - */ - if ((n = dn_skipname(*cpp, eom)) < 0) { - dprintf(1, (ddt, "FORMERR IQuery packet name problem\n")); - hp->rcode = FORMERR; - return (Finish); - } - *cpp += n; - GETSHORT(type, *cpp); - GETSHORT(class, *cpp); - *cpp += INT32SZ; /* ttl */ - GETSHORT(dlen, *cpp); - *cpp += dlen; - if (*cpp != eom) { - dprintf(1, (ddt, "FORMERR IQuery message length off\n")); - hp->rcode = FORMERR; - return (Finish); - } - - /* - * not all inverse queries are handled. - */ - switch (type) { - case T_A: - case T_UID: - case T_GID: - break; - default: - return (Refuse); - } - dprintf(1, (ddt, "req: IQuery class %d type %d\n", class, type)); - - fname = (char *)msg + HFIXEDSZ; - bcopy(fname, anbuf, alen = (char *)*cpp - fname); - data = anbuf + alen - dlen; - *cpp = (u_char *)fname; - *buflenp -= HFIXEDSZ; - count = 0; - for (ip = invtab[dhash((u_char *)data, dlen)]; - ip != NULL; - ip = ip->i_next) { - for (i = 0; i < INVBLKSZ; i++) { - if ((np = ip->i_dname[i]) == NULL) - break; - dprintf(5, (ddt, "dname = %d\n", np->n_dname)); - for (dp = np->n_data; dp != NULL; dp = dp->d_next) { - if (!match(dp, class, type)) - continue; - if (dp->d_size != dlen || - bcmp(dp->d_data, data, dlen)) - continue; - getname(np, dnbuf, sizeof(dnbuf)); - dprintf(2, (ddt, "req: IQuery found %s\n", - dnbuf)); - *buflenp -= QFIXEDSZ; - n = dn_comp(dnbuf, *cpp, *buflenp, NULL, NULL); - if (n < 0) { - hp->tc = 1; - return (Finish); - } - *cpp += n; - PUTSHORT((u_int16_t)dp->d_type, *cpp); - PUTSHORT((u_int16_t)dp->d_class, *cpp); - *buflenp -= n; - count++; - } - } - } - dprintf(1, (ddt, "req: IQuery %d records\n", count)); - hp->qdcount = htons((u_int16_t)count); - if (alen > *buflenp) { - hp->tc = 1; - return (Finish); - } - bcopy(anbuf, *cpp, alen); - *cpp += alen; - return (Finish); -} -#endif - -static void -fwritemsg(rfp, msg, msglen) - FILE *rfp; - u_char *msg; - int msglen; -{ - u_char len[INT16SZ]; - - __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)); - } -} - -/* - * Test a datum for validity and return non-zero if it is out of date. - */ -int -stale(dp) - register struct databuf *dp; -{ - register struct zoneinfo *zp = &zones[dp->d_zone]; - - switch (zp->z_type) { - - case Z_PRIMARY: - return (0); - - case Z_SECONDARY: -#ifdef STUBS - case Z_STUB: -#endif - /* - * Check to see whether a secondary zone - * has expired; if so clear authority flag - * for zone and return true. If lastupdate - * is in the future, assume zone is up-to-date. - */ - if ((int32_t)(tt.tv_sec - zp->z_lastupdate) - > (int32_t)zp->z_expire) { - dprintf(1, (ddt, - "stale: secondary zone %s expired\n", - zp->z_origin)); - if (!haveComplained(zp->z_origin, (char*)stale)) { - syslog(LOG_ERR, - "secondary zone \"%s\" expired", - 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)); - return (1); - - default: - /* FALLTHROUGH */ ; - - } - abort(); - /* NOTREACHED */ -} - -/* - * Copy databuf into a resource record for replies. - * Return size of RR if OK, -1 if buffer is full. - */ -int -make_rr(name, dp, buf, buflen, doadd) - char *name; - register struct databuf *dp; - u_char *buf; - int buflen, doadd; -{ - register u_char *cp; - u_char *cp1, *sp; - struct zoneinfo *zp; - register int32_t n; - 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, - buflen, doadd, dp->d_size, dp->d_zone, dp->d_ttl)); - -#ifdef NCACHE - if (dp->d_rcode -#ifdef RETURNSOA - && 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 */ - } -#endif - zp = &zones[dp->d_zone]; - /* 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 */ - ttl = 0; - } - } else { - if (dp->d_ttl) - ttl = dp->d_ttl; - else - ttl = zp->z_minimum; /* really default */ -#ifdef notdef /* don't decrease ttl based on time since verification */ - if (zp->z_type == Z_SECONDARY) { - /* - * Set ttl to value received from primary, - * less time since we verified it (but never - * less than a small positive value). - */ - ttl -= tt.tv_sec - zp->z_lastupdate; - if (ttl <= 0) - ttl = 120; - } -#endif - } - - buflen -= RRFIXEDSZ; -#if defined(RETURNSOA) && defined(NCACHE) - if (dp->d_rcode == NXDOMAIN) { - name = (char *)dp->d_data; - name += strlen(name) +1; - name += strlen(name) +1; - name += 5 * INT32SZ; - } -#endif - if ((n = dn_comp(name, buf, buflen, dnptrs, edp)) < 0) - return (-1); - cp = buf + n; - buflen -= n; - PUTSHORT((u_int16_t)dp->d_type, cp); - PUTSHORT((u_int16_t)dp->d_class, cp); - PUTLONG(ttl, cp); - sp = cp; - cp += INT16SZ; - switch (dp->d_type) { - case T_CNAME: - case T_MG: - case T_MR: - case T_PTR: - n = dn_comp((char *)dp->d_data, cp, buflen, dnptrs, edp); - if (n < 0) - return (-1); - PUTSHORT((u_int16_t)n, sp); - cp += n; - break; - - case T_MB: - case T_NS: - /* Store domain name in answer */ - n = dn_comp((char *)dp->d_data, cp, buflen, dnptrs, edp); - if (n < 0) - return (-1); - PUTSHORT((u_int16_t)n, sp); - cp += n; - if (doadd) - addname((char*)dp->d_data, dp->d_class); - break; - - case T_SOA: - case T_MINFO: - case T_RP: - cp1 = dp->d_data; - n = dn_comp((char *)cp1, cp, buflen, dnptrs, edp); - if (n < 0) - return (-1); - cp += n; - buflen -= dp->d_type == T_SOA ? n + 5 * INT32SZ : n; - cp1 += strlen((char *)cp1) + 1; - n = dn_comp((char *)cp1, cp, buflen, dnptrs, edp); - if (n < 0) - return (-1); - cp += n; - if (dp->d_type == T_SOA) { - cp1 += strlen((char *)cp1) + 1; - bcopy(cp1, cp, (n = 5 * INT32SZ)); - cp += n; - } - n = (u_int16_t)((cp - sp) - INT16SZ); - PUTSHORT((u_int16_t)n, sp); - break; - - case T_MX: - case T_AFSDB: - case T_RT: - /* cp1 == our data/ cp == data of RR */ - cp1 = dp->d_data; - - /* 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; - - /* save data length */ - n = (u_int16_t)((cp - sp) - INT16SZ); - PUTSHORT((u_int16_t)n, sp); - if (doadd) - addname((char*)cp1, dp->d_class); - break; - - default: - if (dp->d_size > buflen) - return (-1); - bcopy(dp->d_data, cp, dp->d_size); - PUTSHORT((u_int16_t)dp->d_size, sp); - cp += dp->d_size; - } - return (cp - buf); -} - -#if defined(__STDC__) || defined(__GNUC__) -static void -addname(register char *name, - u_int16_t class) -#else -static void -addname(name, class) - register char *name; - 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) - 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_class = class; - } -} - -/* - * Lookup addresses for names in addinfo and put into the message's - * additional section. - */ -int -doaddinfo(hp, msg, msglen) - HEADER *hp; - u_char *msg; - int msglen; -{ - register struct namebuf *np; - register struct databuf *dp; - register struct addinfo *ap; - register u_char *cp; - struct hashbuf *htp; - char *fname; - int n, count; - - dprintf(3, (ddt, "doaddinfo() addcount = %d\n", addcount)); - - if (hp->tc) { - dprintf(4, (ddt, "doaddinfo(): tc already set, bailing\n")); - return (0); - } - - count = 0; - cp = msg; - for (ap = addinfo; --addcount >= 0; ap++) { - int foundstale = 0, - foundany = 0, - save_count = count, - save_msglen = msglen; - u_char *save_cp = cp; - - dprintf(3, (ddt, "do additional '%s'\n", ap->a_dname)); - htp = hashtab; /* because "nlookup" stomps on arg. */ - np = nlookup(ap->a_dname, &htp, &fname, 0); - if (np == NULL || fname != ap->a_dname) - goto next_rr; - 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)) - ) { - continue; - } - foundany++; - if (stale(dp)) { - foundstale++; - dprintf(1, (ddt, - "doaddinfo: stale entry '%s'%s\n", - np->n_dname, - (dp->d_flags&DB_F_HINT) - ? " hint" - : "" - )); - continue; - } -#ifdef NCACHE - if (dp->d_rcode) - continue; -#endif - /* - * Should be smart and eliminate duplicate - * data here. XXX - */ - if ((n = make_rr(ap->a_dname, dp, cp, msglen, 0)) < 0){ - /* truncation in the additional-data section - * is not all that serious. we do not set TC, - * since the answer and authority sections are - * OK; however, since we're not setting TC we - * have to make sure that none of the RR's for - * this name go out (!TC implies that all - * {name,type} appearances are complete -- and - * since we only do A RR's here, the name is - * the key). vixie, 23apr93 - */ - cp = save_cp; - msglen = save_msglen; - count = save_count; - break; - } - dprintf(5, (ddt, - "addinfo: adding address data n = %d\n", - n)); - cp += n; - msglen -= n; - count++; - } -next_rr: if (foundstale) { - /* Cache invalidate the address RR's */ - delete_all(np, (int)ap->a_class, T_A); - } - if (foundstale || !foundany) { - /* ask a real server for this info */ - (void) sysquery(ap->a_dname, (int)ap->a_class, T_A, - NULL, 0); - } - free(ap->a_dname); - } - hp->arcount = htons((u_int16_t)count); - return (cp - msg); -} - -int -doaddauth(hp, cp, buflen, np, dp) - register HEADER *hp; - u_char *cp; - int buflen; - struct namebuf *np; - struct databuf *dp; -{ - char dnbuf[MAXDNAME]; - int n; - - getname(np, dnbuf, sizeof(dnbuf)); - if (stale(dp)) { - dprintf(1, (ddt, - "doaddauth: can't add stale '%s' (%d)\n", - dnbuf, buflen)); - return (0); - } - n = make_rr(dnbuf, dp, cp, buflen, 1); - if (n <= 0) { - dprintf(1, (ddt, - "doaddauth: can't add oversize '%s' (%d) (n=%d)\n", - dnbuf, buflen, n)); - if (n < 0) { - hp->tc = 1; - } - return (0); - } - hp->nscount = htons((u_int16_t)1); - return (n); -} - -/* - * Do a zone transfer (or a recursive part of a zone transfer). - * SOA record already sent. - * - * top always refers to the domain at the top of the zone being transferred. - * np refers to a domain inside the zone being transferred, - * which will be equal to top if this is the first call, - * or will be a subdomain below top if this is a recursive call, - * rfp is a stdio file to which output is sent. - */ -static void -doaxfr(np, rfp, top, class) - register struct namebuf *np; - FILE *rfp; - struct namebuf *top; - int class; /* Class to transfer */ -{ - register struct databuf *dp; - register int n; - struct hashbuf *htp; - struct databuf *gdp; /* glue databuf */ - struct namebuf *gnp; /* glue namebuf */ - struct namebuf *tnp; /* top namebuf */ - struct databuf *tdp; /* top databuf */ - struct namebuf **npp, **nppend; - u_char msg[PACKETSZ]; - u_char *cp; - char *fname; - char dname[MAXDNAME]; - HEADER *hp = (HEADER *) msg; - int fndns; - - if (np == top) - dprintf(1, (ddt, "doaxfr()\n")); - fndns = 0; - hp->id = 0; - 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)); - - /* first do the NS records (del@harris) */ - for (dp = np->n_data; dp != NULL; dp = dp->d_next) { -#ifdef GEN_AXFR - if (dp->d_class != class && class != C_ANY) - continue; -#endif -#ifdef NCACHE - if (dp->d_rcode) - continue; -#endif - if (dp->d_type == T_NS) { - fndns = 1; - n = make_rr(dname, dp, cp, sizeof(msg)-HFIXEDSZ, 0); - if (n < 0) - continue; - fwritemsg(rfp, msg, n + HFIXEDSZ); -#ifdef NO_GLUE - if ((np != top) || (top->n_dname[0] == '\0')) { -#endif /*NO_GLUE*/ - /* Glue the sub domains together by sending - * the address records for the sub domain - * name servers along if necessary. - * Glue is necessary if the server is in any zone - * delegated from the current (top) zone. Such - * a delegated zone might or might not be that - * referred to by the NS record now being handled. - */ - htp = hashtab; - cp = (u_char *) (msg + HFIXEDSZ); - gnp = nlookup((char *)dp->d_data, &htp, &fname, 0); - if (gnp == NULL || fname != (char *)dp->d_data) - continue; -#ifdef NO_GLUE - for (tnp = gnp; tnp != NULL; tnp = tnp->n_parent) - if ( tnp == top ) - 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 (tdp = tnp->n_data; - tdp != NULL; - tdp = tdp->d_next) { -#ifdef GEN_AXFR - if (tdp->d_class != class && class != C_ANY) - continue; -#endif - if (tdp->d_type == T_NS) - break; - } - if (tdp != NULL) - break; /* found a zone cut */ - } - if (tnp == top) - continue; /* name server is not in a delegated zone */ - /* now we know glue records are needed. send them. */ -#endif /*NO_GLUE*/ - for (gdp=gnp->n_data; gdp != NULL; gdp=gdp->d_next) { -#ifdef GEN_AXFR - if (gdp->d_class != class && class != C_ANY) - continue; -#endif - if (gdp->d_type != T_A || stale(gdp)) - continue; -#ifdef NCACHE - if (gdp->d_rcode) - continue; -#endif - n = make_rr(fname, gdp, cp, sizeof(msg)-HFIXEDSZ, 0); - if (n < 0) - continue; - fwritemsg(rfp, msg, n + HFIXEDSZ); - } -#ifdef NO_GLUE - } -#endif /*NO_GLUE*/ - } - } - /* no need to send anything else if a delegation appeared */ - if ((np != top) && fndns) - return; - - /* do the rest of the data records */ - for (dp = np->n_data; dp != NULL; dp = dp->d_next) { -#ifdef GEN_AXFR - if (dp->d_class != class && class != C_ANY) - continue; -#endif - /* - * Skip the top SOA record (marks end of data); - * don't send SOA for subdomains, as we're not sending them; - * skip the NS records because we did them first. - */ - if (dp->d_type == T_SOA || dp->d_type == T_NS) - continue; - if (dp->d_zone == 0 || stale(dp)) - continue; -#ifdef NCACHE - if (dp->d_rcode) - continue; -#endif - if ((n = make_rr(dname, dp, cp, sizeof(msg)-HFIXEDSZ, 0)) < 0) - continue; - fwritemsg(rfp, msg, n + HFIXEDSZ); - } - - /* Finally do non-delegated subdomains. Delegated subdomains - * have already been handled. - */ - /* - * We find the subdomains by looking in the hash table for this - * domain, but the root domain needs special treatment, because - * of the following wart in the database design: - * - * The top level hash table (pointed to by the global `hashtab' - * variable) contains pointers to the namebuf's for the root as - * well as for the top-level domains below the root, in contrast - * to the usual situation where a hash table contains entries - * for domains at the same level. The n_hash member of the - * namebuf for the root domain is NULL instead of pointing to a - * hashbuf for the top-level domains. The n_parent members of - * the namebufs for the top-level domains are NULL instead of - * pointing to the namebuf for the root. - * - * We work around the wart as follows: - * - * If we are not dealing with the root zone then we just set - * htp = np->n_hash, pointing to the hash table for the current - * domain, and we walk through the hash table as usual, - * processing the namebufs for all the subdomains. - * - * If we are dealing with the root zone, then we set - * htp = hashtab, pointing to the global hash table (because - * there is no hash table associated with the root domain's - * namebuf. While we walk this hash table, we take care not to - * recursively process the entry for the root namebuf. - * - * (apb@und nov1990) - */ - htp = ((dname[0] == '\0') ? hashtab : np->n_hash); - if (htp == NULL) { - return; /* no subdomains */ - } - npp = htp->h_tab; - nppend = npp + htp->h_size; - while (npp < nppend) { - for (np = *npp++; np != NULL; np = np->n_next) { - if (np->n_dname[0] != '\0') { /* don't redo root domain */ - doaxfr(np, rfp, top, class); - } - } - } - if (np == top) - dprintf(1, (ddt, "exit doaxfr()\n")); -} - -#ifdef ALLOW_UPDATES -/* - * Called by UPDATE{A,D,DA,M,MA} to initiate a dynamic update. If this is the - * primary server for the zone being updated, we update the zone's serial - * number and then call doupdate directly. If this is a secondary, we just - * forward the update; this way, if the primary update fails (e.g., if the - * primary is unavailable), we don't update the secondary; if the primary - * update suceeds, ns_resp will get called with the response (when it comes - * in), and then update the secondary's copy. - */ -static int -InitDynUpdate(hp, msg, msglen, startcp, from, qsp, dfd) - register HEADER *hp; - char *msg; - int msglen; - u_char *startcp; - struct sockaddr_in *from; - struct qstream *qsp; - int dfd; -{ - struct databuf *nsp[NSMAX]; - struct zoneinfo *zp; - char dnbuf[MAXDNAME]; - struct hashbuf *htp = hashtab; /* lookup relative to root */ - struct namebuf *np; - struct databuf *olddp, *newdp, *dp; - struct databuf **nspp; - char *fname; - register u_char *cp = startcp; - u_int16_t class, type; - int n, size, zonenum; - char ZoneName[MAXDNAME], *znp; - -#ifdef DATUMREFCNT - nsp[0] = NULL; -#endif - if ((n = dn_expand(msg, msg + msglen, cp, dnbuf, sizeof(dnbuf))) < 0) { - dprintf(1, (ddt,"FORMERR InitDynUpdate expand name failed\n")); - hp->rcode = FORMERR; - return (FORMERR); - } - cp += n; - GETSHORT(type, cp); - if (type == T_SOA) { /* T_SOA updates not allowed */ - hp->rcode = REFUSED; - dprintf(1, (ddt, "InitDynUpdate: REFUSED - SOA update\n")); - return (REFUSED); - } - GETSHORT(class, cp); - cp += INT32SZ; - GETSHORT(size, cp); -/****XXX - need bounds checking here ****/ - cp += size; - - if ((zonenum = findzone(dnbuf, class)) == 0) { /* zone not found */ - hp->rcode = NXDOMAIN; - return (NXDOMAIN); - } - zp = &zones[zonenum]; - - /* Disallow updates for which we aren't authoratative. Note: the - following test doesn't work right: If it's for a non-local zone, - we will think it's a primary but be unable to lookup the namebuf, - thus returning 'NXDOMAIN' */ - if (zp->z_type != Z_PRIMARY && zp->z_type != Z_SECONDARY) { - hp->rcode = REFUSED; - dprintf(1, (ddt, - "InitDynUpdate: REFUSED - non-{primary,secondary} update\n")); - return (REFUSED); - } - if (!(zp->z_flags & Z_DYNAMIC)) { - hp->rcode = REFUSED; - dprintf(1, (ddt, - "InitDynUpdate: REFUSED - dynamic flag not set for zone\n")); - return (REFUSED); - } - - /* - * Lookup the zone namebuf. Lookup "xyz" not "xyz.", since - * otherwise the lookup fails, because '.' may have a nil n_hash - * associated with it. - */ - strcpy(ZoneName, zp->z_origin); - znp = &ZoneName[strlen(ZoneName) - 1]; - if (*znp == '.') - *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; - return (NXDOMAIN); - } - - /* - * If this is the primary copy increment the serial number. Don't - * increment the serial number if this is a secondary; this way, if 2 - * different secondaries both update the primary, they will both have - * lower serial numbers than the primary has, and hence eventually - * refresh and get all updates and become consistent. - * - * Note that the serial number must be incremented in both the zone - * data structure and the zone's namebuf. - */ - switch (zp->z_type) { - case Z_SECONDARY: /* forward update to primary */ - nspp = nsp; - dp = np->n_data; - while (dp != NULL) { - if (match(dp, class, T_NS)) { - if (nspp < &nsp[NSMAX-1]) { - *nspp++ = dp; -#ifdef DATUMREFCNT - dp->d_rcnt++; -#endif - } else - break; - } - dp = dp->d_next; - } - *nspp = NULL; /* Delimiter */ - if (ns_forw(nsp, msg, msglen, from, qsp, dfd, NULL, dnbuf, np) - < - 0) { - hp->rcode = SERVFAIL; -#ifdef DATUMREFCNT - free_nsp(nsp); -#endif - return (SERVFAIL); - } -#ifdef DATUMREFCNT - free_nsp(nsp); -#endif - return (FORWARDED); - - case Z_PRIMARY: - zp->z_serial++; - /* Find the SOA record */ - for (olddp = np->n_data; olddp != NULL; olddp = olddp->d_next) - 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); - hp->rcode = NXDOMAIN; -#ifdef DATUMREFCNT - free_nsp(nsp); -#endif - return (NXDOMAIN); - } - newdp = savedata(olddp->d_class, olddp->d_type, olddp->d_ttl, - olddp->d_data, olddp->d_size); - newdp->d_zone = olddp->d_zone; - newdp->d_cred = DB_C_AUTH; /* XXX - it may not be so */ - newdp->d_clev = db_getclev(zp->z_origin); - cp = (u_char *)newdp->d_data; - cp += strlen(cp) + 1; /* skip origin string */ - cp += strlen(cp) + 1; /* skip in-charge string */ - putlong((u_int32_t)(zp->z_serial), cp); - dprintf(4, (ddt, "after stuffing data into newdp:\n")); -#ifdef DEBUG - if (debug >= 4) - printSOAdata(newdp); -#endif - - if ((n = db_update(ZoneName, olddp, newdp, DB_DELETE, - hashtab)) != NOERROR) { /* XXX */ - dprintf(1, (ddt, - "InitDynUpdate: SOA update failed\n")); - hp->rcode = NOCHANGE; - free((char*) dp); -#ifdef DATUMREFCNT - free_nsp(nsp); -#endif - return (NOCHANGE); - } - - /* Now update the RR itself */ - /* XXX - DB_C_AUTH may be wrong */ - if (doupdate(msg, msglen, msg + HFIXEDSZ, zonenum, - (struct databuf *)0, DB_NODATA, DB_C_AUTH) < 0) { - dprintf(1, (ddt, "InitDynUpdate: doupdate failed\n")); - /* doupdate fills in rcode */ -#ifdef DATUMREFCNT - free_nsp(nsp); -#endif - return (hp->rcode); - } - zp->z_flags |= Z_CHANGED; -#ifdef DATUMREFCNT - free_nsp(nsp); -#endif - return (NOERROR); - } -} - -#ifdef DEBUG -/* - * Print the contents of the data in databuf pointed to by dp for an SOA record - */ -static void -printSOAdata(dp) - struct databuf *dp; -{ - register u_char *cp; - - 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); - cp += strlen(cp) + 1; /* skip origin string */ - fprintf(ddt, "printSOAdata: in-charge(%x)='%s'\n", cp, cp); - cp += strlen(cp) + 1; /* skip in-charge string */ - fprintf(ddt, "printSOAdata: serial(%x)=%d\n", cp, _getlong(cp)); -} -#endif -#endif - -static void -startxfr(qsp, np, soa, soalen, class, dname) - struct qstream *qsp; - struct namebuf *np; - u_char *soa; - int soalen; - int class; - const char *dname; -{ - FILE *rfp; - int fdstat; - pid_t pid; - - dprintf(5, (ddt, "startxfr()\n")); - - /* - * child does the work while - * the parent continues - */ - switch (pid = fork()) { - case -1: - syslog(LOG_ERR, "startxfr(%s -> [%s]) failing; fork: %m", - dname, inet_ntoa(qsp->s_from.sin_addr)); - 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); - return; - } - - /* - * Child. - * - * XXX: this should be a vfork/exec since on non-copy-on-write - * systems with huge nameserver images, this is very expensive. - */ - close(vs); - sqflush(/*allbut*/ qsp); - dqflush((time_t)0); - -#ifdef RENICE - nice(-40); nice(20); nice(0); /* back to "normal" */ -#endif - dprintf(5, (ddt, "startxfr: child pid %lu\n", (u_long)pid)); - - if (!(rfp = fdopen(qsp->s_rfd, "w"))) { - syslog(LOG_ERR, "fdopen: %m"); - _exit(1); - } - ns_setproctitle("zone XFR to", qsp->s_rfd); - if (-1 == (fdstat = fcntl(qsp->s_rfd, F_GETFL, 0))) { - syslog(LOG_ERR, "fcntl(F_GETFL): %m"); - _exit(1); - } - (void) fcntl(qsp->s_rfd, F_SETFL, fdstat & ~PORT_NONBLOCK); - fwritemsg(rfp, soa, soalen); - doaxfr(np, rfp, np, class); - fwritemsg(rfp, soa, soalen); - (void) fflush(rfp); - _exit(0); -} - -free_addinfo() { - struct addinfo *ap; - - for (ap = addinfo; --addcount >= 0; ap++) { - free(ap->a_dname); - } - addcount = 0; -} - -#ifdef DATUMREFCNT -free_nsp(nsp) -struct databuf **nsp; -{ - while (*nsp) { - if (--((*nsp)->d_rcnt)) { - dprintf(3, (ddt, "free_nsp: %s rcnt %d\n", - (*nsp)->d_data, (*nsp)->d_rcnt)); - } else { - dprintf(3, (ddt, "free_nsp: %s rcnt %d delayed\n", - (*nsp)->d_data, (*nsp)->d_rcnt)); - free(*nsp); /* delayed free */ - } - *nsp++ = NULL; - } -} -#endif diff --git a/usr.sbin/named/ns_resp.c b/usr.sbin/named/ns_resp.c deleted file mode 100644 index f8086e316dbb..000000000000 --- a/usr.sbin/named/ns_resp.c +++ /dev/null @@ -1,2190 +0,0 @@ -#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 4.9.1.24 1994/07/23 23:23:56 vixie Exp $"; -#endif /* not lint */ - -/* - * ++Copyright++ 1986, 1988, 1990 - * - - * Copyright (c) 1986, 1988, 1990 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - - * Portions Copyright (c) 1993 by Digital Equipment Corporation. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies, and that - * the name of Digital Equipment Corporation not be used in advertising or - * publicity pertaining to distribution of the document or software without - * specific, written prior permission. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT - * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - * - - * --Copyright-- - */ - -#include <sys/param.h> -#include <sys/socket.h> -#include <sys/file.h> -#include <netinet/in.h> -#include <arpa/nameser.h> -#include <arpa/inet.h> -#include <syslog.h> -#include <errno.h> -#include <stdio.h> -#include <resolv.h> - -#include "named.h" - -static void check_root __P((void)), - check_ns __P((void)); - -static u_int8_t norootlogged[MAXCLASS]; /* XXX- should be a bitmap */ - -static 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 - expandFailedQuery[] = "dn_expand failed in query", - 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"; - -void -ns_resp(msg, msglen) - u_char *msg; - int msglen; -{ - register struct qinfo *qp; - register HEADER *hp; - register struct qserv *qs; - register struct databuf *ns, *ns2; - register u_char *cp; -#ifdef VALIDATE - register u_char *tempcp; - struct sockaddr_in *server = &from_addr; - int *validatelist; - int lesscount; -#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 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"; - u_char newmsg[BUFSIZ]; - u_char **dpp, *tp; - time_t rtrip; - struct hashbuf *htp; - struct namebuf *np; - struct netinfo *lp; - struct fwdinfo *fwd; - - nameserIncr(from_addr.sin_addr, nssRcvdR); -#ifdef DATUMREFCNT - nsp[0] = NULL; -#endif - hp = (HEADER *) msg; - if ((qp = qfindid(hp->id)) == NULL ) { - dprintf(1, (ddt, "DUP? dropped (id %d)\n", ntohs(hp->id))); - nameserIncr(from_addr.sin_addr, nssRcvdDupR); - return; - } - - dprintf(2, (ddt, "Response (%s %s %s) nsid=%d id=%d\n", - (qp->q_flags & Q_SYSTEM) ?"SYSTEM" :"USER", - (qp->q_flags & Q_PRIMING) ?"PRIMING" :"NORMAL", - (qp->q_flags & Q_ZSERIAL) ?"ZSERIAL" :"-", - ntohs(qp->q_nsid), ntohs(qp->q_id))); - - /* - * Here we handle bad responses from servers. - * Several possibilities come to mind: - * The server is sick and returns SERVFAIL - * The server returns some garbage opcode (its sick) - * The server can't understand our query and return FORMERR - * In all these cases, we simply drop the packet and force - * a retry. This will make him look bad due to unresponsiveness. - */ - if ((hp->rcode != NOERROR && hp->rcode != NXDOMAIN) -#ifndef NCACHE - || (hp->rcode == NXDOMAIN && !hp->aa) /* must accept this one if - * we allow negative caching - */ -#endif /*NCACHE*/ - || hp->opcode != QUERY) { - dprintf(2, (ddt, "resp: error (ret %d, op %d), dropped\n", - hp->rcode, hp->opcode)); - switch (hp->rcode) { - case SERVFAIL: - nameserIncr(from_addr.sin_addr, nssRcvdFail); - break; - case FORMERR: - nameserIncr(from_addr.sin_addr, nssRcvdFErr); - break; - default: - nameserIncr(from_addr.sin_addr, nssRcvdErr); - break; - } - return; - } -#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 */ - -#ifdef DEBUG - if (debug > 0) - fp_query(msg, 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); - if (n < 0) { - formerrmsg = expandFailedAuth; - goto formerr; - } - cp += n; - GETSHORT(type, cp); - if (cp - msg > msglen) { - formerrmsg = outofDataAuth; - goto formerr; - } - - /* - * If the answer delegates us either to the same level in - * the hierarchy or closer to the root, we consider this - * server lame. - */ - - 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) - ) - ) - ) { - 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); - } -#endif /* LAME_LOGGING */ - return; - } - } -#endif /* LAME_DELEGATION */ - - -#ifdef ALLOW_UPDATES - if ( (hp->rcode == NOERROR) && - (hp->opcode == UPDATEA || hp->opcode == UPDATED || - hp->opcode == UPDATEDA || hp->opcode == UPDATEM || - hp->opcode == UPDATEMA) ) { - /* - * Update the secondary's copy, now that the primary - * successfully completed the update. Zone doesn't matter - * for dyn. update -- doupdate calls findzone to find it - */ - /* XXX - DB_C_AUTH may be wrong */ - (void) doupdate(qp->q_msg, qp->q_msglen, qp->q_msg + HFIXEDSZ, - 0, (struct databuf *)0, 0, DB_C_AUTH); - dprintf(3, (ddt, "resp: leaving, UPDATE*\n")); - /* return code filled in by doupdate */ - goto return_msg; - } -#endif /* ALLOW_UPDATES */ - - /* - * Determine if the response came from a forwarder. Packets from - * anyplace not listed as a forwarder or as a server to whom we - * might have forwarded the query will be dropped. - */ - for (fwd = fwdtab; fwd != (struct fwdinfo *)NULL; fwd = fwd->next) { - if (fwd->fwdaddr.sin_addr.s_addr == - from_addr.sin_addr.s_addr) { - /* XXX - should put this in STATS somewhere */ - break; - } - } - /* 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. - */ - /* - * If we were using nameservers, 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++) - if (qs->ns_addr.sin_addr.s_addr == - from_addr.sin_addr.s_addr) - break; - if (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)); - } - /* - * We don't know who this response came from so it - * gets dropped on the floor. - */ - return; - } - stp = &qs->stime; - - /* Handle response from different (untried) interface */ - if ((qs->ns != NULL) && (stp->tv_sec == 0)) { - ns = qs->ns; - while (qs > qp->q_addr && - (qs->stime.tv_sec == 0 || qs->ns != ns)) - qs--; - *stp = qs->stime; - /* XXX - sometimes stp still ends up pointing to - * a zero timeval, in spite of the above attempt. - * Why? What should we do about it? - */ - dprintf(1, (ddt, - "Response from unused address %s, assuming %s\n", - inet_ntoa(from_addr.sin_addr), - inet_ntoa(qs->ns_addr.sin_addr))); - /* XXX - catch aliases here */ - } - - /* compute query round trip time */ - /* XXX - avoid integer overflow, which is quite likely if stp - * points to a zero timeval (see above). - * rtrip is of type time_t, which we assume is at least - * as big as an int. - */ - if ((tt.tv_sec - stp->tv_sec) > (INT_MAX-999)/1000) { - rtrip = INT_MAX; - } else { - rtrip = ((tt.tv_sec - stp->tv_sec) * 1000 + - (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)); - - /* prevent floating point overflow, limit to 1000 sec */ - if (rtrip > 1000000) { - rtrip = 1000000; - } - ns = qs->nsdata; - /* - * Don't update nstime if this doesn't look - * like an address databuf now. XXX - */ - if (ns && (ns->d_type==T_A) && (ns->d_class==qs->ns->d_class)){ - if (ns->d_nstime == 0) - ns->d_nstime = (u_int32_t)rtrip; - else - ns->d_nstime = (u_int32_t) - (ns->d_nstime * ALPHA - + - (1-ALPHA) * (u_int32_t)rtrip); - /* prevent floating point overflow, - * limit to 1000 sec - */ - if (ns->d_nstime > 1000000) - ns->d_nstime = 1000000; - } - - /* - * Record the source so that we do not use this NS again. - */ - 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), - ns->d_nstime)); - } - - /* - * Penalize those who had earlier chances but failed - * by multiplying round-trip times by BETA (>1). - * Improve nstime for unused addresses by applying GAMMA. - * The GAMMA factor makes unused entries slowly - * improve, so they eventually get tried again. - * GAMMA should be slightly less than 1. - * Watch out for records that may have timed out - * and are no longer the correct type. XXX - */ - - for (n = 0, qs = qp->q_addr; n < qp->q_naddr; n++, qs++) { - ns2 = qs->nsdata; - if ((!ns2) || (ns2 == ns)) - continue; - if (ns2->d_type != T_A || - ns2->d_class != qs->ns->d_class) /* XXX */ - continue; - if (qs->stime.tv_sec) { - if (ns2->d_nstime == 0) - ns2->d_nstime = (u_int32_t)(rtrip * BETA); - else - ns2->d_nstime = (u_int32_t)( - ns2->d_nstime * BETA + (1-ALPHA) * rtrip - ); - if (ns2->d_nstime > 1000000) - 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), - ns2->d_nstime)); - } - } - - /*************************************************************/ - - /* - * Skip query section - */ - 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; - } - } - - /* - * 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", - ancount, aucount, arcount)); - - /* - * If there's an answer, check if it's a CNAME response; - * if no answer but aucount > 0, see if there is an NS - * or just an SOA. (NOTE: ancount might be 1 with a CNAME, - * and NS records may still be in the authority section; - * we don't bother counting them, as we only use nscount - * if ancount == 0.) - */ - if (ancount == 1 || (ancount == 0 && aucount > 0)) { - c = aucount; - do { - if (tp - msg >= msglen) { - formerrmsg = outofDataAnswer; - goto formerr; - } - n = dn_skipname(tp, msg + msglen); - if (n <= 0) { - formerrmsg = skipnameFailedAnswer; - goto formerr; - } - tp += n; /* name */ - GETSHORT(i, tp); /* type */ - tp += INT16SZ; /* class */ - tp += INT32SZ; /* ttl */ - GETSHORT(count, tp); /* dlen */ - if (tp - msg > msglen - count) { - formerrmsg = dlenOverrunAnswer; - goto formerr; - } - tp += count; - if (ancount && i == T_CNAME) { - cname++; - dprintf(1, - (ddt, - "CNAME - needs more processing\n" - ) - ); - if (!qp->q_cmsglen) { - qp->q_cmsg = qp->q_msg; - qp->q_cmsglen = qp->q_msglen; - qp->q_msg = NULL; - qp->q_msglen = 0; - } - } - /* - * See if authority record is a nameserver. - */ - if (ancount == 0 && i == T_NS) - nscount++; - } while (--c > 0); - tp = cp; - } - - 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 */ - int n; - u_int16_t dlen; - u_int32_t serial; - u_char *tp = cp; - - if (0 >= (n = dn_skipname(tp, msg + msglen))) { - formerrmsg = skipnameFailedAnswer; - goto formerr; - } - tp += n /* name */ - + INT16SZ /* type */ - + INT16SZ /* class */ - + INT32SZ; /* ttl */ - GETSHORT(dlen, tp); /* dlen */ - - if (dlen < (5 * INT32SZ)) { - formerrmsg = dlenUnderrunAnswer; - goto formerr; - } - - if (0 >= (n = dn_skipname(tp, msg + msglen))) { - formerrmsg = skipnameFailedAnswer; - goto formerr; - } - tp += n; /* mname */ - if (0 >= (n = dn_skipname(tp, msg + msglen))) { - formerrmsg = skipnameFailedAnswer; - goto formerr; - } - tp += n; /* rname */ - GETLONG(serial, tp); - - qserial_answer(qp, serial); - } - qremove(qp); - return; - } - - /* - * Add the info received in the response to the data base. - */ - c = ancount + aucount + arcount; -#ifdef NCACHE - /* -ve $ing non-existence of record, must handle non-authoritative - * NOERRORs with c == 0. - */ - if (!hp->aa && hp->rcode == NOERROR && c == 0) { - goto return_msg; - } /*should ideally validate message before returning it*/ -#endif /*NCACHE*/ -#ifdef notdef - /* - * If the request was for a CNAME that doesn't exist, - * but the name is valid, fetch any other data for the name. - * 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 - && !(qp->q_flags & Q_SYSTEM)) { - dprintf(4, (ddt, "resp: leaving, no CNAME\n")); - - /* Cause us to put it in the cache later */ - prime(class, T_ANY, qp); - - /* Nothing to store, just give user the answer */ - goto return_msg; - } -#endif /* notdef */ - - nspp = nsp; - if (qp->q_flags & Q_SYSTEM) - dbflags = DB_NOTAUTH | DB_NODATA; - else - dbflags = DB_NOTAUTH | DB_NODATA | DB_NOHINTS; - count = c; - if (hp->tc) { - count -= arcount; /* truncation had to affect this */ - if (!arcount) { - count -= aucount; /* guess it got this too */ - } - if (!(arcount || aucount)) { - count -= ancount; /* things are pretty grim */ - } - /* XXX - should retry this query with TCP */ - } -#ifdef VALIDATE - tempcp = cp; - validatelist = (int *)malloc(count * sizeof(int)); - lesscount = 0; /*initialize*/ - old_ancount = ancount; - for (i = 0; i < count; i++) { - int VCode; - if (tempcp >= msg + msglen) { - free((char *)validatelist); - formerrmsg = outofDataFinal; - goto formerr; - } - if ((n = dovalidate(msg, msglen, tempcp, 0, - dbflags, server, &VCode)) < 0) { - dprintf(1, (ddt, - "resp: leaving, dovalidate failed\n")); - free((char *)validatelist); - - /* return code filled in by dovalidate */ - goto return_msg; - } - validatelist[i] = VCode; - if (VCode == INVALID) lesscount++; - tempcp += n; - } - - /* need to delete INVALID records from the message - * and change fields appropriately - */ - n = update_msg(msg, &msglen, validatelist, count); - free((char *)validatelist); - if (n < 0) - goto formerr; - count -= lesscount; - - if (old_ancount && !hp->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) { - formerrmsg = outofDataFinal; - goto formerr; - } - if (i < ancount) { - cred = hp->aa ? DB_C_AUTH : DB_C_ANSWER; - } else { - cred = DB_C_ADDITIONAL; - } - ns3 = 0; - n = doupdate(msg, msglen, cp, 0, &ns3, dbflags, cred); - if (n < 0) { - dprintf(1, (ddt, "resp: leaving, doupdate failed\n")); - - /* return code filled in by doupdate */ - goto return_msg; - } - /* - * Remember nameservers from the authority section - * for referrals. - * (This is usually overwritten by findns below(?). XXX - */ - if (ns3 && i >= ancount && i < ancount + aucount && - nspp < &nsp[NSMAX-1]) { - *nspp++ = ns3; -#ifdef DATUMREFCNT - ns3->d_rcnt++; - *nspp = NULL; -#endif - } - cp += n; - } - - if ((qp->q_flags & Q_SYSTEM) && ancount) { - if (qp->q_flags & Q_PRIMING) - check_root(); - dprintf(3, (ddt, "resp: leaving, SYSQUERY ancount %d\n", - ancount)); - qremove(qp); -#ifdef DATUMREFCNT - free_nsp(nsp); -#endif - return; - } - - if (cp > msg + msglen) { - formerrmsg = outofDataAFinal; - goto formerr; - } - - /* - * If there are addresses and this is a local query, - * sort them appropriately for the local context. - */ - if (ancount > 1 && (lp = local(&qp->q_from)) != NULL) - sort_response(tp, ancount, lp, msg + msglen); - - /* - * 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) || - (!cname && !qp->q_cmsglen && ancount)) { - dprintf(3, (ddt, "resp: got as much answer as there is\n")); - goto return_msg; - } - - /* - * We might want to cache this negative answer. - */ - if (!ancount && - (!nscount || hp->rcode == NXDOMAIN) && - (hp->aa || fwd || class == C_ANY)) { - /* we have an authoritative NO */ - dprintf(3, (ddt, "resp: leaving auth NO\n")); - if (qp->q_cmsglen) { - msg = qp->q_cmsg; - msglen = qp->q_cmsglen; - hp = (HEADER *)msg; - } -#ifdef NCACHE - /* answer was NO */ - if (hp->aa && - ((hp->rcode == NXDOMAIN) || (hp->rcode == NOERROR))) { - cache_n_resp(msg, msglen); - } -#endif /*NCACHE*/ - goto return_msg; - } - - /* - * All messages in here need further processing. i.e. they - * are either CNAMEs or we got referred again. - */ - count = 0; - founddata = 0; - foundname = 0; - dname = name; - if (!cname && qp->q_cmsglen && ancount) { - dprintf(1, (ddt, "Cname second pass\n")); - newmsglen = qp->q_cmsglen; - bcopy(qp->q_cmsg, newmsg, newmsglen); - } else { - newmsglen = msglen; - bcopy(msg, newmsg, newmsglen); - } - hp = (HEADER *) newmsg; - hp->ancount = 0; - hp->nscount = 0; - hp->arcount = 0; - dnptrs[0] = newmsg; - dnptrs[1] = NULL; - cp = newmsg + HFIXEDSZ; - if (cname) - cp += dn_skipname(cp, newmsg + newmsglen) + QFIXEDSZ; - n = dn_expand(newmsg, newmsg + newmsglen, cp, dname, sizeof name); - if (n < 0) { - dprintf(1, (ddt, "dn_expand failed\n")); - goto servfail; - } - if (!cname) - cp += n + QFIXEDSZ; - buflen = sizeof(newmsg) - (cp - newmsg); - -try_again: - dprintf(1, (ddt, "resp: nlookup(%s) type=%d\n", dname, type)); - fname = ""; - htp = hashtab; /* lookup relative to root */ - np = nlookup(dname, &htp, &fname, 0); - dprintf(1, (ddt, "resp: %s '%s' as '%s' (cname=%d)\n", - np == NULL ? "missed" : "found", dname, fname, cname)); - if (np == NULL || fname != dname) - goto fetch_ns; - - foundname++; - count = cp - newmsg; - n = finddata(np, class, type, 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) { - cname++; - goto try_again; - } - founddata = 1; - - dprintf(3, (ddt, - "resp: foundname=%d, count=%d, founddata=%d, cname=%d\n", - foundname, count, founddata, cname)); - -fetch_ns: - hp->ancount = htons(hp->ancount); - /* - * Look for name servers to refer to and fill in the authority - * section or record the address for forwarding the query - * (recursion desired). - */ -#ifdef DATUMREFCNT - free_nsp(nsp); -#endif - switch (findns(&np, class, 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) { - hp->aa = 1; - /* XXX: should return SOA if founddata == 0, - * but old named's are confused by an SOA - * in the auth. section if there's no error. - */ - if (foundname == 0 && np) { - n = doaddauth(hp, cp, buflen, np, nsp[0]); - cp += n; - buflen -= n; - } - } - goto return_newmsg; - - case SERVFAIL: - goto servfail; - } - - if (founddata) { - hp = (HEADER *)newmsg; - n = add_data(np, nsp, cp, buflen); - if (n < 0) { - hp->tc = 1; - n = (-n); - } - cp += n; - buflen -= n; - hp->nscount = htons((u_int16_t)count); - goto return_newmsg; - } - - /* - * If we get here, we don't have the answer yet and are about - * 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); - 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); - } - 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); - } - } -#endif - qp->q_naddr = 0; - qp->q_curaddr = 0; - qp->q_fwd = fwdtab; -#ifdef LAME_DELEGATION - getname(np, qp->q_domain, sizeof(qp->q_domain)); -#endif /* LAME_DELEGATION */ - if ((n = nslookup(nsp, qp, dname, "ns_resp")) <= 0) { - if (n < 0) { - dprintf(3, (ddt, "resp: nslookup reports danger\n")); - } else { - dprintf(3, (ddt, "resp: no addrs found for NS's\n")); - } - if (cname) /* a remote CNAME that does not have data */ - goto return_newmsg; - goto servfail; - } - for (n = 0; n < qp->q_naddr; n++) - qp->q_addr[n].stime.tv_sec = 0; - if (!qp->q_fwd) - qp->q_addr[0].stime = tt; - if (cname) { - if (qp->q_cname++ == MAXCNAMES) { - dprintf(3, (ddt, - "resp: leaving, MAXCNAMES exceeded\n")); - goto servfail; - } - dprintf(1, (ddt, "q_cname = %d\n",qp->q_cname)); - dprintf(3, (ddt, - "resp: building recursive query; nslookup\n")); - 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")); - goto servfail; - } - qp->q_msglen = res_mkquery(QUERY, dname, class, - type, NULL, 0, NULL, - qp->q_msg, BUFSIZ); - hp = (HEADER *) qp->q_msg; - hp->rd = 0; - } else - hp = (HEADER *)qp->q_msg; - hp->id = qp->q_nsid = htons((u_int16_t)++nsid); - 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, - 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); -#endif - if (sendto(ds, 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)); - nameserIncr(nsa->sin_addr, nssSendtoErr); - } - hp->rd = 0; /* leave set to 0 for dup detection */ - nameserIncr(nsa->sin_addr, nssSentFwdR); - nameserIncr(qp->q_from.sin_addr, nssRcvdFwdR); - dprintf(3, (ddt, "resp: Query sent.\n")); -#ifdef DATUMREFCNT - free_nsp(nsp); -#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)); - 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); - } - nameserIncr(from_addr.sin_addr, nssSentFErr); -#ifdef DATUMREFCNT - free_nsp(nsp); -#endif - return; - -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; - (void) send_msg(msg, msglen, qp); - qremove(qp); -#ifdef DATUMREFCNT - free_nsp(nsp); -#endif - return; - -return_newmsg: - nameserIncr(qp->q_from.sin_addr, nssSentAns); - if (addcount) { - n = doaddinfo(hp, cp, buflen); - cp += n; - buflen -= n; - } - hp->qr = 1; - hp->id = qp->q_id; - hp->rd = 1; - hp->ra = 1; - (void) send_msg(newmsg, cp - newmsg, qp); - qremove(qp); -#ifdef DATUMREFCNT - free_nsp(nsp); -#endif - return; - -servfail: - nameserIncr(qp->q_from.sin_addr, nssSentFail); - hp = (HEADER *)(cname ? qp->q_cmsg : qp->q_msg); - hp->rcode = SERVFAIL; - hp->id = qp->q_id; - hp->rd = 1; - hp->ra = 1; - hp->qr = 1; - (void) send_msg((u_char *)hp, (cname ? qp->q_cmsglen : qp->q_msglen), - qp); - qremove(qp); -#ifdef DATUMREFCNT - free_nsp(nsp); -#endif - return; -} - -/* - * Decode the resource record 'rrp' and update the database. - * If savens is non-nil, record pointer for forwarding queries a second time. - */ -int -doupdate(msg, msglen, rrp, zone, savens, flags, cred) - u_char *msg, *rrp; - struct databuf **savens; - int msglen, zone, flags; - u_int cred; -{ - register u_char *cp; - register int n; - int class, type, dlen, n1; - u_int32_t ttl; - struct databuf *dp; - char dname[MAXDNAME]; - u_char *cp1; - u_char data[BUFSIZ]; - register HEADER *hp = (HEADER *)msg; -#ifdef ALLOW_UPDATES - int zonenum; -#endif - - dprintf(3, (ddt, "doupdate(zone %d, savens %x, flags %x)\n", - zone, savens, flags)); - - cp = rrp; - if ((n = dn_expand(msg, msg + msglen, cp, dname, sizeof dname)) < 0) { - hp->rcode = FORMERR; - return (-1); - } - cp += n; - GETSHORT(type, cp); - GETSHORT(class, cp); - GETLONG(ttl, cp); - GETSHORT(dlen, cp); - dprintf(3, (ddt, "doupdate: dname %s type %d class %d ttl %d\n", - dname, type, class, ttl)); - /* - * Convert the resource record data into the internal - * database format. - */ - switch (type) { - case T_A: - if (dlen != INT32SZ) { - hp->rcode = FORMERR; - return (-1); - } - /*FALLTHROUGH*/ - case T_WKS: - case T_HINFO: - case T_UINFO: - case T_UID: - case T_GID: - case T_TXT: - case T_X25: - case T_ISDN: - case T_NSAP: -#ifdef ALLOW_T_UNSPEC - case T_UNSPEC: -#endif - cp1 = cp; - n = dlen; - cp += n; - break; - - case T_CNAME: - case T_MB: - case T_MG: - case T_MR: - case T_NS: - case T_PTR: - n = dn_expand(msg, msg + msglen, cp, - (char *)data, sizeof data); - if (n < 0) { - hp->rcode = FORMERR; - return (-1); - } - cp += n; - cp1 = data; - n = strlen((char *)data) + 1; - break; - - case T_MINFO: - case T_SOA: - case T_RP: - n = dn_expand(msg, msg + msglen, cp, - (char *)data, sizeof data); - if (n < 0) { - hp->rcode = FORMERR; - return (-1); - } - cp += n; - cp1 = data + (n = strlen((char *)data) + 1); - n1 = sizeof(data) - n; - if (type == T_SOA) - n1 -= 5 * INT32SZ; - 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; - if (type == T_SOA) { - bcopy(cp, cp1, n = 5 * INT32SZ); - cp += n; - cp1 += n; - } - n = cp1 - data; - cp1 = data; - break; - - case T_MX: - case T_AFSDB: - case T_RT: - /* grab preference */ - bcopy(cp, data, INT16SZ); - cp1 = data + INT16SZ; - cp += INT16SZ; - - /* get name */ - n = dn_expand(msg, msg + msglen, cp, (char *)cp1, - sizeof data - INT16SZ); - if (n < 0) { - hp->rcode = FORMERR; - return (-1); - } - cp += n; - - /* compute end of data */ - cp1 += strlen((char *)cp1) + 1; - /* compute size of data */ - n = cp1 - data; - cp1 = data; - break; - - default: - dprintf(3, (ddt, "unknown type %d\n", type)); - return ((cp - rrp) + dlen); - } - if (n > MAXDATA) { - dprintf(1, (ddt, - "update type %d: %d bytes is too much data\n", - type, n)); - hp->rcode = NOCHANGE; /* XXX - FORMERR ??? */ - return (-1); - } - -#ifdef ALLOW_UPDATES - /* - * If this is a dynamic update request, process it specially; else, - * execute normal update code. - */ - switch(hp->opcode) { - - /* For UPDATEM and UPDATEMA, do UPDATED/UPDATEDA followed by UPDATEA */ - case UPDATEM: - case UPDATEMA: - - /* - * The named code for UPDATED and UPDATEDA is the same except that for - * UPDATEDA we we ignore any data that was passed: we just delete all - * RRs whose name, type, and class matches - */ - case UPDATED: - case UPDATEDA: - if (type == T_SOA) { /* Not allowed */ - dprintf(1, (ddt, "UDPATE: REFUSED - SOA delete\n")); - hp->rcode = REFUSED; - return (-1); - } - /* - * Don't check message length if doing UPDATEM/UPDATEMA, - * since the whole message wont have been demarshalled until - * we reach the code for UPDATEA - */ - if ( (hp->opcode == UPDATED) || (hp->opcode == UPDATEDA) ) { - if (cp != (u_char *)(msg + msglen)) { - dprintf(1, - (ddt, - "FORMERR UPDATE message length off\n" - ) - ); - hp->rcode = FORMERR; - return (-1); - } - } - if ((zonenum = findzone(dname, class)) == 0) { - hp->rcode = NXDOMAIN; - return (-1); - } - if (zones[zonenum].z_flags & Z_DYNADDONLY) { - hp->rcode = NXDOMAIN; - return (-1); - } - if ( (hp->opcode == UPDATED) || (hp->opcode == UPDATEM) ) { - /* Make a dp for use in db_update, as old dp */ - dp = savedata(class, type, 0, cp1, n); - dp->d_zone = zonenum; - dp->d_cred = cred; - dp->d_clev = db_getclev(zones[zonenum].z_origin); - n = db_update(dname, dp, NULL, DB_MEXIST | DB_DELETE, - hashtab); - if (n != OK) { - dprintf(1, (ddt, - "UPDATE: db_update failed\n")); - free((char*) dp); - hp->rcode = NOCHANGE; - return (-1); - } - } else { /* UPDATEDA or UPDATEMA */ - int DeletedOne = 0; - /* Make a dp for use in db_update, as old dp */ - dp = savedata(class, type, 0, NULL, 0); - dp->d_zone = zonenum; - dp->d_cred = cred; - dp->d_clev = db_getclev(zones[zonenum].z_origin); - do { /* Loop and delete all matching RR(s) */ - n = db_update(dname, dp, NULL, DB_DELETE, - hashtab); - if (n != OK) - break; - DeletedOne++; - } while (1); - free((char*) dp); - /* Ok for UPDATEMA not to have deleted any RRs */ - if (!DeletedOne && hp->opcode == UPDATEDA) { - dprintf(1, (ddt, - "UPDATE: db_update failed\n")); - hp->rcode = NOCHANGE; - return (-1); - } - } - if ( (hp->opcode == UPDATED) || (hp->opcode == UPDATEDA) ) - return (cp - rrp);; - /* - * Else unmarshal the RR to be added and continue on to - * UPDATEA code for UPDATEM/UPDATEMA - */ - if ((n = - dn_expand(msg, msg+msglen, cp, dname, sizeof(dname))) < 0) { - dprintf(1, (ddt, - "FORMERR UPDATE expand name failed\n")); - hp->rcode = FORMERR; - return (-1); - } - cp += n; - GETSHORT(type, cp); - GETSHORT(class, cp); - GETLONG(ttl, cp); - GETSHORT(n, cp); - cp1 = cp; -/**** XXX - need bounds checking here ****/ - cp += n; - - case UPDATEA: - if (n > MAXDATA) { - dprintf(1, (ddt, "UPDATE: too much data\n")); - hp->rcode = NOCHANGE; - return (-1); - } - if (cp != (u_char *)(msg + msglen)) { - dprintf(1, (ddt, - "FORMERR UPDATE message length off\n")); - hp->rcode = FORMERR; - return (-1); - } - if ((zonenum = findzone(dname, class)) == 0) { - hp->rcode = NXDOMAIN; - return (-1); - } - if (zones[zonenum].z_flags & Z_DYNADDONLY) { - struct hashbuf *htp = hashtab; - char *fname; - if (nlookup(dname, &htp, &fname, 0) && - !strcasecmp(dname, fname)) { - dprintf(1, (ddt, - "refusing add of existing name\n" - )); - hp->rcode = REFUSED; - return (-1); - } - } - dp = savedata(class, type, ttl, cp1, n); - dp->d_zone = zonenum; - dp->d_cred = cred; - dp->d_clev = db_getclev(zones[zonenum].z_origin); - if ((n = db_update(dname, NULL, dp, DB_NODATA, - hashtab)) != OK) { - dprintf(1, (ddt, "UPDATE: db_update failed\n")); - hp->rcode = NOCHANGE; - free((char*) dp); - return (-1); - } - else - return (cp - rrp); - } -#endif /* ALLOW_UPDATES */ - - if (zone == 0) - ttl += tt.tv_sec; -#if defined(TRACEROOT) || defined(BOGUSNS) - if ((type == T_NS) && (savens != NULL)) { - char qname[MAXDNAME], *temp; - register int bogus = 0; - int bogusns = 0; -#ifdef BOGUSNS - if (addr_on_netlist(from_addr.sin_addr, boglist)) { - bogusns++; - bogus++; - } -#endif - if (!bogus && - ((temp = strrchr((char *)data, '.')) != NULL) && - !strcasecmp(temp, ".arpa") - ) - bogus++; - qname[0] = qname[1] = '\0'; - if (dn_expand(msg, msg + msglen, msg + HFIXEDSZ, - qname, sizeof(qname)) < 0) - qname[0] = '?'; - else if (qname[0] == '\0') - qname[0] = '.'; - if (bogus && ((dname[0] == '\0') && (zone == 0))) { - 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); - 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); - return (cp - rrp); - } -#endif - } -#endif /*TRACEROOT || BOGUSNS*/ - - dp = savedata(class, type, ttl, cp1, n); - dp->d_zone = zone; - dp->d_cred = cred; - dp->d_clev = 0; /* We trust what is on disk more, except root srvrs */ - if ((n = db_update(dname, dp, dp, flags, hashtab)) != OK) { -#ifdef DEBUG - if (debug && (n != DATAEXISTS)) - fprintf(ddt,"update failed (%d)\n", n); - else if (debug >= 3) - fprintf(ddt,"update failed (DATAEXISTS)\n"); -#endif - free((char *)dp); - } else if (type == T_NS && savens != NULL) - *savens = dp; - return (cp - rrp); -} - -int -send_msg(msg, msglen, qp) - u_char *msg; - int msglen; - struct qinfo *qp; -{ - if (qp->q_flags & Q_SYSTEM) - return (1); -#ifdef DEBUG - if (debug) { - fprintf(ddt,"send_msg -> [%s] (%s %d %d) id=%d\n", - inet_ntoa(qp->q_from.sin_addr), - 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); - } - } - if (debug >= 10) - fp_query(msg, ddt); -#endif /* DEBUG */ - if (qp->q_stream == QSTREAM_NULL) { - if (sendto(qp->q_dfd, 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)); - nameserIncr(qp->q_from.sin_addr, nssSendtoErr); - return (1); - } - } else { - (void) writemsg(qp->q_stream->s_rfd, (u_char*)msg, msglen); - sq_done(qp->q_stream); - } - return (0); -} - -#ifdef notdef -/* i don't quite understand this but the only ref to it is notdef'd --vix */ -prime(class, type, oqp) - int class, type; - register struct qinfo *oqp; -{ - char dname[BUFSIZ]; - - if (oqp->q_msg == NULL) - return; - if (dn_expand((u_char *)oqp->q_msg, - (u_char *)oqp->q_msg + oqp->q_msglen, - (u_char *)oqp->q_msg + HFIXEDSZ, (u_char *)dname, - sizeof(dname)) < 0) - return; - dprintf(2, (ddt, "prime: %s\n", dname)); - (void) sysquery(dname, class, type, NULL, 0); -} -#endif - -void -prime_cache() -{ - register struct qinfo *qp; - - 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) - priming = 0; - else - qp->q_flags |= (Q_SYSTEM | Q_PRIMING); - } - needs_prime_cache = 0; - return; -} - -struct qinfo * -sysquery(dname, class, type, nss, nsc) - char *dname; - int class, type; - struct in_addr *nss; - int nsc; -{ - register struct qinfo *qp, *oqp; - register HEADER *hp; - struct namebuf *np; - struct databuf *nsp[NSMAX]; - struct hashbuf *htp; - struct sockaddr_in *nsa; - char *fname; - int count; - -#ifdef DATUMREFCNT - nsp[0] = NULL; -#endif - dprintf(3, (ddt, "sysquery(%s, %d, %d, 0x%x, %d)\n", - dname, class, type, nss, nsc)); - qp = qnew(); - - if (nss && nsc) { - np = NULL; - } else { - htp = hashtab; - 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)); - qfree(qp); - return (0); - } - - switch (findns(&np, class, nsp, &count, 0)) { - case NXDOMAIN: - case SERVFAIL: - dprintf(1, (ddt, - "sysquery: findns error on %s?\n", dname)); - qfree(qp); -#ifdef DATUMREFCNT - free_nsp(nsp); -#endif - return (0); - } - } - - /* build new qinfo struct */ - qp->q_cmsg = qp->q_msg = NULL; - qp->q_dfd = ds; - if (nss && nsc) - qp->q_fwd = NULL; - else - qp->q_fwd = fwdtab; - qp->q_expire = tt.tv_sec + RETRY_TIMEOUT*2; - qp->q_flags |= Q_SYSTEM; -#ifdef LAME_DELEGATION - getname(np, qp->q_domain, sizeof(qp->q_domain)); -#endif /* LAME_DELEGATION */ - - if ((qp->q_msg = (u_char *)malloc(BUFSIZ)) == NULL) { - qfree(qp); -#ifdef DATUMREFCNT - free_nsp(nsp); -#endif - return (0); - } - qp->q_msglen = res_mkquery(QUERY, dname, class, - type, NULL, 0, NULL, - qp->q_msg, BUFSIZ); - hp = (HEADER *) qp->q_msg; - hp->id = qp->q_nsid = htons((u_int16_t)++nsid); - 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) { - 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); - } - } - - if (nss && nsc) { - int i; - struct qserv *qs; - - for (i = 0, qs = qp->q_addr; - i < nsc; - i++, qs++) { - qs->ns_addr.sin_family = AF_INET; - qs->ns_addr.sin_addr = nss[i]; - qs->ns_addr.sin_port = ns_port; - qs->ns = NULL; - qs->nsdata = NULL; - qs->stime = tt; - qs->nretry = 0; - } - 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")); - } - qfree(qp); -#ifdef DATUMREFCNT - free_nsp(nsp); -#endif - return (0); - } - } - - schedretry(qp, retrytime(qp)); - if (qp->q_fwd == NULL) - qp->q_addr[0].stime = tt; /* XXX - why not every? */ - 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, - ntohs(qp->q_nsid), ntohs(qp->q_id), - qp->q_time)); -#ifdef DEBUG - if (debug >= 10) - fp_query(qp->q_msg, ddt); -#endif - if (sendto(qp->q_dfd, 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)); - nameserIncr(nsa->sin_addr, nssSendtoErr); - } - nameserIncr(nsa->sin_addr, nssSentSysQ); -#ifdef DATUMREFCNT - free_nsp(nsp); -#endif - return (qp); -} - -/* - * Check the list of root servers after receiving a response - * to a query for the root servers. - */ -static void -check_root() -{ - register struct databuf *dp, *pdp; - register struct namebuf *np; - int count = 0; - - priming = 0; - for (np = hashtab->h_tab[0]; np != NULL; np = np->n_next) - if (np->n_dname[0] == '\0') - break; - if (np == NULL) { - syslog(LOG_ERR, "check_root: Can't find root!\n"); - return; - } - for (dp = np->n_data; dp != NULL; dp = dp->d_next) - if (dp->d_type == T_NS) - count++; - dprintf(1, (ddt, "%d root servers\n", count)); - if (count < MINROOTS) { - syslog(LOG_WARNING, - "check_root: %d root servers after query to root server < min", - count); - return; - } - pdp = NULL; - dp = np->n_data; - while (dp != NULL) { - if (dp->d_type == T_NS && dp->d_zone == 0 && - dp->d_ttl < tt.tv_sec) { - dprintf(1, (ddt, "deleting old root server '%s'\n", - dp->d_data)); - dp = rm_datum(dp, np, pdp); - /* SHOULD DELETE FROM HINTS ALSO */ - continue; - } - pdp = dp; - dp = dp->d_next; - } - check_ns(); -} - -/* - * Check the root to make sure that for each NS record we have a A RR - */ -static void -check_ns() -{ - register struct databuf *dp, *tdp; - register struct namebuf *np, *tnp; - struct hashbuf *htp; - char *dname; - int found_arr; - char *fname; - time_t curtime; - - dprintf(2, (ddt, "check_ns()\n")); - - curtime = (u_int32_t) tt.tv_sec; - for (np = hashtab->h_tab[0]; np != NULL; np = np->n_next) { - if (np->n_dname[0] != 0) - continue; - for (dp = np->n_data; dp != NULL; dp = dp->d_next) { - if (dp->d_type != T_NS) - continue; - - /* look for A records */ - dname = (caddr_t) dp->d_data; - htp = hashtab; - 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); - continue; - } - /* look for name server addresses */ - found_arr = 0; - for (tdp=tnp->n_data; tdp!=NULL; tdp=tdp->d_next) { - if (tdp->d_type != T_A || - tdp->d_class != dp->d_class) - continue; - if ((tdp->d_zone == 0) && - (tdp->d_ttl < curtime)) { - dprintf(3, (ddt, - "check_ns: stale entry '%s'\n", - tnp->n_dname)); - /* Cache invalidate the address RR's */ - delete_all(tnp, dp->d_class, T_A); - found_arr = 0; - break; - } - found_arr++; - } - if (!found_arr) - (void) sysquery(dname, dp->d_class, T_A, NULL, 0); - } - } -} - -/* int findns(npp, class, nsp, countp, flag) - * Find NS' or an SOA - * npp, class: - * dname whose least-superior NS is wanted - * nsp, countp: - * result array and count; array will also be NULL terminated - * flag: - * boolean: we're being called from ADDAUTH, bypass authority checks - * return value: - * NXDOMAIN: we are authoritative for this {dname,class} - * SERVFAIL: we are auth but zone isn't loaded; or, no root servers found - * OK: success (this is the only case where *countp and nsp[] are valid) - */ -int -findns(npp, class, nsp, countp, flag) - register struct namebuf **npp; - int class; - struct databuf **nsp; - int *countp; - int flag; -{ - register struct namebuf *np = *npp; - register struct databuf *dp; - register struct databuf **nspp; - struct hashbuf *htp; - -#ifdef DATUMREFCNT - nsp[0] = NULL; -#endif - - if (priming && (np == NULL || np->n_dname[0] == '\0')) - htp = fcachetab; - else - htp = hashtab; - -try_again: - if (htp == fcachetab) - needs_prime_cache = 1; - while (np == NULL && htp != NULL) { - dprintf(3, (ddt, "findns: using %s\n", - htp == hashtab ? "cache" : "hints")); - for (np = htp->h_tab[0]; np != NULL; np = np->n_next) - if (np->n_dname[0] == '\0') - break; - htp = (htp == hashtab ? fcachetab : NULL); /* Fallback */ - } - while (np != NULL) { - dprintf(5, (ddt, "findns: np 0x%x '%s'\n", 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)) { - dprintf(3, (ddt, "findns: SOA found\n")); - if (zones[dp->d_zone].z_flags & Z_AUTH) { - *npp = np; - nsp[0] = dp; -#ifdef DATUMREFCNT - nsp[1] = NULL; - dp->d_rcnt++; -#endif - return (NXDOMAIN); - } else { - /* XXX: zone isn't loaded but we're - * primary or secondary for it. - * should we fwd this? - */ - return (SERVFAIL); - } - } - } - - /* If no SOA records, look for NS records. */ - nspp = &nsp[0]; - *nspp = NULL; - for (dp = np->n_data; dp != NULL; dp = dp->d_next) { - if (!match(dp, class, T_NS)) - continue; - /* - * Don't use records that may become invalid to - * reference later when we do the rtt computation. - * Never delete our safety-belt information! - * - * XXX: this is horribly bogus. - */ - if ((dp->d_zone == 0) && - (dp->d_ttl < (tt.tv_sec+900)) && - !(dp->d_flags & DB_F_HINT)) { - dprintf(1, (ddt, "findns: stale entry '%s'\n", - np->n_dname)); - /* Cache invalidate the NS RR's. */ - if (dp->d_ttl < tt.tv_sec) - delete_all(np, class, T_NS); - goto try_parent; - } - if (nspp < &nsp[NSMAX-1]) { - *nspp++ = dp; -#ifdef DATUMREFCNT - dp->d_rcnt++; -#endif - } - } - - *countp = nspp - nsp; - if (*countp > 0) { - dprintf(3, (ddt, "findns: %d NS's added for '%s'\n", - *countp, np->n_dname)); - *nspp = NULL; - *npp = np; - return (OK); /* Success, got some NS's */ - } -try_parent: - np = np->n_parent; - } - if (htp) - goto try_again; - dprintf(1, (ddt, "findns: No root nameservers for class %s?\n", - p_class(class))); - if ((unsigned)class < MAXCLASS && norootlogged[class] == 0) { - norootlogged[class] = 1; - syslog(LOG_ERR, "No root nameservers for class %s\n", - p_class(class)); - } - return (SERVFAIL); -} - -/* - * Extract RR's from the given node that match class and type. - * Return number of bytes added to response. - * If no matching data is found, then 0 is returned. - */ -int -finddata(np, class, type, hp, dnamep, lenp, countp) - struct namebuf *np; - int class, type; - register HEADER *hp; - char **dnamep; - int *lenp, *countp; -{ - register struct databuf *dp; - register char *cp; - int buflen, n, count = 0, foundstale = 0; - -#ifdef ROUND_ROBIN - if (type != T_ANY && type != T_PTR) { - /* cycle order of RRs, for a load balancing effect... */ - - register struct databuf **dpp; - - for (dpp = &np->n_data; dp = *dpp; dpp = &dp->d_next) { - if (dp->d_next && wanted(dp, class, type)) { - register struct databuf *lp; - - *dpp = lp = dp->d_next; - dp->d_next = NULL; - - for (dpp = &lp->d_next; - *dpp; - dpp = &lp->d_next) - lp = *dpp; - *dpp = dp; - break; - } - } - } -#endif /*ROUND_ROBIN*/ - - buflen = *lenp; - cp = ((char *)hp) + *countp; - for (dp = np->n_data; dp != NULL; dp = dp->d_next) { - if (!wanted(dp, class, type)) { -#ifndef NCACHE /*if no negative caching then cname => nothing else*/ - if (type == T_CNAME && class == dp->d_class) { - /* any data means no CNAME exists */ - *countp = 0; - return 0; - } -#endif /*NCACHE*/ - continue; - } - if (stale(dp)) { - /* - * Don't use stale data. - * Would like to call delete_all here - * and continue, but the data chain would get - * munged; can't restart, as make_rr has side - * effects (leaving pointers in dnptr). - * Just skip this entry for now - * and call delete_all at the end. - */ - dprintf(3, (ddt, - "finddata: stale entry '%s'\n", - np->n_dname)); - if (dp->d_zone == 0) - foundstale++; - continue; - } - if (dp->d_cred == DB_C_ADDITIONAL) { - /* we want to expire additional data very - * quickly. current strategy is to cut 5% - * off each time it is accessed. this makes - * stale(dp) true faster when this datum is - * used often. - */ - dp->d_ttl = tt.tv_sec - + - 0.95 * (int) (dp->d_ttl - tt.tv_sec); - } -#ifdef NCACHE - /* -ve $ing stuff, anant@isi.edu - * if we have a -ve $ed record, change the rcode on the - * header to reflect that - */ - if (dp->d_rcode == NOERROR_NODATA) { - if (count != 0) { - /* - * This should not happen, yet it does... - */ - syslog(LOG_WARNING, - "NODATA & data for \"%s\" type %d class %d", - *dnamep, type, class); - continue; - } - if (type != T_ANY) { - hp->rcode = NOERROR_NODATA; - *countp = 0; - return 1; /* XXX - we have to report success */ - } - /* don't satisfy T_ANY queries from -$ info */ - continue; - } -#ifndef RETURNSOA - if (dp->d_rcode == NXDOMAIN) { - if (count != 0) { - /* - * This should not happen, yet it might... - */ - syslog(LOG_WARNING, - "NXDOMAIN & data for \"%s\" type %d class %d", - *dnamep, type, class); - continue; - } - if (type != T_ANY) { - hp->rcode = NXDOMAIN; - *countp = 0; - return 1; /* XXX - we have to report success */ - } - /* don't satisfy T_ANY queries from -$ info */ - continue; - } -#endif -#endif /*NCACHE*/ - - if ((n = make_rr(*dnamep, dp, (u_char *)cp, buflen, 1)) < 0) { - hp->tc = 1; - *countp = count; - return (*lenp - buflen); - } - - cp += n; - buflen -= n; - count++; -#ifdef notdef - /* this isn't right for glue records, aa is set in ns_req */ - if (dp->d_zone && - (zones[dp->d_zone].z_flags & Z_AUTH) && - class != C_ANY) - hp->aa = 1; /* XXX */ -#endif - if (dp->d_type == T_CNAME) { - if (type != T_ANY) { /* or T_NS? */ - *dnamep = (caddr_t) dp->d_data; - if (dp->d_zone && - (zones[dp->d_zone].z_flags & Z_AUTH) && - class != C_ANY) /* XXX */ - hp->aa = 1; /* XXX */ - } - break; - } - } - /* - * Cache invalidate the other RR's of same type - * if some have timed out - */ - if (foundstale) { - delete_all(np, class, type); - /* XXX this isn't right if 'type' is something special - * such as T_AXFR or T_MAILB, since the matching done - * by match() in delete_all() is different from that - * done by wanted() above. - */ - } - dprintf(3, (ddt, "finddata: added %d class %d type %d RRs\n", - count, class, type)); - *countp = count; - return (*lenp - buflen); -} - -/* - * Do we want this data record based on the class and type? - */ -int -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)); - - if (dp->d_class != class && class != C_ANY) - return (0); - if (type == dp->d_type) - return (1); -#ifdef NCACHE - /*-ve $ing stuff, for a T_ANY query, we do not want to return - * -ve $ed RRs. - */ - if (type == T_ANY && dp->d_rcode == NOERROR_NODATA) - return (0); -#endif - - switch (dp->d_type) { - case T_ANY: - return (1); - case T_CNAME: -#ifdef NCACHE - if (dp->d_rcode != NOERROR_NODATA) -#endif - return (1); -#ifdef NCACHE - else - break; -#endif - } - switch (type) { - case T_ANY: - return (1); - - case T_MAILB: - switch (dp->d_type) { - case T_MR: - case T_MB: - case T_MG: - case T_MINFO: - return (1); - } - break; - - case T_AXFR: - /* T_AXFR needs an authoritative SOA */ - if (dp->d_type == T_SOA && dp->d_zone != 0 - && (zones[dp->d_zone].z_flags & Z_AUTH)) - return (1); - break; - } - return (0); -} - -/* - * Add RR entries from dpp array to a query/response. - * Return the number of bytes added or negative the amount - * added if truncation was required. Typically you are - * adding NS records to a response. - */ -int -add_data(np, dpp, cp, buflen) - struct namebuf *np; - struct databuf **dpp; - register u_char *cp; - int buflen; -{ - register struct databuf *dp; - char dname[MAXDNAME]; - register int n, count = 0; - - getname(np, dname, sizeof(dname)); - for(dp = *dpp++; dp != NULL; dp = *dpp++) { - if (stale(dp)) - continue; /* ignore old cache entry */ -#ifdef NCACHE - if (dp->d_rcode) - continue; -#endif - if ((n = make_rr(dname, dp, cp, buflen, 1)) < 0) - return (-count); /* Truncation */ - cp += n; - buflen -= n; - count += n; - } - return (count); -} - -/* - * This is best thought of as a "cache invalidate" function. - * It is called whenever a piece of data is determined to have - * timed out. It is better to have no information, than to - * have partial information you pass off as complete. - */ -void -delete_all(np, class, type) - register struct namebuf *np; - int 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)); - pdp = NULL; - dp = np->n_data; - while (dp != NULL) { - if ((dp->d_zone == 0) && !(dp->d_flags & DB_F_HINT) - && match(dp, class, type)) { - dp = rm_datum(dp, np, pdp); - continue; - } - pdp = dp; - dp = dp->d_next; - } -} diff --git a/usr.sbin/named/ns_sort.c b/usr.sbin/named/ns_sort.c deleted file mode 100644 index c35b58f16ae4..000000000000 --- a/usr.sbin/named/ns_sort.c +++ /dev/null @@ -1,169 +0,0 @@ -#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 4.9.1.6 1994/07/23 23:23:56 vixie Exp $"; -#endif /* not lint */ - -/* - * ++Copyright++ 1986, 1990 - * - - * Copyright (c) 1986, 1990 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - - * Portions Copyright (c) 1993 by Digital Equipment Corporation. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies, and that - * the name of Digital Equipment Corporation not be used in advertising or - * publicity pertaining to distribution of the document or software without - * specific, written prior permission. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT - * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - * - - * --Copyright-- - */ - -#include <sys/param.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/file.h> -#include <netinet/in.h> -#include <arpa/nameser.h> -#include <arpa/inet.h> -#include <stdio.h> -#include <syslog.h> -#include <resolv.h> - -#include "named.h" - -static int sort_rr __P((u_char *cp, int count, struct netinfo *ntp, u_char *eom)); - -struct netinfo * -local(from) - struct sockaddr_in *from; -{ - struct netinfo *ntp; - - if (from->sin_addr.s_addr == netloop.my_addr.s_addr) - return (&netloop); - for (ntp = nettab; ntp != *enettab; ntp = ntp->next) { - if (ntp->addr == (from->sin_addr.s_addr & ntp->mask)) - return (ntp); - } - return (NULL); -} - -void -sort_response(cp, ancount, lp, eom) - register u_char *cp; - register int ancount; - struct netinfo *lp; - u_char *eom; -{ - register struct netinfo *ntp; - - dprintf(3, (ddt, "sort_response(%d)\n", ancount)); - if (ancount > 1) { - if (sort_rr(cp, ancount, lp, eom)) - return; - for (ntp = nettab; ntp != NULL; ntp = ntp->next) { - if ((ntp->addr == lp->addr) && (ntp->mask == lp->mask)) - continue; - if (sort_rr(cp, ancount, ntp, eom)) - break; - } - } -} - -static int -sort_rr(cp, count, ntp, eom) - register u_char *cp; - int count; - register struct netinfo *ntp; - u_char *eom; -{ - int type, class, dlen, n, c; - struct in_addr inaddr; - u_char *rr1; - -#ifdef DEBUG - if (debug > 2) { - inaddr.s_addr = ntp->addr; - fprintf(ddt, "sort_rr(x%x, %d, [%s])\n", - cp, count, inet_ntoa(inaddr)); - } -#endif - rr1 = NULL; - for (c = count; c > 0; --c) { - n = dn_skipname(cp, eom); - if (n < 0) - return (1); /* bogus, stop processing */ - cp += n; - if (cp + QFIXEDSZ > eom) - return (1); - GETSHORT(type, cp); - GETSHORT(class, cp); - cp += INT32SZ; - GETSHORT(dlen, cp); - if (dlen > eom - cp) - return (1); /* bogus, stop processing */ - switch (type) { - case T_A: - switch (class) { - case C_IN: - case C_HS: - bcopy(cp, (char *)&inaddr, INADDRSZ); - if (rr1 == NULL) - rr1 = cp; - if ((ntp->mask & inaddr.s_addr) == ntp->addr) { - dprintf(2, (ddt,"net [%s] best choice\n", - inet_ntoa(inaddr))); - if (rr1 != cp) { - bcopy(rr1, cp, INADDRSZ); - bcopy((char *)&inaddr, rr1, INADDRSZ); - } - return (1); - } - break; - } - break; - } - cp += dlen; - } - return (0); -} diff --git a/usr.sbin/named/ns_stats.c b/usr.sbin/named/ns_stats.c deleted file mode 100644 index d6d6225b6210..000000000000 --- a/usr.sbin/named/ns_stats.c +++ /dev/null @@ -1,325 +0,0 @@ -#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 4.9.1.7 1994/06/06 09:08:15 vixie Exp $"; -#endif /* not lint */ - -/* - * ++Copyright++ 1986 - * - - * Copyright (c) 1986 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - - * Portions Copyright (c) 1993 by Digital Equipment Corporation. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies, and that - * the name of Digital Equipment Corporation not be used in advertising or - * publicity pertaining to distribution of the document or software without - * specific, written prior permission. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT - * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - * - - * --Copyright-- - */ - -/**************************************************************************/ -/* simple monitoring of named behavior */ -/* dumps a bunch of values into a well-known file */ -/**************************************************************************/ - -#include <sys/param.h> -#include <netinet/in.h> -#include <arpa/nameser.h> -#include <stdio.h> -#include <syslog.h> -#include <errno.h> - -#include "named.h" -#include "tree.h" - -static u_long typestats[T_ANY+1]; -static const char *typenames[T_ANY+1] = { - /* 5 types per line */ - "Unknown", "A", "NS", "invalid(MD)", "invalid(MF)", - "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, - /* 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, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - /* 100 */ - "UINFO", "UID", "GID", "UNSPEC", 0, 0, 0, 0, 0, 0, - /* 110 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - /* 120 */ - 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, - 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, - /* 200 */ - 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, - /* 240 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - /* 250 */ - 0, 0, "AXFR", "MAILB", "MAILA", "ANY" -}; - -static void nameserStats __P((FILE *)); - -void -ns_stats() -{ - time_t timenow; - register FILE *f; - register int i; - - 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); - 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); - -#ifdef DMALLOC - /* malloc statistics */ - dmallocstats(f); -#endif - - /* query type statistics */ - fprintf(f, "%d\tUnknown query types\n", 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]); - else - fprintf(f, "%lu\ttype %d queries\n", - typestats[i], i); - - /* name server statistics */ - nameserStats(f); - - fprintf(f, "--- Statistics Dump --- (%ld) %s", - (long)timenow, ctime(&timenow)); - (void) my_fclose(f); -} - -void -qtypeIncr(qtype) - int qtype; -{ - if (qtype < T_A || qtype > T_ANY) - qtype = 0; /* bad type */ - typestats[qtype]++; -} - -static tree *nameserTree; -static int nameserInit; - -#ifdef STATS -static FILE *nameserStatsFile; -static u_long globalStats[nssLast]; -static const char *statNames[nssLast] = { - "RQ", /* sent us a query */ - "RR", /* sent us an answer */ - "RIQ", /* sent us an inverse query */ - "RNXD", /* sent us a negative response */ - "RFwdQ", /* sent us a query we had to fwd */ - "RFwdR", /* sent us a response we had to fwd */ - "RDupQ", /* sent us a retry */ - "RDupR", /* sent us an extra answer */ - "RFail", /* sent us a SERVFAIL */ - "RFErr", /* sent us a FORMERR */ - "RErr", /* sent us some other error */ - "RTCP", /* sent us a query using TCP */ - "RAXFR", /* sent us an AXFR */ - "RLame", /* sent us a lame delegation */ - "ROpts", /* sent us some IP options */ - "SSysQ", /* sent them a sysquery */ - "SAns", /* sent them an answer */ - "SFwdQ", /* fwdd a query to them */ - "SFwdR", /* fwdd a response to them */ - "SDupQ", /* sent them a retry */ - "SFail", /* sent them a SERVFAIL */ - "SFErr", /* sent them a FORMERR */ - }; -#endif /*STATS*/ - -static int -nameserCompar(t1, t2) - const tree_t t1, t2; -{ - u_int32_t a1 = ntohl(((struct nameser *)t1)->addr.s_addr), - a2 = ntohl(((struct nameser *)t2)->addr.s_addr); - - if (a1 < a2) - return (-1); - else if (a1 > a2) - return (1); - else - return (0); -} - -struct nameser * -nameserFind(addr, flags) - struct in_addr addr; - int flags; -{ - struct nameser dummy; - struct nameser *ns; - - if (!nameserInit) { - tree_init(&nameserTree); - nameserInit++; - } - - dummy.addr = addr; - ns = (struct nameser *)tree_srch(&nameserTree, nameserCompar, - (tree_t)&dummy); - if (!ns && (flags & NS_F_INSERT)) { - ns = (struct nameser *)malloc(sizeof(struct nameser)); - if (!ns) { - nomem: if (!haveComplained("nameserFind complaint", "")) - syslog(LOG_NOTICE, - "nameserFind: malloc failed; %m"); - return (NULL); - } - memset(ns, 0, sizeof(struct nameser)); - ns->addr = addr; - if (!tree_add(&nameserTree, nameserCompar, (tree_t)ns, NULL)) { - int save = errno; - free(ns); - errno = save; - goto nomem; - } - } - return (ns); -} - - -void -nameserIncr(addr, which) - struct in_addr addr; - enum nameserStats which; -{ -#ifdef STATS - struct nameser *ns = nameserFind(addr, NS_F_INSERT); - - if ((int)which < (int)nssLast) { - if (ns) - ns->stats[(int)which]++; - globalStats[(int)which]++; - } else { - syslog(LOG_DEBUG, "nameserIncr([%d], %d): bad 'which'", - inet_ntoa(addr), (int)which); - } -#endif /*STATS*/ -} - -#ifdef STATS -static void -nameserStatsOut(f, stats) - FILE *f; - u_long stats[]; -{ - int i; - char *pre = "\t"; - - for (i = 0; i < (int)nssLast; i++) { - fprintf(f, "%s%u", pre, stats[i]); - pre = ((i+1) % 5) ? " " : " "; - } - fputc('\n', f); -} - -static void -nameserStatsHdr(f) - FILE *f; -{ - int i; - char *pre = "\t"; - - fprintf(f, "(Legend)\n"); - for (i = 0; i < (int)nssLast; i++) { - fprintf(f, "%s%s", pre, - statNames[i] ? statNames[i] : ""); - pre = ((i+1) % 5) ? "\t" : "\n\t"; - } - fputc('\n', f); -} - -static int -nameserStatsTravUAR(t) - tree_t t; -{ - struct nameser *ns = (struct nameser *)t; - - fprintf(nameserStatsFile, "[%s]\n", /* : rtt %u */ - inet_ntoa(ns->addr) /*, ns->rtt*/ ); - nameserStatsOut(nameserStatsFile, ns->stats); - return (1); -} -#endif /*STATS*/ - -static void -nameserStats(f) - FILE *f; -{ -#ifndef STATS - fprintf(f, "<<No nameserver statistics in this server>>\n"); -#else - nameserStatsFile = f; - fprintf(f, "++ Name Server Statistics ++\n"); - nameserStatsHdr(f); - fprintf(f, "(Global)\n"); - nameserStatsOut(f, globalStats); - tree_trav(&nameserTree, nameserStatsTravUAR); - fprintf(f, "-- Name Server Statistics --\n"); - nameserStatsFile = NULL; -#endif /*STATS*/ -} diff --git a/usr.sbin/named/ns_validate.c b/usr.sbin/named/ns_validate.c deleted file mode 100644 index f1236c542e10..000000000000 --- a/usr.sbin/named/ns_validate.c +++ /dev/null @@ -1,1161 +0,0 @@ -/************************************************************************** - * ns_validate.c (was security.c in original ISI contribution) - * author: anant kumar - * contributed: March 17, 1993 - * - * implements validation procedure for RR's received from a server as a - * response to a query. - */ - -#include <sys/param.h> -#include <sys/socket.h> -#include <sys/file.h> -#include <netinet/in.h> -#include <arpa/nameser.h> -#include <syslog.h> -#include <errno.h> -#include <stdio.h> -#include <resolv.h> - -#include "named.h" - -#ifdef VALIDATE - -static int isvalid __P((struct namebuf *, int, int, char *, int)), - check_addr_ns __P((struct databuf **, - struct sockaddr_in *, - char *)), - check_in_tables __P((struct databuf **, - struct sockaddr_in *, - char *)); -#if 0 -static void stick_in_queue __P((char *, int, int, char *)); -#endif - -static NAMEADDR nameaddrlist[MAXNAMECACHE]; -static int firstNA = 0, - lastNA = 0; - -static TO_Validate *validateQ, *currentVQ; -static int VQcount; - -/***************************************************************** - * validate() is called from dovalidate(). it takes as parameters, - * the domain name sought, the class, type etc. of record, the server - * that gave us the answer and the data it gave us - * - * it returns VALID if it is able to validate the record, INVALID if it cannot. - * furtehr VALID is split into VALID_CACHE if we need to cache this record - * since the domainname is not something we are authoritative for and - * VALID_NO_CACHE if the name is something we are authoritative for. - * - * 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) - * 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) - * =>the name does not exist in our database - * => data is bad: return INVALID - * if(data agrees with what we have) - * return VALID_NO_CACHE; - * else return INVALID; - * - * if(we are not authoritative) /findns() returned OK;/ - * if (address records for NS's found in cache){ - * if("server" = one of the addresses){ - * return VALID_CACHE; - * }else{ - * stick in queue of "to_validate" data; - * return (INVALID); - * } - * else return INVALID; - * - * This performs the validation procedure described above. Checks - * for the longest component of the dname that has a NS record - * associated with it. At any stage, if no data is found, it implies - * that the name is bad (has an unknown domain identifier) thus, we - * return INVALID. - * If address of one of these servers matches the address of the server - * that returned us this data, we are happy! - * - * since findns will set needs_prime_cache if np = NULL is passed, we always - * reset it. will let ns_req do it when we are searching for ns records to - * query someone. hence in all the three cases of switch(findns()) - * we have needs_prime_cache = 0; - *****************************************************************************/ -int -validate(dname, server, type, class, data, dlen -#ifdef NCACHE - ,rcode -#endif - ) - char *dname; - struct sockaddr_in *server; - int type; - int class; - char *data; - int dlen; -#ifdef NCACHE - int rcode; -#endif -{ - struct namebuf *np, *dnamep; - struct hashbuf *htp; - struct databuf *nsp[NSMAX]; - int count; - char *fname; - int exactmatch = 0; - struct fwdinfo *fwd; - -#ifdef DATUMREFCNT - nsp[0] = NULL; -#endif - dprintf(3, (ddt, - "validate(), d:%s, s:[%s], t:%d, c:%d\n", - dname, inet_ntoa(server->sin_addr), type, class)); - - /* 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); - } - - htp = hashtab; - if (priming && (dname[0] == '\0')) - np = NULL; - else - np = nlookup(dname, &htp, &fname, 0); - - /* we were able to locate namebufs for this domain, or a parent domain, - * or ??? */ - - if (np == NULL) { - fname = (char *)malloc(1); - fname[0] = '\0'; - } - dprintf(5, (ddt, - "validate:namebuf found np:0x%x, d:\"%s\", f:\"%s\"\n", - 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) { - free((char *)fname); - } - switch (findns(&np, class, nsp, &count, 0)) { - case NXDOMAIN: - /** we are authoritative for this domain, lookup name - * in our zone data, if it matches, return valid. - * in either case, do not cache - **/ - dprintf(5, (ddt, "validate: auth data found\n")); -#ifdef DATUMREFCNT - free_nsp(nsp); -#endif - if (needs_prime_cache) - needs_prime_cache = 0; - -#ifdef NCACHE - 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; - 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; - } -#endif - if (!strcasecmp(dname, np->n_dname)) { - - /* if the name we seek is the same as that we have ns - * records for, compare the data we have to see if it - * matches. if it does, return valid_no_cache, if it - * doesn't, invalid. - */ - if (isvalid(np, type, class, data, dlen)) - return VALID_NO_CACHE; - else - return INVALID; - } - - /* we found ns records in a higher level, if we were unable to - * locate the exact name earlier, it means we are - * authoritative for this domain but do not have records for - * this name. this name is obviously invalid - */ - if (!exactmatch) - 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; - else - return INVALID; - - case SERVFAIL:/* could not find name server records*/ - /* stick_in_queue(dname, type, class, data); */ - if (needs_prime_cache) - needs_prime_cache = 0; -#ifdef DATUMREFCNT - free_nsp(nsp); -#endif - return INVALID; - - case OK: /*proceed */ - dprintf(5, - (ddt, - "validate:found ns records:calling check_addr_ns\n")); - if (needs_prime_cache) - needs_prime_cache = 0; - if (check_addr_ns(nsp, server, dname)) { -#ifdef DATUMREFCNT - free_nsp(nsp); -#endif - 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; - default: -#ifdef DATUMREFCNT - free_nsp(nsp); -#endif - return INVALID; - } /*switch*/ - -} /*validate*/ - -/*********************************************************************** - * validate rr returned by somebody against your own database, if you are - * authoritative for the information. if you have a record that matches, - * return 1, else return 0. validate() above will use this and determine - * if the record should be returned/discarded. - ***********************************************************************/ -static int -isvalid(np, type, class, data, dlen) - struct namebuf *np; - int type, class; - char *data; - int dlen; -{ - register struct databuf *dp; - - for (dp = np->n_data; dp != NULL; dp = dp->d_next) { - if (!wanted(dp, class, type)) { - if ((type == T_CNAME) && (class == dp->d_class)) { - /* if a cname exists, any other will not */ - return(0); - /* we come here only for zone info, - * so -ve $ed info can't be - */ - } - continue; - } - /* type and class match, if i get here - * let's now compare the data section, per RR type - */ - - /* unless, of course, the data was negative, in which case - * we should return FAILURE since we should not have found - * data here. - */ - if ((data == NULL) || (dlen == 0)) { - return 0; - } - - /* XXX: why aren't we just calling db_cmp() ? - */ - - switch (type) { - char *td; - u_char *tdp; - int x; - - case T_A: - case T_WKS: - case T_HINFO: - case T_UINFO: - case T_UID: - case T_GID: - case T_TXT: - case T_X25: - case T_ISDN: -#ifdef ALLOW_T_UNSPEC - case T_UNSPEC: -#endif - x = memcmp(dp->d_data, data, dlen); - dprintf(3, (ddt, "type = %d, GOOD = %d\n", - type, x)); - if (x == 0) - return (1); - else - break; - - case T_CNAME: - case T_MB: - case T_MG: - case T_MR: - case T_NS: - case T_PTR: - x = strncasecmp((char *)dp->d_data, data, dlen); - dprintf(3, (ddt, "type = %d, GOOD = %d\n", - type, x)); - if (x == 0) - return (1); - else - break; - - case T_MINFO: - case T_SOA: - case T_RP: - /* compare first string */ - x = strncasecmp((char *)dp->d_data, data, - strlen(data) + 1); - if (x != 0) - break; - - /* move to second string */ - td = data + (strlen(data) + 1); - tdp = dp->d_data + - (strlen((char *)dp->d_data)+1); - - /* compare second string */ - x = strncasecmp(td, (char *)tdp, - strlen((char *)td+1)); - if (x != 0) - break; - - /* move beyond second string, to - * set of words in SOA. - * RP and MINFO stuff really - * ends here - */ - - td = td + strlen((char *)td) + 1; - tdp = tdp + strlen((char *)tdp) + 1; - if (type == T_SOA) { - x = memcmp(td, (char *)tdp, - 5*INT32SZ); - if (x != 0) - break; - } - - /* everything was equal, wow! - * so return a success - */ - return (1); - - case T_MX: - case T_AFSDB: - case T_RT: - x = memcmp(dp->d_data, data, - INT16SZ); - if (x != 0) - break; - td = data + INT16SZ; - tdp = dp->d_data + INT16SZ; - 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); - } - /* continue in loop if record did not match */ - } - /* saw no record of interest in whole chain - * If the data we were trying to validate was negative, we succeeded! - * else we failed - */ - if ((data == NULL) || (dlen == 0)) { - /* negative data, report success */ - return 1; - } - /* positive data, no such RR, validation failed */ - return (0); -} - -/****************************************************************** - * get a list of databufs that have ns addresses for the closest domain - * you know about, get their addresses and confirm that server indeed - * is one of them. if yes return 1 else 0. - * first checks the cache that we build in nslookup() earlier - * when we ns_forw(). if unableto find it there, it checks the entire - * hash table to do address translations. - *******************************************************************/ -static int -check_addr_ns(nsp, server, dname) - struct databuf **nsp; - struct sockaddr_in *server; - char *dname; -{ - int i, found=0; - char sname[MAXDNAME]; - struct in_addr *saddr = &(server->sin_addr); - struct databuf **nsdp; - - dprintf(5, (ddt, - "check_addr_ns: s:[%s], db:0x%x, d:\"%s\"\n", - inet_ntoa(*saddr), nsp, dname)); - - for(i = lastNA; i != firstNA; i = (i+1) % MAXNAMECACHE) { - if (!bcmp((char *)saddr, - (char *)&(nameaddrlist[i].ns_addr), - INADDRSZ)) { - strcpy(sname, nameaddrlist[i].nsname); - found = 1; - break; - } - } - if (found) { - dprintf(3, (ddt, - "check_addr_ns: found address:[%s]\n", - inet_ntoa(*saddr))); - for (nsdp = nsp; *nsdp != NULL;nsdp++) { - dprintf(5, (ddt, - "check_addr_ns:names are:%s, %s\n", - sname,(*nsdp)->d_data)); - if (!strcasecmp(sname,(char *)((*nsdp)->d_data))) { - return (1); - } - } - } - /* could not find name in my cache of servers, must go through the - * whole grind - */ - - dprintf(2, (ddt, "check_addr_ns:calling check_in_tables()\n")); - return (check_in_tables(nsp, server, dname)); -} - -/************************************************************************* - * checks in hash tables for the address of servers whose name is in the - * data section of nsp records. borrows code from nslookup()/ns_forw.c - * largely. - *************************************************************************/ -static int -check_in_tables(nsp, server, syslogdname) - struct databuf *nsp[]; - struct sockaddr_in *server; - char *syslogdname; -{ - register struct namebuf *np; - register struct databuf *dp, *nsdp; - struct hashbuf *tmphtp; - char *dname, *fname; - int class; - int qcomp(); - - dprintf(3, (ddt, "check_in_tables(nsp=x%x,qp=x%x,'%s')\n", - nsp, server, syslogdname)); - - while ((nsdp = *nsp++) != NULL) { - class = nsdp->d_class; - dname = (char *)nsdp->d_data; - dprintf(3, (ddt, "check_in_tables: NS %s c%d t%d (x%x)\n", - dname, class, nsdp->d_type, nsdp->d_flags)); - 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)); - continue; - } - /* look for name server addresses */ - for (dp = np->n_data; dp != NULL; dp = dp->d_next) { - if (stale(dp)) - continue; - if (dp->d_type != T_A || dp->d_class != class) - continue; -#ifdef NCACHE - if (dp->d_rcode) - continue; -#endif - if (!bcmp((char *)dp->d_data, - (char *)&(server->sin_addr), - INADDRSZ)) { - return (1); - } - } - } - return (0); /* haven't been able to locate the right address */ -} - -/************************************************************************ - * is called in nslookup() and stores the name vs address of a name server - * --& check_in_tables above-- - * we contact, in a list of a maximum MAXNAMECACHE entries. we later refer - * -- NAMEADDR nameaddrlist[MAXNAMECACHE]; -- - * to this list when we are trying to resolve the name in check_addr_ns(). - *************************************************************************/ -void -store_name_addr(servername, serveraddr, syslogdname, sysloginfo) - char *servername; - struct in_addr *serveraddr; - char *syslogdname; - char *sysloginfo; -{ - int i; - - dprintf(3, (ddt, - "store_name_addr:s:%s, a:[%s]\n", - 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 - == - 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))); - return; - } /* if */ - } else if (serveraddr->s_addr - == - nameaddrlist[i].ns_addr.s_addr) { -#ifdef BAD_IDEA - /* - * log this as it needs to be fixed. - * 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)) - ) - ) { - syslog(LOG_INFO, - "%s: server name mismatch for [%s]: (%s != %s) (server for %s)", - sysloginfo, - inet_ntoa(*serveraddr), - nameaddrlist[i].nsname, servername, - syslogdname); - } -#endif - free(nameaddrlist[i].nsname); - nameaddrlist[i].nsname = - (char *)malloc((unsigned)strlen(servername)+1); - strcpy(nameaddrlist[i].nsname, servername); - return; - } - } - /* we have to add this one to our cache */ - - nameaddrlist[firstNA].nsname = - (char *)malloc((unsigned)strlen(servername)+1); - strcpy(nameaddrlist[firstNA].nsname, servername); - bcopy((char *)serveraddr, - (char *)&(nameaddrlist[firstNA].ns_addr), - INADDRSZ); - - dprintf(2, (ddt, "store_name_addr:added entry #:%d n:%s a:[%s]\n", - firstNA, nameaddrlist[firstNA].nsname, - inet_ntoa(nameaddrlist[firstNA].ns_addr))); - - firstNA = (firstNA+1) % MAXNAMECACHE; - if (firstNA == lastNA) { - free(nameaddrlist[firstNA].nsname); - nameaddrlist[firstNA].nsname = 0; - lastNA = (lastNA+1) % MAXNAMECACHE; - } - return; -} - -/* - * Decode the resource record 'rrp' and validate the RR. - * Borrows code almost entirely from doupdate(). is a rather - * non-invasive routine since it just goes thru the same motions - * as doupdate but just marks the array validatelist entry as - * the return code from validate(). This is later used in doupdate - * to cache/not cache the entry. also used in update_msg() to - * delete/keep the record from the outgoing message. - */ -int -dovalidate(msg, msglen, rrp, zone, flags, server, VCode) - u_char *msg, *rrp; - int msglen, zone, flags; - struct sockaddr_in *server; - int *VCode; -{ - register u_char *cp; - register int n; - int class, type, dlen, n1; - u_int32_t ttl; - char dname[MAXDNAME]; - u_char *cp1; - u_char data[BUFSIZ]; - register HEADER *hp = (HEADER *) msg; - - dprintf(2, (ddt, "dovalidate(zone %d, flags %x)\n", - zone, flags)); -#ifdef DEBUG - if (debug >= 10) - fp_query(msg, ddt); -#endif - - cp = rrp; - n = dn_expand(msg, msg + msglen, cp, dname, sizeof dname); - if (n < 0) { - hp->rcode = FORMERR; - return (-1); - } - cp += n; - GETSHORT(type, cp); - GETSHORT(class, cp); - GETLONG(ttl, cp); - GETSHORT(dlen, cp); - dprintf(2, (ddt, "dovalidate: dname %s type %d class %d ttl %d\n", - dname, type, class, ttl)); - /* - * Convert the resource record data into the internal - * database format. - */ - switch (type) { - case T_A: - case T_WKS: - case T_HINFO: - case T_UINFO: - case T_UID: - case T_GID: - case T_TXT: - case T_X25: - case T_ISDN: -#ifdef ALLOW_T_UNSPEC - case T_UNSPEC: -#endif - cp1 = cp; - n = dlen; - cp += n; - break; - - case T_CNAME: - case T_MB: - case T_MG: - case T_MR: - case T_NS: - case T_PTR: - n = dn_expand(msg, msg + msglen, cp, - (char *)data, sizeof data); - if (n < 0) { - hp->rcode = FORMERR; - return (-1); - } - cp += n; - cp1 = data; - n = strlen((char *)data) + 1; - break; - - case T_MINFO: - case T_SOA: - case T_RP: - n = dn_expand(msg, msg + msglen, cp, - (char *)data, sizeof data); - if (n < 0) { - hp->rcode = FORMERR; - return (-1); - } - cp += n; - cp1 = data + (n = strlen((char *)data) + 1); - n1 = sizeof(data) - n; - if (type == T_SOA) - n1 -= 5 * INT32SZ; - 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; - if (type == T_SOA) { - bcopy((char *)cp, (char *)cp1, n = 5 * INT32SZ); - cp += n; - cp1 += n; - } - n = cp1 - data; - cp1 = data; - break; - - case T_MX: - case T_AFSDB: - case T_RT: - /* grab preference */ - bcopy((char *)cp, data, INT16SZ); - cp1 = data + INT16SZ; - cp += INT16SZ; - - /* get name */ - n = dn_expand(msg, msg + msglen, cp, - (char *)cp1, sizeof(data) - INT16SZ); - if (n < 0) { - hp->rcode = FORMERR; - return(-1); - } - cp += n; - - /* compute end of data */ - cp1 += strlen((char *)cp1) + 1; - /* compute size of data */ - n = cp1 - data; - cp1 = data; - break; - - default: - dprintf(3, (ddt, "unknown type %d\n", type)); - return ((cp - rrp) + dlen); - } - if (n > MAXDATA) { - dprintf(2, (ddt, - "update type %d: %d bytes is too much data\n", - type, n)); - hp->rcode = NOCHANGE; /* XXX - FORMERR ??? */ - return(-1); - } - - *VCode = validate(dname, server, type, class,(char *)cp1, n -#ifdef NCACHE - ,NOERROR -#endif - ); - if (*VCode == INVALID) { - dprintf(2, (ddt, - "validation failed d:%s, t:%d, c:%d\n", - dname, type, class)); - } else { - dprintf(2, (ddt, - "validation succeeded d:%s, t:%d, c:%d\n", - dname, type, class)); - } - return(cp -rrp); -} - -#if 0 -/****************************************************************** - * This manages a data structure that stores all RRs that we were - * unable to validate. Am not sure exactly what purpose this might - * serve but until such time as we are sure it will not help, let - * me do it anyway. - *****************************************************************/ -static void -stick_in_queue(dname, type, class, data) - char *dname; - int type; - int class; - char *data; -{ - struct timeval tp; - struct _TIMEZONE tzp; - TO_Validate *tempVQ; - u_long leasttime; - - if (validateQ == NULL) { - validateQ = (TO_Validate *)malloc(sizeof(TO_Validate)); - validateQ->type = type; - validateQ->class = class; - validateQ->dname = malloc((unsigned)strlen(dname)+1); - strcpy(validateQ->dname, dname); - validateQ->data = malloc((unsigned)strlen(data)+1); - strcpy(validateQ->data, data); - gettimeofday(&tp, &tzp); - validateQ->time = tp.tv_sec; - VQcount = 1; - validateQ->next = validateQ->prev = NULL; - currentVQ = validateQ; - return; - } - if (VQcount < MAXVQ) { - tempVQ =(TO_Validate *)malloc(sizeof(TO_Validate)); - tempVQ->type = type; - tempVQ->class = class; - tempVQ->dname = malloc((unsigned)strlen(dname)+1); - strcpy(tempVQ->dname, dname); - tempVQ->data = malloc((unsigned)strlen(data)+1); - strcpy(tempVQ->data, data); - gettimeofday(&tp,&tzp); - tempVQ->time = tp.tv_sec; - tempVQ->next = currentVQ->next; - tempVQ->prev = currentVQ; - if (currentVQ->next != NULL) - currentVQ->next->prev = tempVQ; - currentVQ->next = tempVQ; - currentVQ = tempVQ; - VQcount++; - return; - } - gettimeofday(&tp, &tzp); - leasttime = validateQ->time; - currentVQ = validateQ; - for (tempVQ = validateQ; tempVQ != NULL; tempVQ = tempVQ->next) { - if (tp.tv_sec >= tempVQ->time +VQEXPIRY) { - tempVQ->type = type; - tempVQ->class = class; - strcpy(tempVQ->dname, dname); - strcpy(tempVQ->data, data); - tempVQ->time = tp.tv_sec; - currentVQ = tempVQ; - return; - } - if (tempVQ->time < leasttime) { - leasttime = tempVQ->time; - currentVQ = tempVQ; - } - } - currentVQ->type = type; - currentVQ->class = class; - strcpy(currentVQ->dname, dname); - strcpy(currentVQ->data, data); - currentVQ->time = tp.tv_sec; - return; -} -#endif - -/* removes any INVALID RR's from the msg being returned, updates msglen to - * reflect the new message length. - */ -int -update_msg(msg, msglen, Vlist, c) - u_char *msg; - int *msglen; - int Vlist[]; - int c; -{ - register HEADER *hp; - register u_char *cp; - int i; - int n = 0; - u_char *tempcp, *newcp; - int *RRlen; - int qlen; /* the length of the query section*/ - u_int16_t rdlength; - u_int16_t ancount, nscount; - u_int16_t new_ancount, new_nscount, new_arcount; - char dname[MAXDNAME], qname[MAXDNAME]; - u_char data[MAXDNAME]; - u_char **dpp; - u_char *dnptrs[40]; - u_char **edp = dnptrs + sizeof(dnptrs)/sizeof(dnptrs[0]); - u_char *eom = msg + *msglen; - int n_new; - int rembuflen, newlen; - u_char *newmsg; - u_int16_t type, class, dlen; - u_int32_t ttl; - int inv = 0; - -#ifdef DEBUG - if (debug) { - fprintf(ddt, "update_msg: msglen:%d, c:%d\n", *msglen, c); - if (debug >= 10) - fp_query(msg, ddt); - } -#endif - /* just making sure we do not do all the work for nothing */ - for (i=0; i<c; i++) { - if (Vlist[i] == INVALID) { - inv = 1; - break; - } - } - if (inv != 1) { - /* no invalid records, go about your job */ - return (0); - } - - dprintf(2, (ddt, "update_msg: NEEDS updating:\n")); - - RRlen = (int *)malloc((unsigned)c*sizeof(int)); - hp = (HEADER *)msg; - new_ancount = ancount = ntohs(hp->ancount); - new_nscount = nscount = ntohs(hp->nscount); - new_arcount = ntohs(hp->arcount); - - cp = msg + HFIXEDSZ; - newlen = HFIXEDSZ; - /* skip the query section */ - qlen = dn_expand(msg, eom, cp, qname, sizeof qname); - if (qlen <= 0) { - dprintf(2, (ddt, "dn_skipname() failed, bad record\n")); - goto badend; - } - cp +=qlen; - GETSHORT(type,cp); - GETSHORT(class,cp); - qlen += 2 * INT16SZ; - newlen += qlen; - - for (i = 0; i < c; i++) { - if (Vlist[i] == INVALID) { - if (i < ancount) - new_ancount--; - else if (i < ancount+nscount) - new_nscount--; - else - new_arcount--; - } - - RRlen[i] = dn_skipname(cp, msg + *msglen); - if (RRlen[i] <= 0) { - dprintf(2, (ddt, - "dn_skipname() failed, bad record\n")); - goto badend; - } - RRlen[i] += 2 * INT16SZ + INT32SZ; - /*type+class+TTL*/ - cp += RRlen[i]; - GETSHORT(rdlength, cp); - RRlen[i] += INT16SZ; /*rdlength*/ - RRlen[i] += rdlength; /*rdata field*/ - dprintf(3, (ddt, "RRlen[%d]=%d\n", i, RRlen[i])); - if (Vlist[i] != INVALID) - newlen += RRlen[i]; - cp += rdlength; /*increment pointer to next RR*/ - } - hp->ancount = htons(new_ancount); - hp->nscount = htons(new_nscount); - hp->arcount = htons(new_arcount); - /* get new buffer */ - dprintf(3, (ddt, - "newlen:%d, if no RR is INVALID == msglen\n", newlen)); - newmsg = (u_char *)calloc(1,newlen + MAXDNAME); - if(newmsg == NULL) - goto badend; - dpp = dnptrs; - *dpp++ = newmsg; - *dpp = NULL; - /* bcopy the header, with all the length fields correctly put in */ - bcopy((char *)msg, (char*)newmsg, HFIXEDSZ); /*header copied */ - newcp = newmsg +HFIXEDSZ; /*need a pointer in the new buffer */ - rembuflen = newlen +MAXDNAME - HFIXEDSZ; /*buflen we can workin*/ - newlen = HFIXEDSZ; /* this will now contain the length of msg */ - n_new = dn_comp(qname, newcp, rembuflen, dnptrs, edp); - if (n_new < 0) - goto badend; - newcp += n_new; - PUTSHORT(type, newcp); - PUTSHORT(class, newcp); /*query section complete*/ - newlen += (n_new+2*INT16SZ); - rembuflen -= (n_new+2*INT16SZ); - /* have to decode and copy every Valid RR from here */ - - cp = msg +HFIXEDSZ +qlen; /*skip header and query section*/ - for (i = 0; i < c; i++) { - if (Vlist[i] == INVALID) { - /* go to next RR if this one is not INVALID */ - cp += RRlen[i]; - continue; - } - /* we have a valid record, must put it in the newmsg */ - n = dn_expand(msg, eom, cp, dname, sizeof dname); - if (n < 0) { - hp->rcode = FORMERR; - goto badend; - } - n_new = dn_comp(dname, newcp, rembuflen, dnptrs, edp); - if (n_new < 0) - goto badend; - cp += n; - newcp += n_new; - dprintf(5, (ddt, - "cp:0x%x newcp:0x%x after getting name\n", - cp, newcp)); - GETSHORT(type, cp); - PUTSHORT(type, newcp); - dprintf(5, (ddt, - "cp:0x%x newcp:0x%x after getting type\n", - cp, newcp)); - GETSHORT(class, cp); - PUTSHORT(class, newcp); - dprintf(5, (ddt, - "cp:0x%x newcp:0x%x after getting class\n", - cp, newcp)); - GETLONG(ttl, cp); - PUTLONG(ttl, newcp); - dprintf(5, (ddt, - "cp:0x%x newcp:0x%x after getting ttl\n", - cp, newcp)); - /* this will probably be modified for newmsg, - * will put this in later, after compression - */ - GETSHORT(dlen, cp); - newlen += (n_new+3*INT16SZ + INT32SZ); - rembuflen -= (n_new+3*INT16SZ+ INT32SZ); - tempcp = newcp; - newcp += INT16SZ; /*advance to rdata field*/ - dprintf(5, (ddt, "tempcp:0x%x newcp:0x%x\n", - tempcp, newcp)); - dprintf(3, (ddt, - "update_msg: dname %s type %d class %d ttl %d\n", - dname, type, class, ttl)); - /* read off the data section */ - switch (type) { - case T_A: - case T_WKS: - case T_HINFO: - case T_UINFO: - case T_UID: - case T_GID: - case T_TXT: - case T_X25: - case T_ISDN: -#ifdef ALLOW_T_UNSPEC - case T_UNSPEC: -#endif - n = dlen; - PUTSHORT(n, tempcp); /*time to put in the dlen*/ - bcopy(cp, newcp,n); /*done here*/ - cp +=n; - newcp +=n; - newlen += n; - rembuflen -= n; - dprintf(3, (ddt, "\tcp:0x%x newcp:0x%x dlen:%d\n", - cp, newcp, dlen)); - break; - - case T_CNAME: - case T_MB: - case T_MG: - case T_MR: - case T_NS: - case T_PTR: - /*read off name from data section */ - n = dn_expand(msg, eom, cp, - (char *)data, sizeof data); - if (n < 0) { - hp->rcode = FORMERR; - goto badend; - } - cp += n; /*advance pointer*/ - /* fill in new packet */ - n_new = dn_comp((char *)data, newcp, rembuflen, - dnptrs, edp); - if (n_new < 0) - goto badend; - PUTSHORT(n_new,tempcp); /*put in dlen field*/ - newcp += n_new; /*advance new pointer*/ - newlen += n_new; - rembuflen -= n_new; - break; - - case T_MINFO: - case T_SOA: - case T_RP: - 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; - 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; - if (type == T_SOA) { - bcopy(cp, newcp, n = 5*INT32SZ); - cp += n; - newcp += n; - newlen +=n; - rembuflen -= n; - dlen +=n; - } - PUTSHORT(dlen, tempcp); - break; - - case T_MX: - case T_AFSDB: - case T_RT: - /* grab preference */ - bcopy(cp,newcp,INT16SZ); - cp += INT16SZ; - newcp += INT16SZ; - - /* get 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; - PUTSHORT(n_new+INT16SZ, tempcp); - newcp += n_new; - newlen += n_new+INT16SZ; - rembuflen -= n_new+INT16SZ; - break; - - default: - dprintf(3, (ddt, "unknown type %d\n", type)); - goto badend; - } - dprintf(2, (ddt, - "newlen:%d, i:%d newcp:0x%x cp:0x%x\n\n", - newlen, i, newcp, cp)); - } - bcopy(newmsg, msg, newlen); - n = *msglen - newlen; - if (n < 0) { - dprintf(2, (ddt, - "update_msg():newmsg longer than old: n:%d o:%d ???\n", - newlen, *msglen)); - } - *msglen = newlen; - free((char *)newmsg); - -#ifdef DEBUG - if (debug >= 10) - fp_query(msg, ddt); -#endif - free((char *)RRlen); - return(n); -badend: - dprintf(2, (ddt, "encountered problems: UPDATE_MSG\n")); - free((char *)RRlen); - return(-1); -} - -#endif /*VALIDATE*/ diff --git a/usr.sbin/named/pathnames.h b/usr.sbin/named/pathnames.h deleted file mode 100644 index bcbe642cb4a3..000000000000 --- a/usr.sbin/named/pathnames.h +++ /dev/null @@ -1,122 +0,0 @@ -/* - * @(#)pathnames.h 5.4 (Berkeley) 6/1/90 - * $Id: pathnames.h,v 4.9.1.5 1994/04/09 03:43:17 vixie Exp $ - */ - -/* - * ++Copyright++ 1989 - * - - * Copyright (c) 1989 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - - * Portions Copyright (c) 1993 by Digital Equipment Corporation. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies, and that - * the name of Digital Equipment Corporation not be used in advertising or - * publicity pertaining to distribution of the document or software without - * specific, written prior permission. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT - * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - * - - * --Copyright-- - */ - -#ifdef _PATH_XFER -# define _PATH_XFER_PREDEFINED /* probably from Makefile */ -#endif - -#if defined (__sgi) && !defined(_SYSTYPE_SVR4) && !defined(__SYSTYPE_SVR4) -#define _PATH_BOOT "/usr/etc/named.d/named.boot" -#else -#define _PATH_BOOT "/etc/named.boot" -#endif - -#if defined(BSD) && BSD >= 198810 - -#include <paths.h> -#ifndef _PATH_XFER -# define _PATH_XFER "/usr/libexec/named-xfer" -#endif -#define _PATH_DEBUG "/var/tmp/named.run" -#define _PATH_DUMPFILE "/var/tmp/named_dump.db" -#ifndef _PATH_PIDFILE -# define _PATH_PIDFILE "/var/run/named.pid" -#endif -#define _PATH_STATS "/var/tmp/named.stats" -#define _PATH_XFERTRACE "/var/tmp/xfer.trace" -#define _PATH_XFERDDT "/var/tmp/xfer.ddt" -#define _PATH_TMPXFER "/var/tmp/xfer.ddt.XXXXXX" -#define _PATH_TMPDIR "/var/tmp" - -#else /* BSD */ - -#define _PATH_DEVNULL "/dev/null" -#define _PATH_TTY "/dev/tty" -#ifndef _PATH_XFER -# define _PATH_XFER "/etc/named-xfer" -#endif -#define _PATH_DEBUG "/usr/tmp/named.run" -#define _PATH_DUMPFILE "/usr/tmp/named_dump.db" -#ifndef _PATH_PIDFILE -# define _PATH_PIDFILE "/etc/named.pid" -#endif -#define _PATH_STATS "/usr/tmp/named.stats" -#define _PATH_XFERTRACE "/usr/tmp/xfer.trace" -#define _PATH_XFERDDT "/usr/tmp/xfer.ddt" -#define _PATH_TMPXFER "/usr/tmp/xfer.ddt.XXXXXX" -#define _PATH_TMPDIR "/usr/tmp" -#endif /* BSD */ - -#ifndef _PATH_XFER_PREDEFINED -# if defined(__sgi) || defined(NeXT) || defined(__ultrix) -# undef _PATH_XFER -# define _PATH_XFER "/usr/etc/named-xfer" -# endif -# if defined(__osf__) -# undef _PATH_XFER -# define _PATH_XFER "/usr/sbin/named-xfer" -# endif -# ifdef sun -# undef _PATH_XFER -# define _PATH_XFER "/usr/etc/in.named-xfer" -# endif -#else -# undef _PATH_XFER_PREDEFINED -#endif /*_PATH_XFER_PREDEFINED*/ diff --git a/usr.sbin/named/storage.c b/usr.sbin/named/storage.c deleted file mode 100644 index 98a71b3f294b..000000000000 --- a/usr.sbin/named/storage.c +++ /dev/null @@ -1,207 +0,0 @@ -/* - * ++Copyright++ 1985, 1989 - * - - * Copyright (c) 1985, 1989 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - - * Portions Copyright (c) 1993 by Digital Equipment Corporation. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies, and that - * the name of Digital Equipment Corporation not be used in advertising or - * publicity pertaining to distribution of the document or software without - * specific, written prior permission. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT - * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - * - - * --Copyright-- - */ - -#include <sys/param.h> -#include <syslog.h> -#include "../conf/portability.h" -#include "../conf/options.h" - -#ifdef DSTORAGE -/* - * S T O R A G E . C - * - * Ray Tracing program, storage manager. - * - * Functions - - * rt_malloc Allocate storage, with visibility & checking - * rt_free Similarly, free storage - * rt_prmem When debugging, print memory map - * calloc, cfree Which call rt_malloc, rt_free - * - * Author - - * Michael John Muuss - * - * Source - - * SECAD/VLD Computing Consortium, Bldg 394 - * The U. S. Army Ballistic Research Laboratory - * Aberdeen Proving Ground, Maryland 21005-5066 - * - * Copyright Notice - - * This software is Copyright (C) 1987 by the United States Army. - * All rights reserved. - */ -#ifndef lint -static char RCSid[] = "$Id: storage.c,v 4.9.1.2 1993/09/08 00:01:17 vixie Exp $"; -#endif - -#undef malloc -#undef free - -#define MDB_SIZE 20000 -#define MDB_MAGIC 0x12348969 -struct memdebug { - char *mdb_addr; - char *mdb_str; - int mdb_len; -} rt_mdb[MDB_SIZE]; - -/* - * R T _ M A L L O C - */ -char * -rt_malloc(cnt) -unsigned int cnt; -{ - register char *ptr; - - cnt = (cnt+2*sizeof(int)-1)&(~(sizeof(int)-1)); - ptr = malloc(cnt); - - if( ptr==(char *)0 ) { - syslog(LOG_ERR, "rt_malloc: malloc failure"); - abort(); - } else { - register struct memdebug *mp = rt_mdb; - for( ; mp < &rt_mdb[MDB_SIZE]; mp++ ) { - if( mp->mdb_len > 0 ) continue; - mp->mdb_addr = ptr; - mp->mdb_len = cnt; - mp->mdb_str = "???"; - goto ok; - } - syslog(LOG_ERR, "rt_malloc: memdebug overflow\n"); - } -ok: ; - { - register int *ip = (int *)(ptr+cnt-sizeof(int)); - *ip = MDB_MAGIC; - } - return(ptr); -} - -/* - * R T _ F R E E - */ -void -rt_free(ptr) -char *ptr; -{ - register struct memdebug *mp = rt_mdb; - for( ; mp < &rt_mdb[MDB_SIZE]; mp++ ) { - if( mp->mdb_len <= 0 ) continue; - 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(); - } - } - mp->mdb_len = 0; /* successful free */ - goto ok; - } - syslog(LOG_ERR, "ERROR rt_free(x%x, %s) bad pointer!\n", ptr, "???"); - abort(); -ok: ; - - *((int *)ptr) = -1; /* zappo! */ - free(ptr); -} - -/* - * R T _ P R M E M - * - * Print map of memory currently in use. - */ -void -rt_prmem(str) -char *str; -{ - register struct memdebug *mp = rt_mdb; - register int *ip; - - printf("\nRT memory use\t\t%s\n", str); - for( ; mp < &rt_mdb[MDB_SIZE]; mp++ ) { - if( mp->mdb_len <= 0 ) continue; - ip = (int *)(mp->mdb_addr+mp->mdb_len-sizeof(int)); - printf("%7x %5x %s %s\n", - mp->mdb_addr, mp->mdb_len, mp->mdb_str, - *ip!=MDB_MAGIC ? "-BAD-" : "" ); - if( *ip != MDB_MAGIC ) - printf("\t%x\t%x\n", *ip, MDB_MAGIC); - } -} - -char * -calloc(num, size) - register unsigned num, size; -{ - register char *p; - - size *= num; - if (p = rt_malloc(size)) - bzero(p, size); - return (p); -} - -cfree(p, num, size) - char *p; - unsigned num; - unsigned size; -{ - rt_free(p); -} - -#endif /*DSTORAGE*/ diff --git a/usr.sbin/named/tools/named.reload/named.reload.sh b/usr.sbin/named/tools/named.reload/named.reload.sh deleted file mode 100644 index a25de1b87f61..000000000000 --- a/usr.sbin/named/tools/named.reload/named.reload.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/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 $ -# -kill -HUP `cat %PIDDIR%/named.pid` diff --git a/usr.sbin/named/tools/named.restart/named.restart.sh b/usr.sbin/named/tools/named.restart/named.restart.sh deleted file mode 100644 index 8a61ccca4df4..000000000000 --- a/usr.sbin/named/tools/named.restart/named.restart.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/sh - -# -# from named.restart 5.4 (Berkeley) 6/27/89 -# $Id: named.restart.sh,v 4.9.1.5 1994/04/09 03:43:17 vixie Exp $ -# - -PATH=%DESTSBIN%:/bin:/usr/bin - -pid=`cat %PIDDIR%/named.pid` -kill $pid -sleep 5 -exec %INDOT%named diff --git a/usr.sbin/named/tools/nsquery/nsquery.c b/usr.sbin/named/tools/nsquery/nsquery.c deleted file mode 100644 index c7ff6ebe4d72..000000000000 --- a/usr.sbin/named/tools/nsquery/nsquery.c +++ /dev/null @@ -1,140 +0,0 @@ -/* - * ++Copyright++ 1986 - * - - * Copyright (c) 1986 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - - * Portions Copyright (c) 1993 by Digital Equipment Corporation. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies, and that - * the name of Digital Equipment Corporation not be used in advertising or - * publicity pertaining to distribution of the document or software without - * specific, written prior permission. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT - * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - * - - * --Copyright-- - */ - -#ifndef lint -char copyright[] = -"@(#) Copyright (c) 1986 Regents of the University of California.\n\ - portions Copyright (c) 1993 Digital Equipment Corporation\n\ - All rights reserved.\n"; -#endif /* not lint */ - -#ifndef lint -static char sccsid[] = "@(#)nsquery.c 4.8 (Berkeley) 6/1/90"; -static char rcsid[] = "$Id: nsquery.c,v 4.9.1.4 1994/06/11 22:05:07 vixie Exp $"; -#endif /* not lint */ - -#include <sys/param.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/nameser.h> -#include <arpa/inet.h> -#include <stdio.h> -#include <netdb.h> -#include <resolv.h> -#include "../conf/portability.h" - -main(argc, argv) - int argc; - char **argv; -{ - extern struct __res_state _res; - register struct hostent *hp; - register char *s; - - res_init(); - - if (argc >= 2 && strcmp(argv[1], "-d") == 0) { - _res.options |= RES_DEBUG; - argc--; - argv++; - } - if (argc < 2) { - fprintf(stderr, "usage: nsquery [-d] host [server]\n"); - exit(1); - } - if (argc == 3) { - hp = gethostbyname(argv[2]); - if (hp == NULL) { - fprintf(stderr, "nsquery:"); - herror(argv[2]); - exit(1); - } - printf("\nServer:\n"); - printanswer(hp); - _res.nsaddr.sin_addr = *(struct in_addr *)hp->h_addr; -#ifdef nsaddr /* struct __res_state includes nscount and nsaddr_list[] */ - _res.nscount = 1; -#endif - } - - hp = gethostbyname(argv[1]); - if (hp == NULL) { - fprintf(stderr, "nsquery: %s: ", argv[1]); - herror((char *)NULL); - exit(1); - } - printanswer(hp); - exit(0); -} - -printanswer(hp) - register struct hostent *hp; -{ - register char **cp; - - printf("Name: %s\n", hp->h_name); -#if BSD >= 43 || defined(h_addr) - printf("Addresses:"); - for (cp = hp->h_addr_list; cp && *cp; cp++) - printf(" %s", inet_ntoa(*(struct in_addr *)(*cp))); - printf("\n"); -#else - printf("Address: %s\n", inet_ntoa(*(struct in_addr *)hp->h_addr)); -#endif - printf("Aliases:"); - for (cp = hp->h_aliases; cp && *cp && **cp; cp++) - printf(" %s", *cp); - printf("\n\n"); -} diff --git a/usr.sbin/named/tools/nstest/nstest.c b/usr.sbin/named/tools/nstest/nstest.c deleted file mode 100644 index f20388d8696e..000000000000 --- a/usr.sbin/named/tools/nstest/nstest.c +++ /dev/null @@ -1,424 +0,0 @@ -/* - * ++Copyright++ 1986 - * - - * Copyright (c) 1986 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - - * Portions Copyright (c) 1993 by Digital Equipment Corporation. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies, and that - * the name of Digital Equipment Corporation not be used in advertising or - * publicity pertaining to distribution of the document or software without - * specific, written prior permission. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT - * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - * - - * --Copyright-- - */ - -#ifndef lint -char copyright[] = -"@(#) Copyright (c) 1986 Regents of the University of California.\n\ - portions Copyright (c) 1993 Digital Equipment Corporation\n\ - All rights reserved.\n"; -#endif /* not lint */ - -#ifndef lint -static char sccsid[] = "@(#)nstest.c 4.15 (Berkeley) 3/21/91"; -static char rcsid[] = "$Id: nstest.c,v 4.9.1.6 1994/06/01 21:10:11 vixie Exp $"; -#endif /* not lint */ - -#include <sys/param.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <arpa/nameser.h> -#include <stdio.h> -#include <resolv.h> -#include "../conf/portability.h" - -char *progname; -FILE *log; -#define MAXDATA 256 /* really should get this from named/db.h */ -main(argc, argv) - char **argv; -{ - register char *cp; - register u_char *ucp; - struct hostent *hp; - u_short port = htons(NAMESERVER_PORT); - char buf[BUFSIZ]; - u_char packet[PACKETSZ], answer[8*1024], OldRRData[MAXDATA]; - struct rrec NewRR; - u_int32_t l; - int n, dump_packet; - - NewRR.r_data = (char *) malloc(MAXDATA); - NewRR.r_data = (char *) malloc(MAXDATA); - progname = argv[0]; - dump_packet = 0; - _res.options |= RES_DEBUG|RES_RECURSE; - (void) res_init(); - while (argc > 1 && argv[1][0] == '-') { - argc--; - cp = *++argv; - while (*++cp) - switch (*cp) { - case 'p': - if (--argc <= 0) - usage(); - port = htons(atoi(*++argv)); - break; - - case 'i': - _res.options |= RES_IGNTC; - break; - - case 'v': - _res.options |= RES_USEVC|RES_STAYOPEN; - break; - - case 'r': - _res.options &= ~RES_RECURSE; - break; - - case 'd': - dump_packet++; - break; - - default: - usage(); - } - } - _res.nsaddr.sin_family = AF_INET; - _res.nsaddr.sin_addr = inet_makeaddr(IN_LOOPBACKNET, 1); - _res.nsaddr.sin_port = port; - if (argc > 1) { - if (!inet_aton(argv[1], - (struct in_addr *)&_res.nsaddr.sin_addr)) - usage(); - } - if (argc > 2) { - log = fopen(argv[2],"w"); - if (log == NULL) perror(argv[2]); - } - for (;;) { - printf("> "); - fflush(stdout); - if ((cp = fgets(buf, sizeof buf, stdin)) == NULL) - break; - switch (*cp++) { - case 'a': - n = res_mkquery(QUERY, cp, C_IN, T_A, NULL, 0, - NULL, packet, sizeof packet); - break; - - case 'A': - n = ntohl(inet_addr(cp)); - putlong((u_int32_t)n, (u_char*)cp); - n = res_mkquery(IQUERY, "", C_IN, T_A, (u_char *)cp, - INT32SZ, NULL, - packet, sizeof(packet)); - break; - - case 'f': - n = res_mkquery(QUERY, cp, C_ANY, T_UINFO, NULL, - 0, NULL, packet, sizeof packet); - break; - - case 'F': - n = res_mkquery(QUERY, cp, C_IN, T_AFSDB, NULL, 0, - NULL, packet, sizeof packet); - break; - - case 'g': - n = res_mkquery(QUERY, cp, C_ANY, T_GID, NULL, 0, - NULL, packet, sizeof packet); - break; - - case 'G': - *(int *)cp = htonl(atoi(cp)); - n = res_mkquery(IQUERY, "", C_ANY, T_GID, (u_char *)cp, - sizeof(int), NULL, packet, sizeof packet); - break; - - case 'c': - n = res_mkquery(QUERY, cp, C_IN, T_CNAME, NULL, 0, - NULL, packet, sizeof packet); - break; - - case 'h': - n = res_mkquery(QUERY, cp, C_IN, T_HINFO, NULL, 0, - NULL, packet, sizeof packet); - break; - - case 'm': - n = res_mkquery(QUERY, cp, C_IN, T_MX, NULL, 0, - NULL, packet, sizeof packet); - break; - - case 'M': - n = res_mkquery(QUERY, cp, C_IN, T_MAILB, NULL, 0, - NULL, packet, sizeof packet); - break; - - case 'n': - n = res_mkquery(QUERY, cp, C_IN, T_NS, NULL, 0, - NULL, packet, sizeof packet); - break; - - case 'p': - n = res_mkquery(QUERY, cp, C_IN, T_PTR, NULL, 0, - NULL, packet, sizeof packet); - break; - - case 's': - n = res_mkquery(QUERY, cp, C_IN, T_SOA, NULL, 0, - NULL, packet, sizeof packet); - break; - - case 'T': - n = res_mkquery(QUERY, cp, C_IN, T_TXT, NULL, 0, - NULL, packet, sizeof packet); - break; - - case 'u': - n = res_mkquery(QUERY, cp, C_ANY, T_UID, NULL, 0, - NULL, packet, sizeof packet); - break; - - case 'U': - *(int *)cp = htonl(atoi(cp)); - n = res_mkquery(IQUERY, "", C_ANY, T_UID, (u_char *)cp, - sizeof(int), NULL, - packet, sizeof packet); - break; - - case 'x': - n = res_mkquery(QUERY, cp, C_IN, T_AXFR, NULL, 0, - NULL, packet, sizeof packet); - break; - - case 'w': - n = res_mkquery(QUERY, cp, C_IN, T_WKS, NULL, 0, - NULL, packet, sizeof packet); - break; - - case 'b': - n = res_mkquery(QUERY, cp, C_IN, T_MB, NULL, 0, - NULL, packet, sizeof packet); - break; - - case 'B': - n = res_mkquery(QUERY, cp, C_IN, T_MG, NULL, 0, - NULL, packet, sizeof packet); - break; - - case 'i': - n = res_mkquery(QUERY, cp, C_IN, T_MINFO, NULL, 0, - NULL, packet, sizeof packet); - break; - - case 'r': - n = res_mkquery(QUERY, cp, C_IN, T_MR, NULL, 0, - NULL, packet, sizeof packet); - break; - - case '*': - n = res_mkquery(QUERY, cp, C_IN, T_ANY, NULL, 0, - NULL, packet, sizeof packet); - break; - -#ifdef ALLOW_UPDATES - case '^': - { - char IType[10], TempStr[50]; - int Type, oldnbytes, nbytes, i; -#ifdef ALLOW_T_UNSPEC - printf("Data type (a = T_A, u = T_UNSPEC): "); - gets(IType); - if (IType[0] == 'u') { - Type = T_UNSPEC; - printf("How many data bytes? "); - gets(TempStr); /* Throw away CR */ - sscanf(TempStr, "%d", &nbytes); - for (i = 0; i < nbytes; i++) { - (NewRR.r_data)[i] = (char) i; - } - } else { -#endif /* ALLOW_T_UNSPEC */ - Type = T_A; - nbytes = INT32SZ; - printf( - "Inet addr for new dname (e.g., 192.4.3.2): " - ); - gets(TempStr); - putlong(ntohl(inet_addr(TempStr)), - NewRR.r_data); -#ifdef ALLOW_T_UNSPEC - } -#endif - NewRR.r_class = C_IN; - NewRR.r_type = Type; - NewRR.r_size = nbytes; - NewRR.r_ttl = 99999999; - printf("Add, modify, or modify all (a/m/M)? "); - gets(TempStr); - if (TempStr[0] == 'a') { - n = res_mkquery(UPDATEA, cp, C_IN, Type, - OldRRData, nbytes, - &NewRR, packet, - sizeof packet); - } else { - if (TempStr[0] == 'm') { - printf("How many data bytes in old RR? "); - gets(TempStr); /* Throw away CR */ - sscanf(TempStr, "%d", &oldnbytes); - for (i = 0; i < oldnbytes; i++) { - OldRRData[i] = (char) i; - } - n = res_mkquery(UPDATEM, cp, - C_IN, Type, - OldRRData, oldnbytes, - &NewRR, packet, - sizeof packet); - } else { /* Modify all */ - n = res_mkquery(UPDATEMA, cp, - C_IN, Type, NULL, 0, - &NewRR, packet, - sizeof packet); - - } - } - } - break; - -#ifdef ALLOW_T_UNSPEC - case 'D': - n = res_mkquery(UPDATEDA, cp, C_IN, T_UNSPEC, - (char *)0, 0, NULL, - packet, sizeof packet); - break; - - case 'd': - { - char TempStr[100]; - int nbytes, i; - printf("How many data bytes in oldrr data? "); - gets(TempStr); /* Throw away CR */ - sscanf(TempStr, "%d", &nbytes); - for (i = 0; i < nbytes; i++) { - OldRRData[i] = (char) i; - } - n = res_mkquery(UPDATED, cp, C_IN, T_UNSPEC, - OldRRData, nbytes, NULL, - packet, sizeof packet); - } - break; -#endif /* ALLOW_T_UNSPEC */ -#endif /* ALLOW_UPDATES */ - - default: - printf("a{host} - query T_A\n"); - printf("A{addr} - iquery T_A\n"); - printf("b{user} - query T_MB\n"); - printf("B{user} - query T_MG\n"); - printf("f{host} - query T_UINFO\n"); - printf("g{host} - query T_GID\n"); - printf("G{gid} - iquery T_GID\n"); - printf("h{host} - query T_HINFO\n"); - printf("i{host} - query T_MINFO\n"); - printf("p{host} - query T_PTR\n"); - printf("m{host} - query T_MX\n"); - printf("M{host} - query T_MAILB\n"); - printf("n{host} - query T_NS\n"); - printf("r{host} - query T_MR\n"); - printf("s{host} - query T_SOA\n"); - printf("T{host} - query T_TXT\n"); - printf("u{host} - query T_UID\n"); - printf("U{uid} - iquery T_UID\n"); - printf("x{host} - query T_AXFR\n"); - printf("w{host} - query T_WKS\n"); - printf("F{host} - query T_AFSDB\n"); - printf("c{host} - query T_CNAME\n"); - printf("*{host} - query T_ANY\n"); -#ifdef ALLOW_UPDATES - printf("^{host} - add/mod/moda (T_A/T_UNSPEC)\n"); -#ifdef ALLOW_T_UNSPEC - printf("D{host} - deletea T_UNSPEC\n"); - printf("d{host} - delete T_UNSPEC\n"); -#endif /* ALLOW_T_UNSPEC */ -#endif /* ALLOW_UPDATES */ - continue; - } - if (n < 0) { - printf("res_mkquery: buffer too small\n"); - continue; - } - if (log) { - fprintf(log,"SEND QUERY\n"); - fp_query(packet, log); - } - n = res_send(packet, n, answer, sizeof(answer)); - if (n < 0) { - printf("res_send: send error\n"); - if (log) fprintf(log, "res_send: send error\n"); - } - else { - if (dump_packet) { - int f; - f = creat("ns_packet.dump", 0644); - write(f, answer, n); - (void) close(f); - } - if (log) { - fprintf(log, "GOT ANSWER\n"); - fp_query(answer, log); - } - } - } -} - -usage() -{ - fprintf(stderr, "Usage: %s [-v] [-i] [-r] [-d] [-p port] hostaddr\n", - progname); - exit(1); -} diff --git a/usr.sbin/named/tree.c b/usr.sbin/named/tree.c deleted file mode 100644 index 58607ea0bd48..000000000000 --- a/usr.sbin/named/tree.c +++ /dev/null @@ -1,570 +0,0 @@ -/* tree - balanced binary tree library - * - * vix 05apr94 [removed vixie.h dependencies; cleaned up formatting, names] - * vix 22jan93 [revisited; uses RCS, ANSI, POSIX; has bug fixes] - * vix 23jun86 [added delete uar to add for replaced nodes] - * vix 20jun86 [added tree_delete per wirth a+ds (mod2 v.) p. 224] - * vix 06feb86 [added tree_mung()] - * vix 02feb86 [added tree balancing from wirth "a+ds=p" p. 220-221] - * vix 14dec85 [written] - */ - - -/* This program text was created by Paul Vixie using examples from the book: - * "Algorithms & Data Structures," Niklaus Wirth, Prentice-Hall, 1986, ISBN - * 0-13-022005-1. Any errors in the conversion from Modula-2 to C are Paul - * Vixie's. - * - * This code and associated documentation is hereby placed in the public - * domain, with the wish that my name and Prof. Wirth's not be removed - * from the source or documentation. - */ - - -#ifndef LINT -static char RCSid[] = "$Id:"; -#endif - - -/*#define DEBUG "tree"*/ - - -#include <stdio.h> -#ifndef _PATH_XFER -# include <stdlib.h> -#else -# include "../conf/portability.h" -#endif -#include "tree.h" - - -#ifdef DEBUG -static int debugDepth = 0; -static char *debugFuncs[256]; -# define ENTER(proc) { \ - debugFuncs[debugDepth] = proc; \ - fprintf(stderr, "ENTER(%d:%s.%s)\n", \ - debugDepth, DEBUG, - debugFuncs[debugDepth]); \ - debugDepth++; \ - } -# define RET(value) { \ - debugDepth--; \ - fprintf(stderr, "RET(%d:%s.%s)\n", \ - debugDepth, DEBUG, \ - debugFuncs[debugDepth]); \ - return (value); \ - } -# define RETV { \ - debugDepth--; \ - fprintf(stderr, "RETV(%d:%s.%s)\n", \ - debugDepth, DEBUG, \ - debugFuncs[debugDepth]); \ - return; \ - } -# define MSG(msg) fprintf(stderr, "MSG(%s)\n", msg); -#else -# define ENTER(proc) ; -# define RET(value) return (value); -# define RETV return; -# define MSG(msg) ; -#endif - - -#ifndef TRUE -# define TRUE 1 -# define FALSE 0 -#endif - - -static tree * sprout __P( (tree **, tree_t, int *, int (*)(), void (*)()) ); -static int delete __P( (tree **, int (*)(), tree_t, void (*)(), - int *, int *) ); -static void del __P( (tree **, int *, tree **, void (*)(), int *) ); -static void bal_L __P( (tree **, int *) ); -static void bal_R __P( (tree **, int *) ); - - -void -tree_init(ppr_tree) - tree **ppr_tree; -{ - ENTER("tree_init") - *ppr_tree = NULL; - RETV -} - - -tree_t -tree_srch(ppr_tree, pfi_compare, p_user) - tree **ppr_tree; - int (*pfi_compare)(); - tree_t p_user; -{ - register int i_comp; - - ENTER("tree_srch") - - if (*ppr_tree) { - i_comp = (*pfi_compare)(p_user, (**ppr_tree).data); - - if (i_comp > 0) - RET(tree_srch(&(**ppr_tree).right, - pfi_compare, - p_user)) - - if (i_comp < 0) - RET(tree_srch(&(**ppr_tree).left, - pfi_compare, - p_user)) - - /* not higher, not lower... this must be the one. - */ - RET((**ppr_tree).data) - } - - /* grounded. NOT found. - */ - RET(NULL) -} - - -tree_t -tree_add(ppr_tree, pfi_compare, p_user, pfv_uar) - tree **ppr_tree; - int (*pfi_compare)(); - tree_t p_user; - void (*pfv_uar)(); -{ - int i_balance = FALSE; - - ENTER("tree_add") - if (!sprout(ppr_tree, p_user, &i_balance, pfi_compare, pfv_uar)) - RET(NULL) - RET(p_user) -} - - -int -tree_delete(ppr_p, pfi_compare, p_user, pfv_uar) - tree **ppr_p; - int (*pfi_compare)(); - tree_t p_user; - void (*pfv_uar)(); -{ - int i_balance = FALSE, - i_uar_called = FALSE; - - ENTER("tree_delete"); - RET(delete(ppr_p, pfi_compare, p_user, pfv_uar, - &i_balance, &i_uar_called)) -} - - -int -tree_trav(ppr_tree, pfi_uar) - tree **ppr_tree; - int (*pfi_uar)(); -{ - ENTER("tree_trav") - - if (!*ppr_tree) - RET(TRUE) - - if (!tree_trav(&(**ppr_tree).left, pfi_uar)) - RET(FALSE) - if (!(*pfi_uar)((**ppr_tree).data)) - RET(FALSE) - if (!tree_trav(&(**ppr_tree).right, pfi_uar)) - RET(FALSE) - RET(TRUE) -} - - -void -tree_mung(ppr_tree, pfv_uar) - tree **ppr_tree; - void (*pfv_uar)(); -{ - ENTER("tree_mung") - if (*ppr_tree) { - tree_mung(&(**ppr_tree).left, pfv_uar); - tree_mung(&(**ppr_tree).right, pfv_uar); - if (pfv_uar) - (*pfv_uar)((**ppr_tree).data); - free(*ppr_tree); - *ppr_tree = NULL; - } - RETV -} - - -static tree * -sprout(ppr, p_data, pi_balance, pfi_compare, pfv_delete) - tree **ppr; - tree_t p_data; - int *pi_balance; - int (*pfi_compare)(); - void (*pfv_delete)(); -{ - tree *p1, *p2, *sub; - int cmp; - - ENTER("sprout") - - /* are we grounded? if so, add the node "here" and set the rebalance - * flag, then exit. - */ - if (!*ppr) { - MSG("grounded. adding new node, setting h=true") - *ppr = (tree *) malloc(sizeof(tree)); - if (*ppr) { - (*ppr)->left = NULL; - (*ppr)->right = NULL; - (*ppr)->bal = 0; - (*ppr)->data = p_data; - *pi_balance = TRUE; - } - RET(*ppr); - } - - /* compare the data using routine passed by caller. - */ - cmp = (*pfi_compare)(p_data, (*ppr)->data); - - /* if LESS, prepare to move to the left. - */ - if (cmp < 0) { - MSG("LESS. sprouting left.") - sub = sprout(&(*ppr)->left, p_data, pi_balance, - pfi_compare, pfv_delete); - if (sub && *pi_balance) { /* left branch has grown */ - MSG("LESS: left branch has grown") - switch ((*ppr)->bal) { - case 1: /* right branch WAS longer; bal is ok now */ - MSG("LESS: case 1.. bal restored implicitly") - (*ppr)->bal = 0; - *pi_balance = FALSE; - break; - case 0: /* balance WAS okay; now left branch longer */ - MSG("LESS: case 0.. balnce bad but still ok") - (*ppr)->bal = -1; - break; - case -1: /* left branch was already too long. rebal */ - MSG("LESS: case -1: rebalancing") - p1 = (*ppr)->left; - if (p1->bal == -1) { /* LL */ - MSG("LESS: single LL") - (*ppr)->left = p1->right; - p1->right = *ppr; - (*ppr)->bal = 0; - *ppr = p1; - } else { /* double LR */ - MSG("LESS: double LR") - - p2 = p1->right; - p1->right = p2->left; - p2->left = p1; - - (*ppr)->left = p2->right; - p2->right = *ppr; - - if (p2->bal == -1) - (*ppr)->bal = 1; - else - (*ppr)->bal = 0; - - if (p2->bal == 1) - p1->bal = -1; - else - p1->bal = 0; - *ppr = p2; - } /*else*/ - (*ppr)->bal = 0; - *pi_balance = FALSE; - } /*switch*/ - } /*if*/ - RET(sub) - } /*if*/ - - /* if MORE, prepare to move to the right. - */ - if (cmp > 0) { - MSG("MORE: sprouting to the right") - sub = sprout(&(*ppr)->right, p_data, pi_balance, - pfi_compare, pfv_delete); - if (sub && *pi_balance) { - MSG("MORE: right branch has grown") - - switch ((*ppr)->bal) { - case -1: - MSG("MORE: balance was off, fixed implicitly") - (*ppr)->bal = 0; - *pi_balance = FALSE; - break; - case 0: - MSG("MORE: balance was okay, now off but ok") - (*ppr)->bal = 1; - break; - case 1: - MSG("MORE: balance was off, need to rebalance") - p1 = (*ppr)->right; - if (p1->bal == 1) { /* RR */ - MSG("MORE: single RR") - (*ppr)->right = p1->left; - p1->left = *ppr; - (*ppr)->bal = 0; - *ppr = p1; - } else { /* double RL */ - MSG("MORE: double RL") - - p2 = p1->left; - p1->left = p2->right; - p2->right = p1; - - (*ppr)->right = p2->left; - p2->left = *ppr; - - if (p2->bal == 1) - (*ppr)->bal = -1; - else - (*ppr)->bal = 0; - - if (p2->bal == -1) - p1->bal = 1; - else - p1->bal = 0; - - *ppr = p2; - } /*else*/ - (*ppr)->bal = 0; - *pi_balance = FALSE; - } /*switch*/ - } /*if*/ - RET(sub) - } /*if*/ - - /* not less, not more: this is the same key! replace... - */ - MSG("FOUND: Replacing data value") - *pi_balance = FALSE; - if (pfv_delete) - (*pfv_delete)((*ppr)->data); - (*ppr)->data = p_data; - RET(*ppr) -} - - -static int -delete(ppr_p, pfi_compare, p_user, pfv_uar, pi_balance, pi_uar_called) - tree **ppr_p; - int (*pfi_compare)(); - tree_t p_user; - void (*pfv_uar)(); - int *pi_balance; - int *pi_uar_called; -{ - tree *pr_q; - int i_comp, i_ret; - - ENTER("delete") - - if (*ppr_p == NULL) { - MSG("key not in tree") - RET(FALSE) - } - - i_comp = (*pfi_compare)((*ppr_p)->data, p_user); - if (i_comp > 0) { - MSG("too high - scan left") - i_ret = delete(&(*ppr_p)->left, pfi_compare, p_user, pfv_uar, - pi_balance, pi_uar_called); - if (*pi_balance) - bal_L(ppr_p, pi_balance); - } else if (i_comp < 0) { - MSG("too low - scan right") - i_ret = delete(&(*ppr_p)->right, pfi_compare, p_user, pfv_uar, - pi_balance, pi_uar_called); - if (*pi_balance) - bal_R(ppr_p, pi_balance); - } else { - MSG("equal") - pr_q = *ppr_p; - if (pr_q->right == NULL) { - MSG("right subtree null") - *ppr_p = pr_q->left; - *pi_balance = TRUE; - } else if (pr_q->left == NULL) { - MSG("right subtree non-null, left subtree null") - *ppr_p = pr_q->right; - *pi_balance = TRUE; - } else { - MSG("neither subtree null") - del(&pr_q->left, pi_balance, &pr_q, - pfv_uar, pi_uar_called); - if (*pi_balance) - bal_L(ppr_p, pi_balance); - } - if (!*pi_uar_called && pfv_uar) - (*pfv_uar)(pr_q->data); - free(pr_q); /* thanks to wuth@castrov.cuc.ab.ca */ - i_ret = TRUE; - } - RET(i_ret) -} - - -static void -del(ppr_r, pi_balance, ppr_q, pfv_uar, pi_uar_called) - tree **ppr_r; - int *pi_balance; - tree **ppr_q; - void (*pfv_uar)(); - int *pi_uar_called; -{ - ENTER("del") - - if ((*ppr_r)->right != NULL) { - del(&(*ppr_r)->right, pi_balance, ppr_q, - pfv_uar, pi_uar_called); - if (*pi_balance) - bal_R(ppr_r, pi_balance); - } else { - if (pfv_uar) - (*pfv_uar)((*ppr_q)->data); - *pi_uar_called = TRUE; - (*ppr_q)->data = (*ppr_r)->data; - *ppr_q = *ppr_r; - *ppr_r = (*ppr_r)->left; - *pi_balance = TRUE; - } - - RETV -} - - -static void -bal_L(ppr_p, pi_balance) - tree **ppr_p; - int *pi_balance; -{ - tree *p1, *p2; - int b1, b2; - - ENTER("bal_L") - MSG("left branch has shrunk") - - switch ((*ppr_p)->bal) { - case -1: - MSG("was imbalanced, fixed implicitly") - (*ppr_p)->bal = 0; - break; - case 0: - MSG("was okay, is now one off") - (*ppr_p)->bal = 1; - *pi_balance = FALSE; - break; - case 1: - MSG("was already off, this is too much") - p1 = (*ppr_p)->right; - b1 = p1->bal; - if (b1 >= 0) { - MSG("single RR") - (*ppr_p)->right = p1->left; - p1->left = *ppr_p; - if (b1 == 0) { - MSG("b1 == 0") - (*ppr_p)->bal = 1; - p1->bal = -1; - *pi_balance = FALSE; - } else { - MSG("b1 != 0") - (*ppr_p)->bal = 0; - p1->bal = 0; - } - *ppr_p = p1; - } else { - MSG("double RL") - p2 = p1->left; - b2 = p2->bal; - p1->left = p2->right; - p2->right = p1; - (*ppr_p)->right = p2->left; - p2->left = *ppr_p; - if (b2 == 1) - (*ppr_p)->bal = -1; - else - (*ppr_p)->bal = 0; - if (b2 == -1) - p1->bal = 1; - else - p1->bal = 0; - *ppr_p = p2; - p2->bal = 0; - } - } - RETV -} - - -static void -bal_R(ppr_p, pi_balance) - tree **ppr_p; - int *pi_balance; -{ - tree *p1, *p2; - int b1, b2; - - ENTER("bal_R") - MSG("right branch has shrunk") - switch ((*ppr_p)->bal) { - case 1: - MSG("was imbalanced, fixed implicitly") - (*ppr_p)->bal = 0; - break; - case 0: - MSG("was okay, is now one off") - (*ppr_p)->bal = -1; - *pi_balance = FALSE; - break; - case -1: - MSG("was already off, this is too much") - p1 = (*ppr_p)->left; - b1 = p1->bal; - if (b1 <= 0) { - MSG("single LL") - (*ppr_p)->left = p1->right; - p1->right = *ppr_p; - if (b1 == 0) { - MSG("b1 == 0") - (*ppr_p)->bal = -1; - p1->bal = 1; - *pi_balance = FALSE; - } else { - MSG("b1 != 0") - (*ppr_p)->bal = 0; - p1->bal = 0; - } - *ppr_p = p1; - } else { - MSG("double LR") - p2 = p1->right; - b2 = p2->bal; - p1->right = p2->left; - p2->left = p1; - (*ppr_p)->left = p2->right; - p2->right = *ppr_p; - if (b2 == -1) - (*ppr_p)->bal = 1; - else - (*ppr_p)->bal = 0; - if (b2 == 1) - p1->bal = -1; - else - p1->bal = 0; - *ppr_p = p2; - p2->bal = 0; - } - } - RETV -} diff --git a/usr.sbin/named/tree.h b/usr.sbin/named/tree.h deleted file mode 100644 index 2cad7c1233ae..000000000000 --- a/usr.sbin/named/tree.h +++ /dev/null @@ -1,48 +0,0 @@ -/* tree.h - declare structures used by tree library - * - * vix 22jan93 [revisited; uses RCS, ANSI, POSIX; has bug fixes] - * vix 27jun86 [broken out of tree.c] - * - * $Id: tree.h,v 1.1 1994/04/09 04:05:46 vixie Exp $ - */ - - -#ifndef _TREE_H_INCLUDED -#define _TREE_H_INCLUDED - - -#ifndef __P -# if defined(__STDC__) || defined(__GNUC__) -# define __P(x) x -# else -# define __P(x) () -# endif -#endif - -/* - * tree_t is our package-specific anonymous pointer. - */ -#if defined(__STDC__) || defined(__GNUC__) -typedef void *tree_t; -#else -typedef char *tree_t; -#endif - - -typedef struct tree_s { - tree_t data; - struct tree_s *left, *right; - short bal; - } - tree; - - -void tree_init __P((tree **)); -tree_t tree_srch __P((tree **, int (*)(), tree_t)); -tree_t tree_add __P((tree **, int (*)(), tree_t, void (*)())); -int tree_delete __P((tree **, int (*)(), tree_t, void (*)())); -int tree_trav __P((tree **, int (*)())); -void tree_mung __P((tree **, void (*)())); - - -#endif /* _TREE_H_INCLUDED */ diff --git a/usr.sbin/named/tree.man3 b/usr.sbin/named/tree.man3 deleted file mode 100644 index 5be48783e2b6..000000000000 --- a/usr.sbin/named/tree.man3 +++ /dev/null @@ -1,154 +0,0 @@ -.TH TREE 3 "5 April 1994" -.\" from .TH TREE 3 "22 Jan 1993" -.\" from .TH TREE 2 "23 June 1986" -.UC 4 -.SH NAME -tree_init, tree_mung, tree_srch, tree_add, tree_delete, tree_trav -\- balanced binary tree routines -.SH SYNOPSIS -.nf -.B void -.B tree_init(tree) -.B void **tree; -.PP -.B void * -.B tree_srch(tree, compare, data) -.B void **tree; -.B int (*compare)(); -.B void *data; -.PP -.B void -.B tree_add(tree, compare, data, del_uar) -.B void **tree; -.B int (*compare)(); -.B void *data; -.B void (*del_uar)(); -.PP -.B int -.B tree_delete(tree, compare, data, del_uar) -.B void **tree; -.B int (*compare)(); -.B void *data; -.B void (*del_uar)(); -.PP -.B int -.B tree_trav(tree, trav_uar) -.B void **tree; -.B int (*trav_uar)(); -.PP -.B void -.B tree_mung(tree, del_uar) -.B void **tree; -.B void (*del_uar)(); -.fi -.SH DESCRIPTION -These functions create and manipulate a balanced binary (AVL) tree. Each node -of the tree contains the expected left & right subtree pointers, a short int -balance indicator, and a pointer to the user data. On a 32 bit system, this -means an overhead of 4+4+2+4 bytes per node (or, on a RISC or otherwise -alignment constrained system with implied padding, 4+4+4+4 bytes per node). -There is no key data type enforced by this package; a caller supplied -compare routine is used to compare user data blocks. -.PP -Balanced binary trees are very fast on searches and replacements, but have a -moderately high cost for additions and deletions. If your application does a -lot more searches and replacements than it does additions and deletions, the -balanced (AVL) binary tree is a good choice for a data structure. -.PP -.I Tree_init -creates an empty tree and binds it to -.I tree -(which for this and all other routines in this package should be declared as -a pointer to void or int, and passed by reference), which can then be used by -other routines in this package. Note that more than one -.I tree -variable can exist at once; thus multiple trees can be manipulated -simultaneously. -.PP -.I Tree_srch -searches a tree for a specific node and returns either -.I NULL -if no node was found, or the value of the user data pointer if the node -was found. -.I compare -is the address of a function to compare two user data blocks. This routine -should work much the way -.IR strcmp (3) -does; in fact, -.I strcmp -could be used if the user data was a \s-2NUL\s+2 terminated string. -.I data -is the address of a user data block to be used by -.I compare -as the search criteria. The tree is searched for a node where -.I compare -returns 0. -.PP -.I Tree_add -inserts or replaces a node in the specified tree. The tree specified by -.I tree -is searched as in -.I tree_srch, -and if a node is found to match -.I data, -then the -.I del_uar -function, if non\-\s-2NULL\s+2, is called with the address of the user data -block for the node (this routine should deallocate any dynamic memory which -is referenced exclusively by the node); the user data pointer for the node -is then replaced by the value of -.I data. -If no node is found to match, a new node is added (which may or may not -cause a transparent rebalance operation), with a user data pointer equal to -.I data. -A rebalance may or may not occur, depending on where the node is added -and what the rest of the tree looks like. -.I Tree_add -will return the -.I data -pointer unless catastrophe occurs in which case it will return \s-2NULL\s+2. -.PP -.I Tree_delete -deletes a node from -.I tree. -A rebalance may or may not occur, depending on where the node is removed from -and what the rest of the tree looks like. -.I Tree_delete -returns TRUE if a node was deleted, FALSE otherwise. -.PP -.I Tree_trav -traverses all of -.I tree, -calling -.I trav_uar -with the address of each user data block. If -.I trav_uar -returns FALSE at any time, -.I tree_trav -will immediately return FALSE to its caller. Otherwise all nodes will be -reached and -.I tree_trav -will return TRUE. -.PP -.I Tree_mung -deletes every node in -.I tree, -calling -.I del_uar -(if it is not \s-2NULL\s+2) with the user data address from each node (see -.I tree_add -and -.I tree_delete -above). The tree is left in the same state that -.I tree_init -leaves it in \- i.e., empty. -.SH BUGS -Should have a way for the caller to specify application specific -.I malloc -and -.I free -functions to be used internally when allocating meta data. -.SH AUTHOR -Paul Vixie, converted and augumented from Modula\-2 examples in -.I Algorithms & Data Structures, -Niklaus Wirth, Prentice\-Hall, ISBN 0\-13\-022005\-1. diff --git a/usr.sbin/named/xfer/named-xfer.c b/usr.sbin/named/xfer/named-xfer.c deleted file mode 100644 index 5d8a9cdd39de..000000000000 --- a/usr.sbin/named/xfer/named-xfer.c +++ /dev/null @@ -1,1481 +0,0 @@ -/* - * The original version of xfer by Kevin Dunlap. - * Completed and integrated with named by David Waitzman - * (dwaitzman@bbn.com) 3/14/88. - * Modified by M. Karels and O. Kure 10-88. - * Modified extensively since then by just about everybody. - */ - -/* - * ++Copyright++ 1988, 1990 - * - - * Copyright (c) 1988, 1990 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - - * Portions Copyright (c) 1993 by Digital Equipment Corporation. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies, and that - * the name of Digital Equipment Corporation not be used in advertising or - * publicity pertaining to distribution of the document or software without - * specific, written prior permission. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT - * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - * - - * --Copyright-- - */ - -#if !defined(lint) && !defined(SABER) -char copyright[] = -"@(#) Copyright (c) 1988, 1990 The Regents of the University of California.\n\ - portions Copyright (c) 1993 Digital Equipment Corporation\n\ - All rights reserved.\n"; -#endif /* not lint */ - -#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 4.9.1.23 1994/07/22 08:42:39 vixie 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 <net/if.h> -#include <netdb.h> -#include <arpa/inet.h> -#include <arpa/nameser.h> - -#include <errno.h> -#include <resolv.h> -#include <stdio.h> -#include <syslog.h> -#include <math.h> -#include <signal.h> - -#define MAIN_PROGRAM -#include "named.h" -#undef MAIN_PROGRAM - -#ifndef LOG_PERROR -# define LOG_PERROR 0 -#endif - -static struct zoneinfo zone; /* zone information */ - -static char ddtfilename[] = _PATH_TMPXFER, - *ddtfile = ddtfilename, - *tmpname, - *domain; /* domain being xfered */ - -static int quiet = 0, - read_interrupted = 0, - domain_len; /* strlen(domain) */ - -static FILE *fp = NULL, - *dbfp = NULL; - -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; - -extern char *optarg; -extern int optind, getopt(); - -void -main(argc, argv) - int argc; - char *argv[]; -{ - register struct zoneinfo *zp; - register struct hostent *hp; - char *dbfile = NULL, *tracefile = NULL, *tm = NULL; - int dbfd, ddtd, result, c, fd, closed = 0; - u_int32_t serial_no = 0; - u_int16_t port = htons(NAMESERVER_PORT); - struct stat statbuf; -#ifdef STUBS - int stub_only = 0; -#endif -#ifdef GEN_AXFR - int class = C_IN; -#endif - - if (ProgName = strrchr(argv[0], '/')) - ProgName++; - else - ProgName = argv[0]; - - (void) umask(022); - - /* this is a hack; closing everything in the parent is hard. */ - for (fd = getdtablesize()-1; fd > STDERR_FILENO; fd--) - closed += (close(fd) == 0); - -#ifdef RENICE - nice (-40); /* this is the recommended procedure to */ - nice (20); /* reset the priority of the current process */ - nice (0); /* to "normal" (== 0) - see nice(3) */ -#endif - -#ifdef LOG_DAEMON - openlog(ProgName, LOG_PID|LOG_CONS|LOG_PERROR, LOGFAC); -#else - openlog(ProgName, LOG_PID); -#endif -#ifdef STUBS - while ((c = getopt(argc, argv, "C:d:l:s:t:z:f:p:P:qS")) != EOF) -#else - while ((c = getopt(argc, argv, "C:d:l:s:t:z:f:p:P:q")) != EOF) -#endif - switch (c) { -#ifdef GEN_AXFR - case 'C': - class = get_class(optarg); - break; -#endif - case 'd': -#ifdef DEBUG - debug = atoi(optarg); -#endif - break; - case 'l': - ddtfile = (char *)malloc(strlen(optarg) + - sizeof(".XXXXXX") + 1); -#ifdef SHORT_FNAMES - filenamecpy(ddtfile, optarg); -#else - (void) strcpy(ddtfile, optarg); -#endif /* SHORT_FNAMES */ - (void) strcat(ddtfile, ".XXXXXX"); - break; - case 's': - serial_no = strtoul(optarg, (char **)NULL, 10); - break; - case 't': - tracefile = optarg; - break; - case 'z': /* zone == domain */ - domain = optarg; - domain_len = strlen(domain); - while ((domain_len > 0) && - (domain[domain_len-1] == '.')) - domain[--domain_len] = '\0'; - break; - case 'f': - dbfile = optarg; - tmpname = (char *)malloc((unsigned)strlen(optarg) + - sizeof(".XXXXXX") + 1); -#ifdef SHORT_FNAMES - filenamecpy(tmpname, optarg); -#else - (void) strcpy(tmpname, optarg); -#endif /* SHORT_FNAMES */ - break; - case 'p': - port = htons((u_int16_t)atoi(optarg)); - break; - case 'P': - port = (u_int16_t)atoi(optarg); - break; -#ifdef STUBS - case 'S': - stub_only = 1; - break; -#endif - case 'q': - quiet++; - break; - case '?': - default: - usage("unrecognized argument"); - /* NOTREACHED */ - } - - if (!domain || !dbfile || optind >= argc) { - if (!domain) - usage("no domain"); - if (!dbfile) - usage("no dbfile"); - if (optind >= argc) - usage("not enough arguments"); - /* NOTREACHED */ - } - if (stat(dbfile, &statbuf) != -1 && - !S_ISREG(statbuf.st_mode) && - !S_ISFIFO(statbuf.st_mode)) - usage("dbfile must be a regular file or FIFO"); - if (tracefile && (fp = fopen(tracefile, "w")) == NULL) - perror(tracefile); - (void) strcat(tmpname, ".XXXXXX"); - /* tmpname is now something like "/etc/named/named.bu.db.XXXXXX" */ - if ((dbfd = mkstemp(tmpname)) == -1) { - perror(tmpname); - if (!quiet) - syslog(LOG_ERR, "can't make tmpfile (%s): %m\n", - tmpname); - exit(XFER_FAIL); - } -#if HAVE_FCHMOD - if (fchmod(dbfd, 0644) == -1) -#else - if (chmod(tmpname, 0644) == -1) -#endif - { - perror(tmpname); - if (!quiet) - syslog(LOG_ERR, "can't [f]chmod tmpfile (%s): %m\n", - tmpname); - exit(XFER_FAIL); - } - if ((dbfp = fdopen(dbfd, "r+")) == NULL) { - perror(tmpname); - if (!quiet) - syslog(LOG_ERR, "can't fdopen tmpfile (%s)", tmpname); - exit(XFER_FAIL); - } -#ifdef DEBUG - if (debug) { - /* ddtfile is now something like "/usr/tmp/xfer.ddt.XXXXXX" */ - if ((ddtd = mkstemp(ddtfile)) == -1) { - perror(ddtfile); - debug = 0; - } -#if HAVE_FCHMOD - else if (fchmod(ddtd, 0644) == -1) -#else - else if (chmod(ddtfile, 0644) == -1) -#endif - { - perror(ddtfile); - debug = 0; - } else if ((ddt = fdopen(ddtd, "w")) == NULL) { - perror(ddtfile); - debug = 0; - } else { -#if defined(SYSV) - setvbuf(ddt, NULL, _IOLBF, BUFSIZ); -#else - setlinebuf(ddt); -#endif - } - } -#endif - /* - * Ignore many types of signals that named (assumed to be our parent) - * considers important- if not, the user controlling named with - * signals usually kills us. - */ - (void) signal(SIGHUP, SIG_IGN); -#ifdef SIGSYS - (void) signal(SIGSYS, SIG_IGN); -#endif -#ifdef DEBUG - if (debug == 0) -#endif - { - (void) signal(SIGINT, SIG_IGN); - (void) signal(SIGQUIT, SIG_IGN); - } - (void) signal(SIGIOT, SIG_IGN); - -#if defined(SIGUSR1) && defined(SIGUSR2) - (void) signal(SIGUSR1, SIG_IGN); - (void) signal(SIGUSR2, SIG_IGN); -#else /* SIGUSR1&&SIGUSR2 */ - (void) signal(SIGEMT, SIG_IGN); - (void) signal(SIGFPE, SIG_IGN); -#endif /* SIGUSR1&&SIGUSR2 */ - - dprintf(1, (ddt, - "domain `%s'; file `%s'; serial %lu; closed %d\n", - domain, dbfile, serial_no, closed)); - - buildservicelist(); - buildprotolist(); - - /* init zone data */ - - zp = &zone; -#ifdef STUBS - if (stub_only) - zp->z_type = Z_STUB; - else -#endif - zp->z_type = Z_SECONDARY; -#ifdef GEN_AXFR - zp->z_class = class; -#endif - zp->z_origin = domain; - zp->z_source = dbfile; - zp->z_addrcnt = 0; - dprintf(1, (ddt, "zone found (%d): \"%s\", source = %s\n", - zp->z_type, - (zp->z_origin[0] == '\0') - ? "." - : zp->z_origin, - zp->z_source)); - - for (; optind != argc; optind++, zp->z_addrcnt++) { - tm = argv[optind]; - if (!inet_aton(tm, &zp->z_addr[zp->z_addrcnt])) { - hp = gethostbyname(tm); - if (hp == NULL) { - syslog(LOG_NOTICE, - "uninterpretable server (%s) for %s\n", - tm, zp->z_origin); - zp->z_addrcnt--; /* hack */ - continue; - } - bcopy(hp->h_addr, - (char *)&zp->z_addr[zp->z_addrcnt], - INADDRSZ); - dprintf(1, (ddt, "Arg: \"%s\"\n", tm)); - } - if (zp->z_addr[zp->z_addrcnt].s_addr == 0) { - syslog(LOG_NOTICE, - "SOA query to localhost (%s) for %s", - tm, zp->z_origin); - zp->z_addrcnt--; /* hack */ - continue; - } - if (zp->z_addrcnt >= NSMAX) { - zp->z_addrcnt = NSMAX; - dprintf(1, (ddt, "NSMAX reached\n")); - break; - } - } - dprintf(1, (ddt, "addrcnt = %d\n", zp->z_addrcnt)); - - _res.options &= ~(RES_DEFNAMES | RES_DNSRCH | RES_RECURSE); - result = getzone(zp, serial_no, port); - (void) my_fclose(dbfp); - switch (result) { - - case XFER_SUCCESS: /* ok exit */ - if (rename(tmpname, dbfile) == -1) { - perror("rename"); - if (!quiet) - syslog(LOG_ERR, "rename %s to %s: %m", - tmpname, dbfile); - exit(XFER_FAIL); - } - exit(XFER_SUCCESS); - - case XFER_UPTODATE: /* the zone was already uptodate */ - (void) unlink(tmpname); - exit(XFER_UPTODATE); - - case XFER_TIMEOUT: -#ifdef DEBUG - if (!debug) -#endif - (void) unlink(tmpname); - exit(XFER_TIMEOUT); /* servers not reachable exit */ - - case XFER_FAIL: - default: -#ifdef DEBUG - if (!debug) -#endif - (void) unlink(tmpname); - exit(XFER_FAIL); /* yuck exit */ - } - /*NOTREACHED*/ -} - -static char *UsageText[] = { - "\t-z zone_to_transfer\n", - "\t-f db_file\n", - "\t-s serial_no\n", - "\t[-d debug_level]\n", - "\t[-l debug_log_file]\n", - "\t[-t trace_file]\n", - "\t[-p port]\n", -#ifdef STUBS - "\t[-S]\n", -#endif -#ifdef GEN_AXFR - "\t[-C class]\n", -#endif - "\tservers...\n", - NULL -}; - -static void -usage(msg) - const char *msg; -{ - char * const *line; - - fprintf(stderr, "Usage error: %s\n", msg); - fprintf(stderr, "Usage: %s\n", ProgName); - for (line = UsageText; *line; line++) - fputs(*line, stderr); - exit(XFER_FAIL); -} - -#define DEF_DNAME '\001' /* '\0' means the root domain */ -/* XXX: The following variables should probably all be "static" */ -int minimum_ttl = 0, got_soa = 0; -int prev_comment = 0; /* was previous record a comment? */ -char zone_top[MAXDNAME]; /* the top of the zone */ -char prev_origin[MAXDNAME]; /* from most recent $ORIGIN line */ -char prev_dname[MAXDNAME] = { DEF_DNAME }; /* from previous record */ -char prev_ns_dname[MAXDNAME] = { DEF_DNAME }; /* from most recent NS record */ - -static int -getzone(zp, serial_no, port) - struct zoneinfo *zp; - u_int32_t serial_no; - int port; -{ - HEADER *hp; - u_int16_t len; - u_int32_t serial; - int s, n, l, cnt, nscnt, soacnt, error = 0; - u_char *cp, *nmp, *eom, *tmp ; - u_char *buf = NULL; - int bufsize; - char name[MAXDNAME], name2[MAXDNAME]; - struct sockaddr_in sin; - struct zoneinfo zp_start, zp_finish; -#ifdef POSIX_SIGNALS - struct sigaction sv, osv; -#else - struct sigvec sv, osv; -#endif - int ancount, aucount; - int Class; -#ifdef DEBUG - if (debug) { - (void)fprintf(ddt,"getzone() %s ", zp->z_origin); - switch (zp->z_type) { - case Z_STUB: - fprintf(ddt,"stub\n"); - break; - case Z_SECONDARY: - fprintf(ddt,"secondary\n"); - break; - default: - fprintf(ddt,"unknown type\n"); - } - } -#endif -#ifdef POSIX_SIGNALS - sv.sa_handler = 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 - sv.sv_handler = read_alarm; - sv.sv_onstack = 0; - sv.sv_mask = ~0; - (void) sigvec(SIGALRM, &sv, &osv); -#endif - - strcpy(zone_top, zp->z_origin); - if ((l = strlen(zone_top)) != 0 && zone_top[l - 1] == '.') - zone_top[l - 1] = '\0'; - strcpy(prev_origin, zone_top); - - for (cnt = 0; cnt < zp->z_addrcnt; cnt++) { -#ifdef GEN_AXFR - Class = zp->z_class; -#else - Class = C_IN; -#endif - error = 0; - if (buf == NULL) { - if ((buf = (u_char *)malloc(2 * PACKETSZ)) == NULL) { - syslog(LOG_ERR, "malloc(%u) failed", - 2 * PACKETSZ); - error++; - break; - } - bufsize = 2 * PACKETSZ; - } - bzero((char *)&sin, sizeof(sin)); - sin.sin_family = AF_INET; - 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"); - error++; - break; - } - dprintf(2, (ddt, "connecting to server #%d [%s].%d\n", - 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)); - error++; - (void) my_close(s); - continue; - } -tryagain: - n = res_mkquery(QUERY, zp->z_origin, Class, - T_SOA, NULL, 0, NULL, buf, bufsize); - if (n < 0) { - if (!quiet) - syslog(LOG_NOTICE, - "zone %s: res_mkquery T_SOA failed", - zp->z_origin); - (void) my_close(s); -#ifdef POSIX_SIGNALS - (void) sigaction(SIGALRM, &osv, (struct sigaction *)0); -#else - (void) sigvec(SIGALRM, &osv, (struct sigvec *)0); -#endif - return (XFER_FAIL); - } - /* - * Send length & message for SOA query - */ - if (writemsg(s, buf, n) < 0) { - syslog(LOG_ERR, "writemsg: %m"); - error++; - (void) my_close(s); - continue; - } - /* - * Get out your butterfly net and catch the SOA - */ - if (netread(s, (char *)buf, INT16SZ, XFER_TIMER) < 0) { - error++; - (void) my_close(s); - continue; - } - if ((len = _getshort(buf)) == 0) { - (void) my_close(s); - continue; - } - if (len > bufsize) { - if ((buf = (u_char *)realloc(buf, len)) == NULL) { - syslog(LOG_ERR, - "malloc(%u) failed for SOA from server [%s], zone %s\n", - len, - inet_ntoa(sin.sin_addr), - zp->z_origin); - (void) my_close(s); - continue; - } - bufsize = len; - } - if (netread(s, (char *)buf, len, XFER_TIMER) < 0) { - error++; - (void) my_close(s); - continue; - } -#ifdef DEBUG - if (debug >= 3) { - (void)fprintf(ddt,"len = %d\n", len); - fp_query(buf, ddt); - } -#endif - hp = (HEADER *) buf; - ancount = ntohs(hp->ancount); - aucount = ntohs(hp->nscount); - - /* - * close socket if: - * 1) rcode != NOERROR - * 2) not an authority response - * 3) both the number of answers and authority count < 1) - */ - if (hp->rcode != NOERROR || !(hp->aa) || - (ancount < 1 && aucount < 1)) { -#ifndef GEN_AXFR - if (Class == C_IN) { - dprintf(1, (ddt, "SOA failed, trying C_HS\n")); - Class = C_HS; - goto tryagain; - } -#endif - syslog(LOG_NOTICE, - "%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, - hp->rcode, hp->aa, ancount, aucount); - error++; - (void) my_close(s); - 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); - error++; - (void) my_close(s); - continue; - } - tmp = buf + HFIXEDSZ; - eom = buf + len; - if ((n = dn_skipname(tmp, eom)) == -1) - goto badsoa; - tmp += n + QFIXEDSZ; - if ((n = dn_skipname(tmp, eom)) == -1) - goto badsoa; - tmp += n; - if (soa_zinfo(&zp_start, tmp, eom) == -1) - 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)); - 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)); - for (;;) { - if ((soacnt == 0) || (zp->z_type == Z_STUB)) { - int type; -#ifdef STUBS - if (zp->z_type == Z_STUB) { - if (!soacnt) - type = T_SOA; - else if (!nscnt) - type = T_NS; - else - type = T_SOA; - } else -#endif - type = T_AXFR; - n = res_mkquery(QUERY, zp->z_origin, - Class, type, NULL, 0, - NULL, buf, bufsize); - if (n < 0) { - if (!quiet) { -#ifdef STUBS - if (zp->z_type == Z_STUB) - syslog(LOG_NOTICE, - (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, - "zone %s: res_mkquery T_AXFR failed", - zp->z_origin); - } - (void) my_close(s); -#ifdef POSIX_SIGNALS - sigaction(SIGALRM, &osv, - (struct sigaction *)0); -#else - sigvec(SIGALRM, &osv, - (struct sigvec *)0); -#endif - return (XFER_FAIL); - } - /* - * Send length & msg for zone transfer - */ - if (writemsg(s, buf, n) < 0) { - syslog(LOG_ERR,"writemsg: %m"); - error++; - (void) my_close(s); - break; - } - } - /* - * Receive length & response - */ - if (netread(s, (char *)buf, INT16SZ, - (soacnt == 0) ?300 :XFER_TIMER) - < 0) { - error++; - break; - } - if ((len = _getshort(buf)) == 0) - break; - eom = buf + len; - if (netread(s, (char *)buf, len, XFER_TIMER) - < 0) { - error++; - break; - } -#ifdef DEBUG - if (debug >= 3) { - (void)fprintf(ddt,"len = %d\n", len); - fp_query(buf, ddt); - } - if (fp) - fp_query(buf, fp); -#endif - if (len < HFIXEDSZ) { - badrec: - error++; - syslog(LOG_NOTICE, - "record too short from [%s], zone %s\n", - inet_ntoa(sin.sin_addr), - zp->z_origin); - break; - } - cp = buf + HFIXEDSZ; - if (hp->qdcount) { - if ((n = dn_skipname(cp, eom)) == -1 - || n + QFIXEDSZ >= eom - cp) - goto badrec; - cp += n + QFIXEDSZ; - } - nmp = cp; - if ((n = dn_skipname(cp, eom)) == -1) - goto badrec; - tmp = cp + n; -#ifdef STUBS - if (zp->z_type == Z_STUB) { - ancount = ntohs(hp->ancount); - for (cnt = 0 ; cnt < ancount ; cnt++) { - - n = print_output(buf, bufsize, cp); - cp += n; - } - if (hp->nscount) { - /* we should not get here */ - ancount = ntohs(hp->nscount); - for (cnt = 0 ; cnt < ancount ; cnt++) { - n = print_output(buf, bufsize, cp); - cp += n; - } - } - ancount = ntohs(hp->arcount); - for (cnt = 0 ; cnt < ancount ; cnt ++) { - n = print_output(buf, bufsize, cp); - cp += n; - } - if (cp != eom) { - syslog(LOG_ERR, - "print_output: short answer (%d, %d), zone %s", - cp - buf, n, zp->z_origin); - error++; - break; - } - - } else { -#endif /*STUBS*/ - n = print_output(buf, bufsize, cp); - if (cp + n != eom) { - syslog(LOG_ERR, - "print_output: short answer (%d, %d), zone %s", - cp - buf, n, zp->z_origin); - error++; - break; - } -#ifdef STUBS - } -#endif - GETSHORT(n, tmp); - if (n == T_SOA) { - if (soacnt == 0) { - soacnt++; - if (dn_expand(buf, buf + 512, nmp, - name, sizeof name) == -1) - goto badsoa; - if (eom - tmp - <= 2 * INT16SZ - + INT32SZ) { - goto badsoa; - } - tmp += 2 * INT16SZ - + INT32SZ; - if ((n = dn_skipname(tmp, eom)) == -1) - goto badsoa; - tmp += n; - if ((n = dn_skipname(tmp, eom)) == -1) - goto badsoa; - tmp += n; - if (eom - tmp <= INT32SZ) - goto badsoa; - GETLONG(serial, tmp); - dprintf(3, (ddt, - "first SOA for %s, serial %d\n", - name, serial)); - continue; - } - if (dn_expand(buf, buf + 512, nmp, - name2, sizeof name2) == -1) - goto badsoa; - if (strcasecmp((char *)name, - (char *)name2) != 0) { - dprintf(2, (ddt, - "extraneous SOA for %s\n", - name2)); - continue; - } - tmp -= INT16SZ; - if (soa_zinfo(&zp_finish, tmp, eom) == -1) - goto badsoa; - dprintf(2, (ddt, - "SOA, serial %d\n", - zp_finish.z_serial)); - if (serial != zp_finish.z_serial) { - soacnt = 0; - got_soa = 0; - minimum_ttl = 0; - strcpy(prev_origin, zp->z_origin); - prev_dname[0] = DEF_DNAME; - dprintf(1, (ddt, - "serial changed, restart\n" - )); - /* - * Flush buffer, truncate file - * and seek to beginning to restart. - */ - fflush(dbfp); - if (ftruncate(fileno(dbfp), 0) != 0) { - if (!quiet) - syslog(LOG_ERR, - "ftruncate %s: %m\n", - tmpname); - return (XFER_FAIL); - } - fseek(dbfp, 0L, 0); - } else - break; -#ifdef STUBS - } else if (zp->z_type == Z_STUB && n == T_NS) { - nscnt++; - } else if (zp->z_type == Z_STUB) { - break; -#endif - } - } - (void) my_close(s); - if (error == 0) { -#ifdef POSIX_SIGNALS - (void) sigaction(SIGALRM, &osv, - (struct sigaction *)0); -#else - (void) sigvec(SIGALRM, &osv, (struct sigvec *)0); -#endif - return (XFER_SUCCESS); - } - dprintf(2, (ddt, "error receiving zone transfer\n")); - } else if (zp_start.z_serial == serial_no) { - (void) my_close(s); - dprintf(1, (ddt, - "zone up-to-date, serial %u\n", - zp_start.z_serial)); - return (XFER_UPTODATE); - } else { - (void) my_close(s); - if (!quiet) - syslog(LOG_NOTICE, - "serial from [%s], zone %s: %u lower than current: %u\n", - inet_ntoa(sin.sin_addr), zp->z_origin, - zp_start.z_serial, serial_no); - return (XFER_FAIL); - } - } -#ifdef POSIX_SIGNALS - (void) sigaction(SIGALRM, &osv, (struct sigaction *)0); -#else - (void) sigvec(SIGALRM, &osv, (struct sigvec *)0); -#endif - if (error) - return (XFER_TIMEOUT); - return (XFER_FAIL); -} - -/* - * Set flag saying to read was interrupted - * used for a read timer - */ -static SIG_FN -read_alarm() -{ - read_interrupted = 1; -} - -static int -netread(fd, buf, len, timeout) - int fd; - register char *buf; - register int len; - int timeout; -{ - static const char setitimerStr[] = "setitimer: %m"; - struct itimerval ival, zeroival; - register int n; -#if defined(sun) - int retries = 0; -#endif - - memset(&zeroival, 0, sizeof zeroival); - ival = zeroival; - ival.it_value.tv_sec = timeout; - while (len > 0) { - if (setitimer(ITIMER_REAL, &ival, NULL) < 0) { - syslog(LOG_ERR, setitimerStr); - return (-1); - } - errno = 0; - n = recv(fd, buf, len, 0); - if (n <= 0) { - if (errno == 0) { -#if defined(sun) - if (++retries < 42) /* doug adams */ - continue; -#endif - syslog(LOG_ERR, - "recv(len=%d): n=%d && !errno", - len, n); - return (-1); - } - if (errno == EINTR && !read_interrupted) { - /* Some other signal returned; ignore it. */ - continue; - } - syslog(LOG_ERR, "recv(len=%d): %m", len); - return (-1); - } - buf += n; - len -= n; - } - if (setitimer(ITIMER_REAL, &zeroival, NULL) < 0) { - syslog(LOG_ERR, setitimerStr); - return (-1); - } - return (0); -} - -static int -soa_zinfo(zp, cp, eom) - register struct zoneinfo *zp; - register u_char *cp; - u_char *eom; -{ - register int n; - - if (eom - cp < 3 * INT16SZ + INT32SZ) - return (-1); - cp += 3 * INT16SZ + INT32SZ; - if ((n = dn_skipname(cp, eom)) == -1) - return (-1); - cp += n; - if ((n = dn_skipname(cp, eom)) == -1) - return (-1); - cp += n; - if (eom - cp < 5 * INT32SZ) - return (-1); - 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); -} - -/* - * Parse the message, determine if it should be printed, and if so, print it - * in .db file form. - * Does minimal error checking on the message content. - */ -static int -print_output(msg, msglen, rrp) - u_char *msg; - int msglen; - u_char *rrp; -{ - register u_char *cp; - register HEADER *hp = (HEADER *) msg; - u_int32_t addr, ttl; - int i, j, tab, result, class, type, dlen, n1, n; - char data[BUFSIZ]; - 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); - if (n < 0) { - hp->rcode = FORMERR; - return (-1); - } - cp += n; - GETSHORT(type, cp); - GETSHORT(class, cp); - GETLONG(ttl, cp); - GETSHORT(dlen, cp); - - origin = strchr(dname, '.'); - if (origin == NULL) - origin = ""; - else - origin++; /* move past the '.' */ - dprintf(3, (ddt, - "print_output: dname %s type %d class %d ttl %d\n", - dname, type, class, ttl)); - /* - * Convert the resource record data into the internal database format. - */ - switch (type) { - case T_A: - case T_WKS: - case T_HINFO: - case T_UINFO: - case T_TXT: - case T_X25: - case T_ISDN: - case T_UID: - case T_GID: - cp1 = cp; - n = dlen; - cp += n; - break; - - case T_CNAME: - case T_MB: - case T_MG: - case T_MR: - case T_NS: - case T_PTR: - n = dn_expand(msg, msg + msglen, cp, data, sizeof data); - if (n < 0) { - hp->rcode = FORMERR; - return (-1); - } - cp += n; - cp1 = (u_char *)data; - n = strlen(data) + 1; - break; - - case T_MINFO: - case T_SOA: - case T_RP: - n = dn_expand(msg, msg + msglen, cp, data, sizeof data); - if (n < 0) { - hp->rcode = FORMERR; - return (-1); - } - cp += n; - n = strlen(data) + 1; - cp1 = (u_char *)data + n; - n1 = sizeof data - n; - if (type == T_SOA) - n1 -= 5 * INT32SZ; - 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; - if (type == T_SOA) { - temp_ptr = cp + 4 * INT32SZ; - GETLONG(minimum_ttl, temp_ptr); - n = 5 * INT32SZ; - bcopy((char *) cp, (char *) cp1, n); - cp += n; - cp1 += n; - } - n = cp1 - (u_char *)data; - cp1 = (u_char *)data; - break; - - case T_MX: - case T_AFSDB: - case T_RT: - /* grab preference */ - bcopy((char *)cp, data, INT16SZ); - cp1 = (u_char *)data + INT16SZ; - cp += INT16SZ; - - /* get name */ - n = dn_expand(msg, msg + msglen, cp, - (char *)cp1, sizeof data - INT16SZ); - if (n < 0) - return (-1); - cp += n; - - /* compute end of data */ - cp1 += strlen((char *) cp1) + 1; - /* compute size of data */ - n = cp1 - (u_char *)data; - cp1 = (u_char *)data; - break; - - default: - dprintf(3, (ddt, "unknown type %d\n", type)); - return ((cp - rrp) + dlen); - } - if (n > MAXDATA) { - dprintf(1, (ddt, - "update type %d: %d bytes is too much data\n", - type, n)); - hp->rcode = NOCHANGE; /* XXX - FORMERR ??? */ - return (-1); - } - cdata = (char *) cp1; - result = cp - rrp; - - /* - * Only print one SOA per db file - */ - if (type == T_SOA) { - if (got_soa) - return (result); - else - got_soa++; - } - -#ifdef NO_GLUE - /* - * If they are trying to tell us info about something that is - * not in the zone that we are transfering, then ignore it! - * They don't have the authority to tell us this info. - * - * We have to do a bit of checking here - the name that we are - * checking vs is fully qualified & may be in a subdomain of the - * zone in question. We also need to ignore any final dots. - * - * If a domain has both NS records and non-NS records, (for - * example, NS and MX records), then we should ignore the non-NS - * records (except that we should not ignore glue A records). - * XXX: It is difficult to do this properly, so we just compare - * the current dname with that in the most recent NS record. - * This defends against the most common error case, - * where the remote server sends MX records soon after the - * NS records for a particular domain. If sent earlier, we lose. XXX - */ - if (!samedomain(dname, domain)) { - (void) fprintf(dbfp, "; Ignoring info about %s, not in zone %s.\n", - dname, domain); - ignore = "; "; - } else if (type != T_NS && type != T_A && - strcasecmp(zone_top, dname) != 0 && - strcasecmp(prev_ns_dname, dname) == 0) - { - (void) fprintf(dbfp, "; Ignoring extra info about %s, invalid after NS delegation.\n", - dname); - ignore = "; "; - } -#endif /*NO_GLUE*/ - - /* - * If the current record is not being ignored, but the - * previous record was ignored, then we invalidate information - * that might have been altered by ignored records. - * (This means that we sometimes output unnecessary $ORIGIN - * lines, but that is harmless.) - * - * Also update prev_comment now. - */ - if (prev_comment && ignore[0] == '\0') { - prev_dname[0] = DEF_DNAME; - prev_origin[0] = DEF_DNAME; - } - prev_comment = (ignore[0] != '\0'); - - /* - * set prev_ns_dname if necessary - */ - if (type == T_NS) { - (void) strcpy(prev_ns_dname, dname); - } - - /* - * If the origin has changed, print the new origin - */ - if (strcasecmp(prev_origin, origin)) { - (void) strcpy(prev_origin, origin); - (void) fprintf(dbfp, "%s$ORIGIN %s.\n", ignore, origin); - } - tab = 0; - - if (strcasecmp(prev_dname, dname)) { - /* - * set the prev_dname to be the current dname, then cut off all - * characters of dname after (and including) the first '.' - */ - char *cutp = strchr(dname, '.'); - - (void) strcpy(prev_dname, dname); - if (cutp) - *cutp = '\0'; - - if (dname[0] == 0) { - if (origin[0] == 0) - (void) fprintf(dbfp, "%s.\t", ignore); - else - (void) fprintf(dbfp, "%s.%s.\t", - ignore, origin); /* ??? */ - } else - (void) fprintf(dbfp, "%s%s\t", ignore, dname); - if (strlen(dname) < 8) - tab = 1; - } else { - (void) fprintf(dbfp, "%s\t", ignore); - tab = 1; - } - - if (ttl != 0 && ttl != minimum_ttl) - (void) fprintf(dbfp, "%d\t", (int) ttl); - else if (tab) - (void) putc('\t', dbfp); - - (void) fprintf(dbfp, "%s\t%s\t", p_class(class), p_type(type)); - cp = (u_char *) cdata; - - /* - * Print type specific data - */ - switch (type) { - - case T_A: - switch (class) { - case C_IN: - case C_HS: - GETLONG(n, cp); - n = htonl(n); - (void) fprintf(dbfp, "%s", - inet_ntoa(*(struct in_addr *) & n)); - break; - } - (void) fprintf(dbfp, "\n"); - break; - - case T_CNAME: - case T_MB: - case T_MG: - case T_MR: - case T_PTR: - if (cp[0] == '\0') - (void) fprintf(dbfp, ".\n"); - else - (void) fprintf(dbfp, "%s.\n", cp); - break; - - case T_NS: - cp = (u_char *) cdata; - if (cp[0] == '\0') - (void) fprintf(dbfp, ".\t"); - else - (void) fprintf(dbfp, "%s.", cp); - (void) fprintf(dbfp, "\n"); - break; - - 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); - } - (void) putc(*cp++, dbfp); - } - (void) fputs("\"\n", dbfp); - break; - - case T_SOA: - (void) fprintf(dbfp, "%s.", cp); - cp += strlen((char *) cp) + 1; - (void) fprintf(dbfp, " %s. (\n", cp); - cp += strlen((char *) cp) + 1; - GETLONG(n, cp); - (void) fprintf(dbfp, "%s\t\t%lu", ignore, n); - GETLONG(n, cp); - (void) fprintf(dbfp, " %lu", n); - GETLONG(n, cp); - (void) fprintf(dbfp, " %lu", n); - GETLONG(n, cp); - (void) fprintf(dbfp, " %lu", n); - GETLONG(n, cp); - (void) fprintf(dbfp, " %lu )\n", n); - break; - - case T_MX: - case T_AFSDB: - case T_RT: - GETSHORT(n, cp); - (void) fprintf(dbfp, "%lu", n); - (void) fprintf(dbfp, " %s.\n", cp); - break; - - case T_TXT: - case T_X25: - cp1 = cp + n; - (void) putc('"', dbfp); - while (cp < cp1) { - if (i = *cp++) { - for (j = i ; j > 0 && cp < cp1 ; j--) { - if ((*cp == '\n') || (*cp == '"')) { - (void) putc('\\', dbfp); - } - (void) putc(*cp++, dbfp); - } - } - } - (void) fputs("\"\n", dbfp); - break; - - case T_NSAP: - fprintf(dbfp, "%s\n", inet_nsap_ntoa(n, cp, NULL)); - break; - - case T_UINFO: - (void) fprintf(dbfp, "\"%s\"\n", cp); - break; - - case T_UID: - case T_GID: - if (n == INT32SZ) { - GETLONG(n, cp); - (void) fprintf(dbfp, "%lu\n", n); - } - break; - - case T_WKS: - GETLONG(addr, cp); - addr = htonl(addr); - (void) fprintf(dbfp, "%s ", - inet_ntoa(*(struct in_addr *) & addr)); - proto = protocolname(*cp); - cp += sizeof(char); - (void) fprintf(dbfp, "%s ", proto); - i = 0; - while (cp < (u_char *) cdata + n) { - j = *cp++; - do { - if (j & 0200) - (void) fprintf(dbfp, " %s", - servicename(i, proto)); - j <<= 1; - } while (++i & 07); - } - (void) fprintf(dbfp, "\n"); - break; - - case T_MINFO: - case T_RP: - (void) fprintf(dbfp, "%s.", cp); - cp += strlen((char *) cp) + 1; - (void) fprintf(dbfp, " %s.\n", cp); - break; - - default: - (void) fprintf(dbfp, "???\n"); - } - if (ferror(dbfp)) { - syslog(LOG_ERR, "%s: %m", tmpname); - exit(XFER_FAIL); - } - return (result); -} - -#ifdef SHORT_FNAMES -/* -** This routine handles creating temporary files with mkstemp -** in the presence of a 14 char filename system. Pathconf() -** does not work over NFS. -*/ -filenamecpy(ddtfile, optarg) -char *ddtfile, *optarg; -{ - int namelen, extra, len; - char *dirname, *filename; - - /* determine the length of filename allowed */ - if((dirname = strrchr(optarg, '/')) == NULL){ - filename = optarg; - } else { - *dirname++ = '\0'; - filename = dirname; - } - namelen = pathconf(dirname == NULL? "." : optarg, _PC_NAME_MAX); - if(namelen <= 0) - namelen = 255; /* length could not be determined */ - if(dirname != NULL) - *--dirname = '/'; - - /* copy a shorter name if it will be longer than allowed */ - extra = (strlen(filename)+strlen(".XXXXXX")) - namelen; - if(extra > 0){ - len = strlen(optarg) - extra; - (void) strncpy(ddtfile, optarg, len); - ddtfile[len] = '\0'; - } else - (void) strcpy(ddtfile, optarg); -} -#endif /* SHORT_FNAMES */ |