summaryrefslogtreecommitdiffstats
path: root/contrib/bind
diff options
context:
space:
mode:
authorpeter <peter@FreeBSD.org>1996-08-29 19:20:22 +0000
committerpeter <peter@FreeBSD.org>1996-08-29 19:20:22 +0000
commit2d3cf9fcaf1ca2528c5fe3ba683d1f6c1268dc41 (patch)
tree8652a0312f865a787c6c1c3003491b4e62ce0ea7 /contrib/bind
downloadFreeBSD-src-2d3cf9fcaf1ca2528c5fe3ba683d1f6c1268dc41.zip
FreeBSD-src-2d3cf9fcaf1ca2528c5fe3ba683d1f6c1268dc41.tar.gz
Take #2. Import bind-4.9.4-P1 into the intended directory!
This has most of the non-essential stuff removed (ie: what is not built) bmake glue to follow.
Diffstat (limited to 'contrib/bind')
-rw-r--r--contrib/bind/CHANGES2600
-rw-r--r--contrib/bind/INSTALL74
-rw-r--r--contrib/bind/Makefile783
-rw-r--r--contrib/bind/OPTIONS412
-rw-r--r--contrib/bind/README483
-rw-r--r--contrib/bind/TODO187
-rwxr-xr-xcontrib/bind/conf/bsdinstall.sh251
-rw-r--r--contrib/bind/conf/copyright50
-rw-r--r--contrib/bind/conf/master/README45
-rw-r--r--contrib/bind/conf/master/named.boot18
-rw-r--r--contrib/bind/conf/master/named.boot.master16
-rw-r--r--contrib/bind/conf/master/named.hosts22
-rw-r--r--contrib/bind/conf/master/named.local13
-rw-r--r--contrib/bind/conf/master/named.rev30
-rw-r--r--contrib/bind/conf/master/root.cache63
-rw-r--r--contrib/bind/conf/options.h167
-rw-r--r--contrib/bind/conf/portability.h595
-rw-r--r--contrib/bind/doc/bog/00macs.me51
-rw-r--r--contrib/bind/doc/bog/00title.me94
-rw-r--r--contrib/bind/doc/bog/Makefile90
-rw-r--r--contrib/bind/doc/bog/ack.me287
-rw-r--r--contrib/bind/doc/bog/build.me102
-rw-r--r--contrib/bind/doc/bog/files.me1150
-rw-r--r--contrib/bind/doc/bog/intro.me75
-rw-r--r--contrib/bind/doc/bog/manage.me156
-rw-r--r--contrib/bind/doc/bog/named.boot.cache77
-rw-r--r--contrib/bind/doc/bog/named.boot.primary78
-rw-r--r--contrib/bind/doc/bog/named.boot.secondary77
-rw-r--r--contrib/bind/doc/bog/named.local75
-rw-r--r--contrib/bind/doc/bog/ns.me96
-rw-r--r--contrib/bind/doc/bog/resolv.conf67
-rw-r--r--contrib/bind/doc/bog/root.cache102
-rw-r--r--contrib/bind/doc/bog/setup.me88
-rw-r--r--contrib/bind/doc/bog/types.me163
-rw-r--r--contrib/bind/doc/bog/ucbhosts118
-rw-r--r--contrib/bind/doc/bog/ucbhosts.rev86
-rw-r--r--contrib/bind/doc/misc/FAQ.1of21339
-rw-r--r--contrib/bind/doc/misc/FAQ.2of21131
-rw-r--r--contrib/bind/doc/misc/IPv672
-rw-r--r--contrib/bind/doc/misc/dns-setup1081
-rw-r--r--contrib/bind/doc/misc/style.txt172
-rw-r--r--contrib/bind/include/Makefile74
-rw-r--r--contrib/bind/include/arpa/Makefile67
-rw-r--r--contrib/bind/include/arpa/inet.h88
-rw-r--r--contrib/bind/include/arpa/nameser.h346
-rw-r--r--contrib/bind/include/netdb.h170
-rw-r--r--contrib/bind/include/resolv.h254
-rw-r--r--contrib/bind/man/Makefile451
-rw-r--r--contrib/bind/man/dig.1364
-rw-r--r--contrib/bind/man/dnsquery.1164
-rw-r--r--contrib/bind/man/gethostbyname.3226
-rw-r--r--contrib/bind/man/getnetent.3133
-rw-r--r--contrib/bind/man/host.1207
-rw-r--r--contrib/bind/man/hostname.7108
-rw-r--r--contrib/bind/man/mailaddr.7135
-rw-r--r--contrib/bind/man/named-xfer.8146
-rw-r--r--contrib/bind/man/named.8435
-rw-r--r--contrib/bind/man/named.reload.869
-rw-r--r--contrib/bind/man/named.restart.873
-rw-r--r--contrib/bind/man/ndc.8127
-rw-r--r--contrib/bind/man/nslookup.8387
-rw-r--r--contrib/bind/man/resolver.3339
-rw-r--r--contrib/bind/man/resolver.5133
-rw-r--r--contrib/bind/named/Makefile196
-rw-r--r--contrib/bind/named/Makefile.reno83
-rw-r--r--contrib/bind/named/Version.c88
-rw-r--r--contrib/bind/named/db_defs.h183
-rw-r--r--contrib/bind/named/db_dump.c924
-rw-r--r--contrib/bind/named/db_func.h113
-rw-r--r--contrib/bind/named/db_glob.h93
-rw-r--r--contrib/bind/named/db_glue.c835
-rw-r--r--contrib/bind/named/db_load.c1501
-rw-r--r--contrib/bind/named/db_lookup.c249
-rw-r--r--contrib/bind/named/db_reload.c126
-rw-r--r--contrib/bind/named/db_save.c208
-rw-r--r--contrib/bind/named/db_secure.c153
-rw-r--r--contrib/bind/named/db_update.c737
-rw-r--r--contrib/bind/named/dmalloc.c315
-rw-r--r--contrib/bind/named/dmalloc.h68
-rw-r--r--contrib/bind/named/named-xfer.c1644
-rw-r--r--contrib/bind/named/named.h19
-rw-r--r--contrib/bind/named/named.reload.sh7
-rw-r--r--contrib/bind/named/named.restart.sh7
-rw-r--r--contrib/bind/named/ndc.sh83
-rw-r--r--contrib/bind/named/ns_defs.h397
-rw-r--r--contrib/bind/named/ns_forw.c1094
-rw-r--r--contrib/bind/named/ns_func.h166
-rw-r--r--contrib/bind/named/ns_glob.h291
-rw-r--r--contrib/bind/named/ns_init.c1110
-rw-r--r--contrib/bind/named/ns_main.c1669
-rw-r--r--contrib/bind/named/ns_maint.c1100
-rw-r--r--contrib/bind/named/ns_ncache.c154
-rw-r--r--contrib/bind/named/ns_req.c2179
-rw-r--r--contrib/bind/named/ns_resp.c2743
-rw-r--r--contrib/bind/named/ns_sort.c171
-rw-r--r--contrib/bind/named/ns_stats.c399
-rw-r--r--contrib/bind/named/ns_validate.c1246
-rw-r--r--contrib/bind/named/pathnames.h122
-rw-r--r--contrib/bind/named/storage.c205
-rw-r--r--contrib/bind/named/tree.c570
-rw-r--r--contrib/bind/named/tree.h48
-rw-r--r--contrib/bind/named/tree.man3154
-rw-r--r--contrib/bind/res/Makefile115
-rw-r--r--contrib/bind/res/gethnamaddr.c927
-rw-r--r--contrib/bind/res/getnetbyaddr.c57
-rw-r--r--contrib/bind/res/getnetbyname.c64
-rw-r--r--contrib/bind/res/getnetent.c163
-rw-r--r--contrib/bind/res/getnetnamadr.c288
-rw-r--r--contrib/bind/res/herror.c119
-rw-r--r--contrib/bind/res/hostnamelen.c94
-rw-r--r--contrib/bind/res/inet_addr.c184
-rw-r--r--contrib/bind/res/inet_ntop.c195
-rw-r--r--contrib/bind/res/inet_pton.c215
-rw-r--r--contrib/bind/res/nsap_addr.c114
-rw-r--r--contrib/bind/res/res_comp.c535
-rw-r--r--contrib/bind/res/res_data.c115
-rw-r--r--contrib/bind/res/res_debug.c1225
-rw-r--r--contrib/bind/res/res_init.c651
-rw-r--r--contrib/bind/res/res_mkquery.c250
-rw-r--r--contrib/bind/res/res_query.c392
-rw-r--r--contrib/bind/res/res_send.c783
-rw-r--r--contrib/bind/res/sethostent.c63
-rw-r--r--contrib/bind/tools/Makefile163
-rw-r--r--contrib/bind/tools/addr.c173
-rw-r--r--contrib/bind/tools/dig.c1236
-rw-r--r--contrib/bind/tools/dnsquery.c239
-rw-r--r--contrib/bind/tools/host.c1471
-rw-r--r--contrib/bind/tools/nslookup/Makefile129
-rw-r--r--contrib/bind/tools/nslookup/commands.l219
-rw-r--r--contrib/bind/tools/nslookup/debug.c590
-rw-r--r--contrib/bind/tools/nslookup/getinfo.c843
-rw-r--r--contrib/bind/tools/nslookup/list.c1071
-rw-r--r--contrib/bind/tools/nslookup/main.c1119
-rw-r--r--contrib/bind/tools/nslookup/nslookup.help34
-rw-r--r--contrib/bind/tools/nslookup/pathnames.h71
-rw-r--r--contrib/bind/tools/nslookup/res.h172
-rw-r--r--contrib/bind/tools/nslookup/send.c412
-rw-r--r--contrib/bind/tools/nslookup/skip.c211
-rw-r--r--contrib/bind/tools/nslookup/subr.c583
139 files changed, 53867 insertions, 0 deletions
diff --git a/contrib/bind/CHANGES b/contrib/bind/CHANGES
new file mode 100644
index 0000000..0379d50
--- /dev/null
+++ b/contrib/bind/CHANGES
@@ -0,0 +1,2600 @@
+$Id: CHANGES,v 8.40 1996/08/05 08:31:20 vixie Exp $
+
+ --- 4.9.4-p1 released ---
+
+657. [bug] some configurations were mistakenly disabling cache purges.
+
+656. [doc] "\ " was causing a line break in zone file parsing.
+
+655. [doc] named(8) wasn't describing the "response" literal.
+
+654. [doc] formatting errors fixed in include/arpa/nameser.h.
+
+653. [doc] doc/misc/DynamicUpdate now has a deprecating comment.
+
+652. [bug] BSD/nslookup/Makefile was making the wrong links.
+
+651. [bug] a hashing function should be as simple as possible,
+ but not simpler.
+
+650. [bug] dn_mailok() could walk off the end of the name buffer.
+
+649. [bug] bad names were not exiting through the right code path.
+
+648. [bug] we were referencing dynamic memory after free()'ing it.
+
+647. [bug] savename() was bzero()'ing the wrong number of bytes.
+
+646. [bug] ctypes.h needed to be included in res/res_debug.c.
+
+645. [port] sys/types.h needed to be included in a lot of places.
+
+ --- 4.9.4-rel released ---
+
+644. [bug] gethnamadr.c:getanswer() wasn't decrementing buflen.
+
+643. [contrib] new contrib/misc/gencidrzone.
+
+ --- 4.9.4-t5b released ---
+
+642. [bug] SOA serial checking was not trying backup servers.
+
+641. [doc] added doc/rfc/rfc1713.
+
+640. [bug] don't try to purge the cache on nonrecursive servers.
+
+639. [bug] sysquery() was not recovering from lack of root servers.
+
+638. [bug] dnsquery.c wasn't calling res_init().
+
+637. [bug] ns_resp() was erroneously detecting name errors.
+
+636. [bug] nslookup() was returning failure even when fwdrs were avail.
+
+635. [bug] inet_pton() was returning EINVAL rather than EAFNOSUPPORT.
+
+ --- 4.9.4-t4b released ---
+
+634. [bug] named-xfer was writing AAAA RRs to the wrong file pointer.
+
+633. [port] ULTRIX and RISCOS both need NEED_STRDUP in conf/portability.h.
+
+632. [bug] BSD/named/Makefile was installing its man page in section 1.
+
+ --- 4.9.4-t4a released ---
+
+631. [bug] nslookup was dumping core on bad 'server' commands.
+
+630. [bug] dig was not able to print SRV RRs.
+
+629. [bug] dig was seeing artificial protocol errors printing AAAA RRs.
+
+ --- 4.9.4-t3b released ---
+
+628. [bug] "stub ." changes were being updated in the wrong place.
+
+627. [bug] forgot to remove fourth arg from inet_pton() in tools/addr.c.
+
+626. [port] was missing -DSPRINTF_CHAR in one spot in the top Makefile.
+
+ --- 4.9.4-t3a released ---
+
+625. [api] inet_pton()'s signature changed due to ipng@sunroof discussion.
+
+624. [port] shres/* should work again (was broken by inet_ntop, inet_pton)
+
+623. [bug] sprintf() doesn't return "int" on DomainOS, either.
+
+ --- 4.9.4-t2a released ---
+
+622. [bug] sprintf() doesn't return "int" on SunOS or ULTRIX.
+
+ --- 4.9.4-t1a released ---
+
+622. [bug] more print errors in the name validation logic fixed.
+
+621. [feature] added support for IPv6 addresses to the resolver and daemon.
+ see doc/misc/IPv6 for details.
+
+620. [perf] XSTATS off by default. client stats now in XSTATS.
+
+619. [conf] LOC_RR is on by default (it's an RFC now).
+
+618. [perf] pulled in memory saving NAME,NAMELEN,NAMESIZE logic from
+ development source pool.
+
+617. [bug] we were logging at INFO priority even when not loading a
+ zone due to certain kinds of database format errors.
+
+616. [bug] truncated responses were not being forwarded.
+
+615. [contrib] added contrib/misc/gencidrzone.pl, updated contrib/host.
+
+614. [bug] minor and latent bug in dcalloc() fixed.
+
+613. [bug] the RFC952 + "_" code wasn't strict enough.
+
+612. [bug] the PTR name check was using ipv6.int rather than ip6.int.
+
+611. [conf] changed "check-names forwarded" to "check-names response".
+
+610. [doc] man page said check-name, should have said check-names.
+
+609. [bug] in res_send(), query ID mismatches weren't handled in VC's.
+
+608. [bug] res_send() would overrun its buffer when parsing truncated
+ replies for its diagnostic output.
+
+607. [bug] EINTR wasn't causing a select() restart in res_send.
+
+606. [bug] fixed a race condition related to SO_LINGER.
+
+605. [bug] some "lame delegation" messages were printing wrong information
+
+604. [bug] uncached out of zone CNAMEs were returning SERVFAIL rather
+ than timing out; this prevented the client from retrying.
+
+603. [bug] lame delegations will now try other servers rather than just
+ SERVFAIL'ing. the old behaviour was too draconian.
+
+602. [security] we were cycling back through the volatile cache when searching
+ for glue to match the bootstrap cache.
+
+601. [bug] we were not recognizing upward zone cuts in some circumstances
+
+600. [API bug] getnetbyaddr() was taking a long, rather than a u_long.
+
+599. [bug] PX RRs were not properly handled by named-xfer.c.
+
+598. [bug] WKS RRs were written incorrectly in db_dump.c.
+
+597. [bug] named would not create a brand new pid file.
+
+596. [bug] memory leak in ns_resp.c plugged.
+
+595. [bug] another wildcarding bug (in ns_maint.c) stomped.
+
+594. [contrib] added contrib/misc/settransfer-gaine.shar.
+
+593. [security] db_load() will allow invalid SOA ANAMEs, for now.
+
+592. [bug] dig and nslookup needed code from 4.9.4-T1A for AXFR (#589).
+
+591. [bug] dig and nslookup both dumped core if dn_expand() failed.
+
+590. [port] changed __RES to 19960229 due to dn_isvalid() API addition.
+
+589. [bug] named-xfer was unable to handle some compliant AXFR streams.
+
+588. [security] call dn_isvalid() from db_load() to catch zone naming errors.
+
+587. [security] added function dn_isvalid(), called from dn_expand(), per CERT.
+
+586. [bug] dangling NS RR's (no A RR's in cache) weren't recoverable.
+
+585. [bug] named was ignoring the cache for "." even after priming.
+
+584. [bug] ns_resp() could dump core during some kinds of query restarts.
+
+583. [bug] default logging priority for lame delegations now LOG_DEBUG.
+
+582. [doc] added RFC 1912 which expands upon RFC 1537.
+
+581. [port] BSD really does not have SIGIOT any more, stop using it.
+
+580. [bug] getnetent() could mangle /etc/networks input lines.
+
+579. [bug] db_dump was printing -1 for TTL wherever default TTL was used.
+
+578. [port] many scanf/printf patterns misused %lu, DEC AXP didn't like it.
+
+577. [bug] named-xfer and res_debug were mishandling "\\" in TXT/HINFO.
+
+576. [bug] "limit" directive was setting current but not max system limit.
+
+ --- 4.9.3-p1 released ---
+
+575. [port] Ultrix/Hesiod named responses are oversized, we were
+ incorrectly accepting them and then overwriting the stack.
+
+574. [port] BSD/OS 2.1 required some ./BSD/Makefile changes.
+
+ --- 4.9.3-rel released ---
+
+573. [contrib] put in "951231" version of contrib/host.
+
+572. [doc] new file doc/info/SCO-2 concerning <sys/param.h> porting.
+
+571. [bug] zones whose master files contained only $INCLUDEs were
+ incorrectly considered to not have any RR's (old bug.)
+
+570. [doc] trivial man/named.8 tweak.
+
+569. [doc] minor documentation tweak to shres/solaris/ISSUES.
+
+ --- 4.9.3-beta34 released ---
+
+568. [bug] very minor initialization bug fixed in tools/dig.c.
+
+567. [bug] disabled VALIDATE; all this code is trash and will be removed
+ along with ALLOW_UPDATES very early in the next alpha cycle.
+ we are now back to the B26 level of stability, with several
+ minor bug fixes from intervening betas.
+
+566. [bug] fixed memory leak introduced in #565.
+
+ --- 4.9.3-beta33 released ---
+
+565. [proto] we were generating truncated RRsets due to VALIDATE bugs.
+
+564. [proto] we weren't stopping early enough on some kinds of truncation.
+
+563. [doc] added doc/info/Solaris, concerning Sun Patch-ID# 102165-02.
+
+562. [bug] named/ns_resp.c had an overzealous #ifdef.
+
+561. [port] tools/nslookup/getinfo.c had an ANSI C nit.
+
+560. [port] shres/netbsd and Makefile's netbsd stuff was wrong.
+
+559. [doc] shres/* documentation had more pathname problems.
+
+558. [port] SCO OSE5 portability problem (minor).
+
+557. [doc] added doc/misc/style.txt out of my archives.
+
+556. [contrib] updated contrib/arlib, contrib/dnsparse (really!).
+
+555. [bug] quoted newlines were still broken even after #509.
+
+554. [bug] dangling CNAME cache chains could make named dump core.
+
+553. [bug] forwarders didn't work well with VALIDATE.
+
+ --- 4.9.3-beta32 released ---
+
+552. [doc] ./Makefile had some out of date comments.
+
+551. [bug] shres/sunos/* needed some fine tuning.
+
+550. [contrib] contrib/dnsparse replaced with a later version.
+
+ --- 4.9.3-beta31 released ---
+
+549. [bug] "make links" hadn't been tested in a while; shres/* req'd chg.
+
+548. [bug] shres/sunos/* needed some fixups due to a late Sun patch.
+
+547. [doc] Makefile comments for Linux were out of date.
+
+546. [doc] OPTIONS had an incorrect path name and some factual errors.
+
+545. [bug] shres/sunos/Makefile had some incorrect path names.
+
+ --- 4.9.3-beta30 released ---
+
+544. [port] some systems with broken CPP's wouldn't compile ns_req.c.
+
+543. [bug] query restart bug in ns_resp.c.
+
+ --- 4.9.3-beta29 released ---
+
+542. [port] rearranged signal() calls to make POSIX + SYSV possible.
+
+541. [port] padded _res to 512 bytes; moved initialized data to res_data.c.
+
+540. [port] added experimental shres/netbsd/ directory.
+
+539. [bug] we weren't able to load 0 ttl's in zone files.
+
+538. [doc] BOG corrections.
+
+ --- 4.9.3-beta28 never released ---
+
+537. [contrib] new contrib/lamers/ directory.
+
+536. [bug] there was a possible deadlock condition over missing glue.
+
+535. [bug] previous patch to db_load() was misapplied.
+
+534. [bug] several ancient cache corruption bugs fixed in ns_resp().
+
+533. [root] root servers required a new ``no-fetch-glue'' option.
+
+532. [bug] all kinds of stuff was broken under shres/ due to new subdir.
+
+ --- 4.9.3-beta27 released ---
+
+531. [bug] limited support for labels containing \. (literal dot.)
+
+530. [bug] new root.cache file imported from internic.
+
+529. [bug] another set of bug fixes to the zone transfer scheduler.
+
+528. [bug] VALIDATE reenabled but without packet editing.
+
+527. [bug] glue passing through CNAMEs will now be cached properly.
+
+526. [bug] deleted zones should no longer cause core dumps.
+
+525. [func] several messages changed to be more informative.
+
+524. [bug] loc_ntoa() was returning a pointer to a stack variable.
+
+523. [bug] wildcard RR's were being deleted by purge_zone().
+
+522. [bug] "ndc start" didn't work if no pid file existed.
+
+521. [port] Sun SVR4 fixes, including shared library support.
+
+520. [bug] we weren't using "forwarders" if "options forward_only"
+ wasn't set (in some cases.)
+
+519. [bug] named-xfer wasn't called res_init().
+
+518. [bug] lots of byte order nits.
+
+517. [bug] "tools/host -a" now prints in RR format again.
+
+516. [proto] minimum TTL changes from five minutes to zero seconds.
+
+515. [bug] SOA TTL of zero is no longer considered an error.
+
+514. [bug] division by zero error corrected in ns_refreshtime().
+
+513. [bug] we had the #ifdefs nexted backwards in <netdb.h>.
+
+512. [bug] we were able to dump core while tracing due to a NULL pointer.
+
+511. [bug] DiG wasn't able to suppress all of res_debug.c's comments.
+
+510. [doc] BOG typos. new doc/misc/FAQ. new site in MIRRORS.
+
+509. [bug] another side effect of the inet_aton() change was fixed,
+ this time it was breaking escaped newlines in named.boot.
+
+508. [contrib] new contrib/host, contrib/misc/settransfer, contrib/msql.
+ contrib/umich/lame_delegation was withdrawn by the author.
+
+507. [bug] DiG didn't do ndots and was trigger happy about options.
+
+506. [port] NextStep, Interactive, SCO, Digital UNIX, ULTRIX improvements.
+
+505. [bug] we were overly restrictive about nonauthoritative NXDOMAINs.
+
+504. [bug] named was generating corrupt responses in au truncation.
+
+503. [port] shres/* now supports SunOS 4.1.4.
+
+502. [bug] nslookup wasn't behaving properly in the presence of "ndots".
+
+501. [bug] we now delay 5 seconds after an "ndc restart" or "ndc start".
+
+500. [bug] change #494 was incomplete.
+
+ --- 4.9.3-beta26 released ---
+
+499. [bug] we needed a SERVFAIL in an error case.
+
+498. [bug] some recently added byte order bugs were stomped;
+ data_inaddr() was made slightly more conservative.
+
+497. [port] local_hostname_length() moved to its own source file.
+
+496. [bug] Beta25's change to compat/Makefile was wrong.
+
+495. [bug] tools/host.c wasn't processing cnames properly.
+
+ --- 4.9.3-beta25 released ---
+
+494. [func] "include" directive in boot file is no longer fatal if the
+ specified file doesn't exist or is not readable.
+
+493. [bug] new interfaces' UDP sockets weren't affecting select()'s mask.
+
+492. [doc] another round of changes and cleanups to the BOG.
+
+491. [bug] various cleanups to lame server detection.
+
+490. [port] completely new shres/* from CKD.
+
+489. [doc] added a ***NOTE*** to ./INSTALL about operating system files.
+
+488. [port] GNU C Library changes for include/netdb.h.
+
+487. [func] named will try a little bit longer to bind() its stream socket.
+
+486. [contrib] new packages: contrib/inaddrtool and contrib/trnamed.
+
+485. [func] ns_forw will no longer forward to 0.0.0.0, 255.255.255.255,
+ or 127.0.0.1.
+
+484. [port] more POSIX_SIGNALS conversions.
+
+483. [bug] compat/Makefile wasn't passing on all definitions to submakes.
+
+482. [port] bad bug in NeXT C Library worked around.
+
+481. [doc] RFC 1794 is now included in doc/rfc.
+
+480. [bug] a debugging printf() was accessing freed memory.
+
+479. [port] doc/info/NCR has been replaced.
+
+478. [port] doc/info/interactive has been replaced by its author.
+
+477. [port] UNIXWARE 2.X changes.
+
+476. [bug] ns_init.c was creating files in "//tmp" rather than "/tmp".
+
+475. [bug] inet_aton() reverts to mostly previous behaviour.
+
+474. [bug] PTR->CNAME support added; name test fixed.
+
+473. [func] added gethostbyname2(), improved its man page.
+
+472. [port] Linux connect() can reconnect, res/res_send.c now knows this.
+
+471. [build] several "clean" targets were not removing ".depend" files.
+
+470. [bug] dqflush() was using memory after free()ing it and never closing
+ any file descriptors and not clearing select()'s mask bits.
+
+ --- 4.9.3-beta24 released ---
+
+469. [bug] We no longer share static return buffers across functions in
+ res_debug.c.
+
+468. [logging] An extraneous haveComplained() was removed from ns_resp.c.
+
+467. [portdoc] Linux build doc changes.
+
+ --- 4.9.3-beta23 released ---
+
+466. [doc] big reorg to BOG.
+
+465. [doc] minor corrections to man pages.
+
+464. [port] NEC Makefile changes.
+
+463. [contrib] random updates.
+
+462. [bug] res_send() wasn't always clearing errno, which led to
+ false-negative return conditions.
+
+461. [port] minor u_char-vs-char lint removed.
+
+460. [port] backed out a recent Linux portability change.
+
+ --- 4.9.3-beta22 released ---
+
+459. [port] made a major lint pass.
+
+458. [func] paved over a bad security hole in named-xfer.
+
+457. [bug] negative caching vs (secure_zone | cname checking) bugs.
+
+456. [port] moved all:: target to be first in top level Makefile.
+
+455. [bug] res/res_send.c had a bad macro definition.
+
+454. [doc] RUNSON moved to doc/info. MIRRORS file added.
+
+453. [quality] learntFrom() was reformatted.
+
+452. [doc] minor changes for shlib/ISSUES, tools/nslookup/nslookup.help.
+
+451. [port] linux, NCR, Solaris, NExT portability changes.
+
+450. [func] added RES_NOALIASES flag, needed for security.
+
+449. [bug] we were defining a nonstandard DNS header flag as PR. no more.
+
+ --- 4.9.3-beta21 released ---
+
+448. [port] systems with hundreds of network interfaces need big ioctl()'s.
+
+447. [func] zones without NS RR's or with mismatching SOA RR's are caught.
+
+446. [bug] miscellaneous fixes to res/gethnamaddr.c.
+
+445. [bug] the secure_zone logic was incomplete.
+
+444. [bug] bootfile "options" parsing was broken.
+
+443. [bug] named-xfer was munging incoming WKS RR's.
+
+442. [contrib] various cleanups.
+
+ --- 4.9.3-beta20 released ---
+
+441. [contrib] put in DOC 2.1.1.
+
+440. [func] change/addition to the "lame delegation" syslog message.
+
+439. [bug] emulation macros WIFSIGNALED and WIFEXITED were bogus.
+
+438. [bug] missing "#ifndef INVQ" added.
+
+437. [doc] man pages and BOG updated to include new B18/B19 features.
+
+436. [port] PIDDIR definition removed from Solaris 2.X.
+
+435. [port] shres/Makefile fixed for new location of inet_addr.c.
+
+434. [port] getnetnamaddr.c had a spurious "#if defined(sun)"
+
+433. [bugs] random typos and glitches from the beta19 afternoon rush.
+
+ --- 4.9.3-beta19 released ---
+
+432. [func] we should be much more resistant to root cache corruption now.
+
+431. [bug] tcp socket send buffer will now be set at 16K to avoid blocks.
+
+430. [bug] ns_req.c had two cases where it could overflow a buffer.
+
+429. [bug] the "." zone will now respect the setting of NO_GLUE.
+
+428. [func] 0.0.0.0 A RR's are allowed in the DB but we won't use them.
+
+427. [func] "options fake-iquery" added, users of Sun nslookup take note.
+
+426. [port] include/netdb.h now has some #ifdef sun defs in it.
+
+425. [bug] negative caching bugs in findns() and in ns_forw.c.
+
+424. [func] "limit transfers-per-ns" directive added.
+
+423. [bug] infinite loop fixed in named-xfer.c's version number printing.
+
+422. [bug] gethostbyname() of a dotted quad in an auto variable will
+ no longer cause the caller to consume random stack trash.
+
+421. [port] inet_aton() has moved from lib44bsd.a back to libresolv.a.
+
+420. [func] any punctuation character can now terminate an inet_aton().
+
+419. [port] use sigemptyset(), sigaddset() - in preference to sigmask().
+
+ --- 4.9.3-beta18 released ---
+
+418. [bug] ``close(11): interrupted system call'' now fixed.
+
+417. [bug] big name servers would never refresh all their zones since
+ tryxfer() wasn't a "fair" scheduler. it is now.
+
+416. [func] SOA syntax errors will now lead to dead zones, not dead srvrs.
+
+415. [func] expiration values lower than refresh values cause a warning.
+
+414. [func] added "options" and "limit" directives to named.boot.
+
+413. [port] new file: doc/info/solaris.too.
+
+412. [bug] possible div-by-zero in ns_init.c.
+
+411. [port] NeXTstep, UNIXWARE, ISC, AUX changes/additions to top Makefile.
+
+410. [port] POSIX_SIGNALS covers a bit more code now.
+
+409. [bug] CNAME->PTR responses were triggering syslog() unnecessarily.
+
+408. [port] res_send.c's socket() calls were using the wrong arguments.
+ this was benign but with IPv6 looming, we need to clean it up.
+
+407. [bug] the delayed free() logic (DATUMREFCNT) didn't account for
+ the possibility of some NULL pointers, in ns_resp.c.
+
+406. [bug] we were walking through purged list items in ns_forw.c.
+ this caused bad things to happen when glue expired.
+
+405. [bug] "attempted update to auth zone" is no longer a warning.
+
+404. [bug] fp_nquery() is now used everywhere, fp_query() is deprecated.
+
+403. [port] hstrerror()'s result is now declared as const.
+
+402. [bug] a flakey initialization in the resolver has been fixed.
+
+401. [port] removed some junk around getnetbyname(), needs testing on suns.
+
+400. [func] BIND's version number now appears as a comment in zone files
+ written by named-xfer.
+
+399. [func] older, bogus HINFO RR's will now be fixed up with warnings.
+
+398. [bug] "SOA class not same as zone's" is now a zone load error.
+
+397. [func] all of the syslog() priorities have been lowered.
+
+396. [doc] added doc/misc/{FAQ.1of2,FAQ.2of2,vixie-security.ps}.
+
+368. [port] top level Makefile updates: .depend files aren't shipped;
+ solaris, linux, dec osf/1, dynix build more cleanly.
+
+367. [port] LOC RR logic has had some lint removed. also named-xfer.c.
+
+366. [contrib] dnswalk 1.8.3 is now included.
+
+365. [security] initial query ID is no longer a fixed constant.
+
+ --- 4.9.3-beta17 released ---
+
+364. named/ndc.sh didn't always exit with nonzero on errors.
+
+363. include/arpa/Makefile was installing into //.
+
+362. convex cleanups. osf/1 cleanups.
+
+361. minor nit in sprintf() format string in tools/host.c.
+
+ --- 4.9.3-beta16 released ---
+
+360. CRED is long gone.
+
+359. convex systems have getrusage().
+
+358. CPPFLAGS wasn't quite right.
+
+ --- 4.9.3-beta15 released ---
+
+357. netdb.h now externs h_errno.
+
+356. fixed odd corner case bug in res_query().
+
+355. no BIND beta is complete without a patch to shres/PROBLEMS.
+
+354. minor addition to the "ndc" command line syntax.
+
+353. "." domain syslog() raised from LOG_DEBUG to LOG_WARNING.
+
+352. minor nit in named-xfer.c.
+
+351. the BSD/* Makefiles were mode 440, are now 444.
+
+350. new (undocumented) make target: "make mkdirs".
+
+349. output format change in tools/host.c.
+
+348. contrib/* updates.
+
+347. CPPFLAGS variable added to the Makefile tree, should quieten some makes.
+ nextstep, solaris, and svr4 systems have some new build parameters.
+
+346. BOG cleanups and addition of PX RR documentation.
+
+345. more items for RUNSON.
+
+344. several combinations and permutations of compilation options didn't work.
+
+ --- 4.9.3-beta14 released ---
+
+343. Type cast fix for #340.
+
+343. Small change to RUNSON.
+
+342. Removed fsync() call, it really wasn't nec'y and was causing trouble.
+
+ --- 4.9.3-beta13 released ---
+
+341. Small fix for #331.
+
+340. Inverse queries, if enabled, will be logged if QRYLOG is enabled and on.
+
+339. Nonrecursive servers (-r) will once again sysquery() for missing glue.
+
+338. named/ndc now preserves the user's $PATH.
+
+337. SUNSECURITY is now only on for shres/*.
+
+336. New version of contrib/host has been included.
+
+335. tools/nsquery.c and tools/nstest.c were moved to contrib/old/.
+
+334. Portability changes for HP-UX, Solaris, Linux, SCO UNIX.
+
+333. INVQ (inverse query support) now defaults to "off".
+
+332. Some of the internal hashing logic for syslog() rate limiting was not
+ accurate (more things were logged than should have been).
+
+ --- 4.9.3-beta12-patch2 released ---
+
+331. Default domain in $INCLUDE files is now intuitive (rather than ".").
+
+330. Lame delegations are now only logged for class "IN".
+
+329. Format change to XSTATS output to make it more readable.
+
+328. Bad responses could cause core dumps in DiG, nslookup, etc.
+
+327. The now-requisite change to shres/* was discovered and put in.
+
+326. Portability changes for Linux, SCO, ULTRIX3, NeXT.
+
+325. Bit the bullet and reset all the RCS revision numbers to 8.1==4.9.3.b12.
+
+ --- 4.9.3-beta12-patch1 released ---
+
+324. Added some missing pieces to the NSAP and NSAP_PTR handling.
+
+323. Tightened some of the GEN_AXFR code, fixed potential C_HS problem.
+
+322. Fixed minor niggle in the way "dig" parses its arguments.
+
+321. Final(?) tuning of the SunOS shres stuff.
+
+320. Reorganized the SunOS build params in the top level Makefile.
+
+ --- 4.9.3-beta12 released ---
+
+319. Fixed DiG so that ". IN NS" was the default if no args are given. (Vixie)
+
+318. Merged the resolver with 4.4BSD's; made a BSD/ subdirectory off the main
+ tree for easy integration into BSD/OS, FreeBSD, NetBSD, et al; moved the
+ "master" subdirectory to "conf/master" to cut down on top level clutter.
+
+317. Lots of last minute fiddling to make Beta12 "right". (cast of thousands)
+
+316. Minor byte order bug in BIND_NOTIFY. (Grange)
+
+315. Added code to db_load() to detect "no RR's found" case. (Vixie; Heiney)
+
+314. "Zone declared more than once" test added. (Grange; Vixie)
+
+313. XSTATS interval was changed from "no more than once a minute, and usually
+ every fifteen minutes" to "no more than once an hour, and usually every
+ hour". (Gianopoulos; Vixie)
+
+312. Minor stuff in BIND_NOTIFY and the Ultrix and OSF/1 builds. (Heiney)
+
+311. Continuing hacks to LOC RR (experimental) and shres/*. (Davis)
+
+ --- 4.9.3-beta11-patch5 released ---
+
+310. Minor BOG patches. (Shapiro)
+
+309. Minor LOC RR lint. (Heiney; Truck)
+
+308. Minor STUBS changes in ns_req.c. (Andrews)
+
+307. Ultrix and OSF/1 now install "man" (not "cat") pages. AIX now installs
+ *.[0-9] rather than *.0 pages. (Vixie, et al)
+
+306. conf/Info.* moved to new directory doc/info/*. (Vixie)
+
+305. NOTIFY could cause multiple simultaneous axfr's. (Andrews; Vixie)
+
+ --- 4.9.3-beta11-patch4 released ---
+
+304. Minor fixes to PURGE_ZONE, CLEANCACHE, RETURNSOA, and dig. (Mark Andrews)
+
+303. LOC RR support is now in. (Chris Davis; Vixie)
+
+302. General portability stuff (with ISC leanings). (Mark Galbraith)
+
+301. Minor DiG portability fix. (Dima Volodin)
+
+300. Yet more HINFO fixes. (Gianopoulos)
+
+299. Really minor patch to tools/nstest.c, plus AIX fixes. (David Bolen)
+
+298. More shres/* fixes. (Davis; Woods)
+
+297. Minor SCO fixups. (Eduard Vopicka)
+
+296. Fixed #include <signal.h> problem in db_glue.c. (cast of thousands)
+
+295. Minor goofs in the sources. (Grange; Gianopoulos)
+
+294. Minor patch to the BOG (font problem). (Shapiro; Vixie)
+
+ --- 4.9.3-beta11-patch3 released ---
+
+293. Minor #ifdef screwup corrected. (Mohamed Ellozy)
+
+292. Small HP-UX portability change. (Truck)
+
+291. Minor BOG correction. (Harlan Stenn)
+
+290. PX RR support. (Pierluigi Bonetti)
+
+289. Made random refresh interval a little more robust. (Miller; Vixie)
+
+288. Minor portability changes for DEC OSF/1. (Bob Heiney)
+
+287. We now do a setvbuf() on outbound AXFR streams since the system's
+ default size causes more write()'s (and therefore TCP segments)
+ than we really want. (Paul Mockapetris' idea; Paul Vixie's code.)
+
+286. Recast all uses of abort() to call private function panic(). This was
+ nec'y since we use the ABRT (IOT) signal to force a statistics dump, and
+ having it dump statistics inside of abort() was a bad thing.
+ (Mark Andrews noticed the problem; Paul Vixie fixed it.)
+
+285. Minor change to top-level Makefile for OSF/1 man pages. (Shapiro)
+
+284. Minor change to HINFO stuff. (Gianopoulos)
+
+283. Minor changes to XSTATS #ifdef's. (Benoit Grange)
+
+282. Minor change to top-level Makefile for ULTRIX/VAX. (William Gianopoulos)
+
+ --- 4.9.3-beta11-patch2 released ---
+
+281. Another batch of (minor) HINFO changes. (William Gianopoulos)
+
+280. Minor formatting changes to keep ctags happy. (Craig Leres)
+
+279. Minor changes to OPTIONS. (Mark Seiden)
+
+278. New option XSTATS (default "on" for now). (Benoit Grange)
+
+277. res_mkquery() wasn't calling res_init(). (Philip Gladstone)
+
+276. Minor cleanup to shres/INSTALL. (Chris Davis)
+
+275. We now set a SO_LINGER on outbound zone transfers. (Peter Wemm; Vixie)
+
+274. Minor portability fix for VAX Ultrix. (Stan Barber)
+
+273. Fixed two time warp problems. (Bob Heiney; Paul Vixie)
+
+272. Named-xfer will now log and error and abort if it encounters an RR type
+ it doesn't recognize. (Mark Andrews; Paul Vixie)
+
+271. Minor cleanups to the HINFO comparison code in db_update. (Bryan Beecher)
+
+270. Made CLEANCACHE less of a CPU hog. (Benoit Grange; Mark Andrews)
+
+269. Add even more branches to the cred/clev decision tree, to make it more
+ robust about borderline data at zone cuts. (Jack McCann; Mark Andrews)
+
+268. New option (default: "on" for now): PURGE_ZONE. (Mark Andrews)
+
+267. Added contrib/misc/{soa-easy,dnsfind}.shar. I will not be including
+ this in the b11p2 diffs, though it will be in the next full kit.
+ (Tim Cook)
+
+266. I finally broke down and made a recommendation in the BOG with respect to
+ "nameserver 127.0.0.1". (Greg Woods supplied the patch)
+
+265. Minor portability stuff for SunOS. (Greg Woods)
+
+ --- 4.9.3-beta11-patch1 released ---
+
+264. 900-second check removed; TTL==0 should work now. (Mark Andrews)
+
+263. Minor db_save() patch for initializing memory. (Bryan Beecher)
+
+262. Minor ESIX (SVR4.0.4/gcc) changes. (John Polstra)
+
+261. Minor dig-related patch to res_send.c. (Mark Andrews)
+
+260. Minor line number fix for ns_init(). (Havard Eidnes)
+
+259. NetBSD shared library stuff is now in contrib/misc/netbsd-shlib.shar.
+ (Matt Ragan)
+
+258. NeXT portability changes. (Allan Nathanson)
+
+257. Minor HP-UX portability stuff. (Lewis; Corrigan)
+
+256. Two medium sized bugs in BIND_NOTIFY. (Don "Truck" Lewis)
+
+255. Minor lint in ns_req.c. (Mark Andrews)
+
+254. Minor ndc.sh build problem. (Michael Corrigan)
+
+253. Minor coding inconsistency in res/res_comp.c. (Jeff Schreiber; Vixie)
+
+252. Minor BOG addition (SIGIOT). (Bryan Knowles)
+
+ --- 4.9.3-beta11 released ---
+
+251. If a master zone's serial number goes backwards, named now logs a
+ warning. (Mark Andrews)
+
+250. Minor portability nit in ns_forw(). (Simon Leinen)
+
+249. Another portability problem fixed in ndc.sh. (Corrigan)
+
+248. Declaration problem with findZonePri() fixed. (Corrigan)
+
+247. References to CNAMES from MX/NS/MB will now be explicitly logged. (Vixie)
+
+246. Made the BIND_NOTIFY logic more robust; it still does not match the
+ current I-D (no delays yet). (Vixie)
+
+245. Fixed a writable-string problem. Added a lot of ANSI "const"'s. (Vixie)
+
+ --- 4.9.3-beta10-patch1 released ---
+
+244. Added shres/PROBLEMS file. (Chris Davis)
+
+243. Corrected the BOG on the meaning of ".". (Doug Luce, Paul Vixie)
+
+242. SOA's can now be stored in $INCLUDE files. (John Lind)
+
+241. Rejection of 0.0.0.0 had a potential seg fault. (Mark Andrews)
+
+240. NoRecurse wasn't preventing queries for missing glue. (Mark Andrews)
+
+239. WKS nonaggregation test had bad length. (Ed Clarke, Chris Britton)
+
+238. NeXT library problem worked around. (Greg Wohletz)
+
+237. Core dump fixed in the dprintf() macro. (Eric Murray)
+
+236. MBZ fields in new queries were actually stack trash. (Olson, Vixie)
+
+235. Adds and changes to contrib/:
+ Added contrib/misc/dnstools.shar, from alt.sources. (Eric Murray)
+ Added contrib/misc/settransfer.shar (nonrecommended). (Tom Brisco)
+ Updated contrib/host/* with latest public version. (Eric Wassenaar)
+ Updated contrib/host/makezones with latest pub. version. (Philip Hazel)
+
+234. Made the "ps" command needed by ndc.sh a configurable parameter.
+
+ --- 4.9.3-beta10 released ---
+
+233. Added and reordered a lot of code in ns_resp() to cause it to be
+ slighly harder to spoof with bad packets. More work needs to be done,
+ so that named will be as spoof-proof as the resolver has become. (Vixie.)
+
+232. Added new RR types to include/arpa/nameser.h, per RFC 1700. (Vixie)
+
+231. New "ndc" command. (Vixie)
+
+230. The VALIDATE option is now formally deprecated. It has bugs its detection
+ of invalid responses, and is known to mutilate perfectly valid CNAME
+ responses, to the detriment of clients. This code will likely be deleted
+ in the next BIND release, to be replaced by an ``always restart query''
+ strategy. (Vixie)
+
+229. Moved a syslog() so that primary as well as secondary loads are logged.
+
+228. Resolver functions now reliably set h_errno. (Vixie, Wassenaar)
+
+227. Expired zones now lose their cached serial number information, giving
+ an opportunity to refresh a zone after a serial number goes backward.
+ (Andrews)
+
+226. Sun386i support crept in on little cat feet. (Brownlee)
+
+225. UDP packets could be overstuffed by 12 bytes. (Reilly, Vixie)
+
+224. failing connect()'s in named-xfer will no longer be logged. (Andrews)
+
+223. merged IETF stream (Vixie):
+ a. made ALLOW_UPDATES even more optional (it will disappear soon);
+ b. added NOTIFY option (experimental);
+ c. cleaned up some comments;
+ d. removed T_SA (was experimental, replaced by ROUND_ROBIN);
+ e. made named/Makefile's default CFLAGS -g (it usually inherits -O);
+ f. random code cleanup;
+ g. some internal errors are now fatal instead of warnings.
+ these changes were brought in once it became clear that there would be
+ another Beta of 4.9.3.
+
+222. tools/Makefile was using "make" instead of "${MAKE}". (Day)
+
+221. yet another bug was found and fixed in the SUNSECURITY code. (Brown)
+
+220. a variable reuse problem in the SUNSECURITY syslog()'s in gethnamaddr.c
+ was fixed. (Wohletz, Wemm, Vixie)
+
+219. "stub" root zones now affect the hint cache (STUBS is experimental).
+ in this situation it is reasonable to not have a "cache" directive,
+ and some code was reordered to make this possible. (Andrews)
+
+218. contrib/umich/lame-delegation/LISA-VI-paper.ps is now a proper
+ PostScript(tm) file. (Davis)
+
+217. syslog() cleanups in named-xfer.c. (Vixie, Barrett)
+
+216. shres/Makefile now forces -O. (Braniss, Ray)
+
+215. New contrib/misc/ctldns.sh. (Bush)
+
+214. New contrib/misc/dns-peers.info. (Wolfhugel)
+
+213. BOG and named(8) fixes. (Paffrath, Vixie, Hawkinson)
+
+212. database input errors will no longer cause the following line to
+ be ignored. (Gianopoulos)
+
+211. the TXT RR fixes done so far in 4.9.3 have been backed out; we're
+ back to the 4.9.2 behaviour. (Gianopoulos)
+
+210. the authority section will no longer duplicate the answer section
+ if both would contain the same NS RR set. (Vixie)
+
+ --- 4.9.3-beta9-patch1 released ---
+
+209. installed marka's patch to CRED that fixes BETA9's flaw.
+
+208. added comment to README about -l44bsd and inet_aton().
+
+207. new directory: contrib/multizdb. highly nonrecommended.
+
+206. small NextStep change in Makefile.
+
+ --- 4.9.3-beta9 released ---
+
+205. minor Makefile fix after beta9 was previewed on bind-workers; also, a
+ new file conf/Info.Linux-more has been included.
+
+204. BOG fixes.
+
+203. netlists elements are now
+ { addr [ "&" mask ] }
+ which for the EBNF-impaired, means that "&" introduces an explicit mask.
+ implicit masks are either by-class or 0xffffffff, depending on ALLOW_HOSTS
+ in the call to get_netlist().
+
+202. name compression is now case-insensitive.
+
+201. duplicate RRDATA won't trigger the new "auth warning" in db_update().
+
+ --- 4.9.3-beta8-patch2 released ---
+
+200. added a haveComplained() to limit auth warnings.
+
+199. fixed idiotic code reordering from patch1.
+
+ --- 4.9.3-beta8-patch1 released ---
+
+198. a bad-string-termination bug was fixed in getnetanswer().
+
+197. an uninitialized-variable bug was fixed in db_update().
+
+ --- 4.9.3-beta8 released ---
+
+196. Several minor corrections were made to the BOG.
+
+195. "clev" now distinguishes between root and TLD (wasn't worth a darn before)
+
+194. empty nodes in authority zones are now protected from non-auth updates.
+ (most of db_update() was rewritten to fix/support this.)
+
+193. negative cache items weren't updated before, now they are.
+
+192. zone updates from answers were prevented for new types but not if some
+ rr already existed with that type. fixed. also syslogged.
+
+191. the cache now distinguishes between authoritative answers and zone rr's.
+
+190. negative cache items are now marked appropriately authoritative.
+
+189. CRED is no longer optional.
+
+188. Another enhancement has been made to HINFO parsing. Named-xfer now
+ accepts RFC-bogus input formats generated by previous versions of BIND.
+
+187. SUNSECURITY now forces RES_DEFNAMES on so that relative "localhost" works.
+
+186. Minor portability fixes for DEC OSF/1, HP-UX.
+
+ --- 4.9.3-beta7-patch2 released ---
+
+186. i forgot to comment out template Linux lines in top Makefile. fixed.
+
+185. "bogusns" directive significantly strengthened, for IN-ADDR.ARPA problem.
+ also fixed a bug in hardcoded root server lame detection.
+
+ --- 4.9.3-beta7-patch1 released ---
+
+184. Yet another ULTRIX incompatibility has been worked around.
+
+183. Bogus HINFO RR's will no longer cause corrupt secondary zone files.
+
+182. NeXT support is now complete. Builds right out of the box.
+
+181. Updated TODO file.
+
+180. Added new INSTALL file.
+
+179. Minor doc fix in OPTIONS file.
+
+178. Security-related bug fix to new sunos shres/* stuff.
+
+177. Limited Linux portability was added.
+
+176. Trailing dots on zone names in named.boot are now ignored.
+
+175. Random lint was removed.
+
+174. DiG changes: increment version number (2.1), allow default domain (.).
+
+ --- 4.9.3-beta7 released ---
+
+173. named-xfer would act strangely if trailing dot domains given as arguments.
+
+172. setenv() now provided on systems that need it (NeXTStep, e.g.).
+
+171. doc changes for shres/*.
+
+170. fixed debugging output problem in ns_req.c.
+
+169. fixed portability "bugs" on ultrix systems (some tools wouldn't link).
+
+168. minor functionality change in named/ns_validate.c.
+
+167. minor lint in res/res_comp.c.
+
+166. minor change to contrib/doc-2.0/*.
+
+ --- 4.9.3-beta6 released ---
+
+165. another small adjustment to the Apollo section of the Makefile.
+
+164. a completely new shres/* was submitted; contrib/sunlibc is deprecated.
+
+163. INVQ is back on again by default. See README.
+
+162. another set of patches for obscure corner cases in the HINFO parser.
+
+161. added new SUNOS4 macro to Makefile and conf/portability.h; this should
+ fix the trouble folks were having with strerror() on SunOS 4.X systems.
+
+160. minor Makefile changes.
+
+159. processes which send outbound zone transfers now close all inherited
+ descriptors, since they can be longer-lived than the main named.
+
+ --- 4.9.3-beta5 released ---
+
+158. various lint involving options which are rarely defined.
+
+157. sunos needed -DBSD=43 rather than -DBSD.
+
+156. minor memory leak fixed in ns_req.c.
+
+155. some install directories for DGUX were wrong.
+
+ --- 4.9.3-beta4 released ---
+
+154. a new man/* hierarchy was installed which should be more portable.
+
+153. a new contrib/host has been included.
+
+152. a parsing problem in HINFO was fixed.
+
+151. a few minor changes to contrib/sunlibc/Makefile.
+
+150. typo in res_send.c fixed.
+
+149. fine tuning the credibility-level heuristics.
+
+148. dn_expand() will fail on names which have bad characters in them.
+
+147. disappearing zones could cause a core dump in syslog() - fixed.
+
+146. text of warnings in named-xfer corrected.
+
+145. limited DGUX, RISCOS support added.
+
+144. contrib/sunlibc/Makefile MFLAGS/MARGS problem fixed.
+
+143. another SunOS recv() bug has been worked around.
+
+142. various BOG fixes.
+
+141. updated master/root.cache file from latest InterNIC version.
+
+140. Added ``max-fetch'' to named(8).
+
+139. NOT_BIND problem in named/tree.c fixed.
+
+138. minor lint, memory leaks, and portability problems were fixed.
+
+ --- 4.9.3-beta3 released ---
+
+137. some serious (and recently) dynamic memory bugs were killed.
+
+136. a reference to uninitialized data was fixed in res_query().
+
+135. a RES_STAYOPEN-related bug was fixed in res_send().
+
+134. isascii() and isxdigit() now simulated on systems which lack them.
+
+133. named's local setproctitle() has been renamed to avoid system conflicts.
+
+132. minor bugfix to negative caching code.
+
+131. minor bugfix in validation code.
+
+130. the typestats[] multiple definition problem was fixed.
+
+129. some Sequent portability changes were folded in.
+
+128. a new contrib/sunlibc was donated, but hasn't been tested.
+
+127. minor changes to contrib/sunlibc/Info.*. is anybody using shres/*, tho?
+
+126. STDIN_FILENO and STDOUT_FILENO are now defined by conf/portability.h.
+
+125. there is now a ``max-fetch'' directive in the boot file (see the BOG).
+
+124. there is now a RENICE option in conf/options.h.
+
+123. the toplevel Makefile has been made slightly more readable.
+
+122. <<DELETED>>
+
+121. minor fixups in the lame delegation code.
+
+ --- 4.9.3-beta2 released ---
+
+120. I upgraded my "-me" macros so that the included doc/bog/file.psf is OK.
+
+119. NXDOMAIN responses from the negative cache will now always be
+ authoritative. this is the least of all evils, trust me.
+
+118. strcasecmp() in compat/lib is now ANSI compliant.
+
+117. PTR RR's are no longer subject to ROUND_ROBIN processing.
+
+116. writev() emulation for SCO had a bug.
+
+115. the resolver no longer calls sscanf() or qsort().
+
+114. minor debugging nit cleaned up in res_querydomain().
+
+113. IP options on incoming connections are now logged and ignored. This
+ should probably be done for datagrams as well but not today.
+
+112. tree.c made portable to non-POSIX/ANSI systems.
+
+111. NSAP RR's are now supported. NSAP_PTR RR's are deprecated and so left out.
+
+110. outbound zone transfers are now logged.
+
+109. various lint cleaned up wrt 16-bit integer handling.
+
+108. named-xfer was exiting bogusly on some systems due to flakey kernel
+ interfaces. i've rewritten some of the code to avoid the problem,
+ and fixed plenty of lint in the process.
+
+ --- 4.9.3-beta1 released ---
+
+107. Apollo systems were dumping core because of a missing #include <resolv.h>.
+
+106. NSAP and NSAP_PTR RR's now recognized by res_debug() (but nothing else).
+
+105. NeXTstep 2.1/3.0 and Pyramid dcosx now nominally supported.
+
+104. res_querydomain() was doing Bad things if given an empty name.
+
+ --- 4.9.3.a5.p4 published ---
+
+103. named-xfer's exit cause is now syslog()'d more often/clearly (Paul Vixie).
+
+102. I left out a ";" in the new compat/lib/ftruncate.c file (Craig Leres).
+
+101. X25, ISDN, and RT RR support have been added (Michael A. Meiszl).
+
+ --- 4.9.3.a5.p3 published ---
+
+100. Another glitch (very minor this time) was found and fixed in the
+ QSERIAL logic. This was a performance problem only -- reliability
+ wasn't affected (Bob Heiney).
+
+99. SCO UNIX is now supported, thanks in part to Michael A. Meiszl.
+
+98. I witlessly used a GCC-only feature (automatic aggregate initialization)
+ in a5p2. Kazuhisa Shimizu was the first to report it.
+
+ --- 4.9.3.a5.p2 published ---
+
+97. NEC EWS4800 EWS-UX/V Rel4.0/Rel4.2 support (from Kazuhisa Shimizu).
+
+96. Some of the security checking logic in the new res/gethnamaddr.c's
+ getanswer() was happening in the wrong order (thanks, Bob Heiney).
+
+95. Minor typo in the man/host.1 man page (caught by Robert Elz).
+
+94. DiG was groping core if given more than 10 tokens in a lookup string
+ (Michael J. Corrigan provided the fix).
+
+93. Queries to INADDR_ANY ("0.0.0.0") come back from the system's primary
+ interface, and res_send() was discarding them. A proper fix would add
+ a lot of code to the resolver, so for now we'll just work around it
+ (Michael J. Corrigan reported this).
+
+92. The "data outside zone" syslog message was misleading (Bob Heiney).
+
+ --- 4.9.3.a5.p1 published ---
+
+91. res/gethnamaddr.c wouldn't compile on non-BSD systems since it depended
+ on LOG_AUTH which is a post-4.3 feature (Bob Heiney reported this).
+
+ ****** 4.9.3-alpha5 released ******
+
+90. redid most of my previous round of prototyping now that i truly
+ understand which variables and parameters should be u_char and which
+ ones should be char. (Vixie)
+
+89. added (optional) prototypes for _getshort() and _getlong(); this means
+ the calls all need casts of their argument since it usually isn't a
+ u_char*. Also prototyped res_query(), res_search, and the nominally
+ private but for some reason not static res_querydomain(). (Vixie)
+
+88. security related: responses from servers we didn't query are now ignored
+ by the resolver; answers with QDCOUNT!=1 are treated as errors; name
+ mismatches in the question or any part of the answer field are syslog()'d
+ and ignored. (Vixie)
+
+87. fixed a bug in the SUNSECURITY stuff. (Vixie)
+
+86. a long standing bug in the name hashing code that caused it to ``hash in''
+ the case of the name's characters, was found and fixed. (twice.) (Vixie)
+
+85. Bob Heiney did some performance analysis and concluded that samedomain()
+ was soaking down cycles at a rate disproportionate to its usefulness; he
+ reimplemented it in a way that violated the (good,fast,cheap) rule.
+
+84. the RFC1101 implementation of getnetby*() was using case-sensitive
+ string compares.
+
+83. fp_query() will no longer try to format packets larger than PACKETSZ,
+ and for perversity, dig and named are now prepared to handle replies
+ (via TCP) larger than PACKETSZ. new function: __fp_nquery(). (Vixie)
+
+82. multiline initial syslog() is fixed (Bill G).
+
+81. Don Lewis sent in a big update for the lame delegation logic. Vixie fixed
+ one bug. Bryan Beecher had a big hand in this.
+
+80. TCP replies can now be up to 8K in size (don walsh).
+
+79. validation bug fixed (don lewis).
+
+78. BOG patches from mike minnich and others.
+
+77. more lint fixes for Cray (norb brotz).
+
+76. a new hostname(7) man page was contributed by Art Harkin.
+
+75. DESTINC is now a settable Makefile parameter (Marion Hakanson).
+
+74. the zones-not-transferring bug is finally gone.
+
+73. now using LOG_PERROR in openlog(); many parallel dprintf()'s are gone.
+
+72. inability to retrieve serial number via UDP now forces TCP transfer.
+
+71. removing secondary zone files and SIGHUP'ing will now force a transfer.
+
+70. "cache" directives can now specify "/class" as documented in the BOG.
+
+69. Mark Andrews' fix for the ns_forw core dump is in.
+
+68. Keith Bostic fixed some typo's in the man pages.
+
+67. Compiling without NCACHE is possible now (John Hanley).
+
+66. Bill Gianopoulos and Alan Barrett finally agreed on what glue was and
+ Bill's alpha4 patch is mostly gone now, and one new idea was added.
+
+65. BOG improvements (Vixie, Brooks).
+
+64. Mark Andrews' CLEANCACHE (recommended) and RETURNSOA (__NOT__ recommended!)
+ are in. RETURNSOA should not be enabled at this time; there's nothing
+ wrong with the code but it will cause cache corruption in older servers
+ and may not be necessary. The jury is still out.
+
+63. outbound zone transfers are now logged (requested by Ron Johnson).
+
+62. serial number queries sent out for zone transfer purposes will now be
+ limited to a maximum of four (4) simultaneous outstanding; this keeps
+ BIND from overflowing its UDP socket buffer when hundreds of zones must
+ be checked (still trying to fix Paul Pomes' problem).
+
+61. short A RR's in responses will no longer lead to purify errors due to short
+ malloc()'s in savedata() (thanks to Nicholas Briggs for reporting this).
+
+ ****** 4.9.3-alpha4 released ******
+
+60. manifest constants used instead of "sizeof({u_,}int{16,32}_t)", for
+ systems which lack 16- and 32-bit integers (paul vixie for norm brotz).
+
+59. zone transfer anti-glue logic made RFC1034-compliant (bill gianopoulos).
+
+58. seg fault in sysquery() (from LAME_DELEGATION) fixed (mark andrews).
+
+ ****** 4.9.3-alpha3 released ******
+
+57. a big, hefty patch was made to the negative caching logic (mark andrews).
+
+56. named-xfer will no longer scramble the default origin (alan barrett).
+
+55. random bits of lint found and removed (mario guerra).
+
+54. convexos-10 is now supported (jukka ukkonen).
+
+53. seg fault in database dumps (from VALIDATE) fixed (don lewis).
+
+52. problem with extra bogus 0.0.0.0 A RR's from VALIDATE fixed (mark andrews).
+
+51. the LAME_DELEGATION logic once written into 4.8.3 by don lewis has
+ been substantially reworked and put into 4.9.3-alpha3 (bryan beecher).
+
+50. all instances of "sizeof(HEADER)" were changed to "HFIXEDSZ" to make
+ life easier for the cray. also, "struct HEADER" in include/arpa/nameser.h
+ uses just bit fields now, for portability to 64-bit systems without
+ 16-bit integer types. (norb brotz suggested it; paul vixie did it).
+
+49. build changes for NeXT and AIX systems (artur romao; c. wolfhugel).
+
+48. random sunshlib changes (piete brooks).
+
+47. minor fixes for solaris build (carson gaspar; paul pomes).
+
+48. a few bugs were wrung out of the BOG (per hedeland; vixie).
+
+ ****** 4.9.3-alpha2 released ******
+
+47. several obscure Makefile problems were fixed (vixie).
+
+46. there is now a per-primary-NS quota for simultaneous zone transfers; this
+ will cut down on the retry thrashing seen on servers that are secondary for
+ thousands of zones (vixie).
+
+45. a bug introduced by change #23 has been fixed (marten terpstra; apb).
+
+44. the "data outside zone" messages are now consistent (piete brooks; vixie).
+
+43. several #include's were reordered in res/*.c and a few #ifdef's were
+ changed; BIND should now run OK on DGUX (henry miller).
+
+42. several changes to the conf/options.h and Makefile (vixie):
+ -> SVR4 has been added as a top-level Makefile CDEFS option
+ -> SYSV has moved from conf/options.h to the top level Makefile
+ -> INVQ is now an "#ifdef" rather than a "#if"
+
+41. resolver no longer uses initialized static data, which should make shared
+ libraries easier to generate (vixie did it, at the urging of many others).
+
+40. now compiles on Apollo DomainOS (don lewis).
+
+ ****** 4.9.3-alpha1 released ******
+
+39. lots of lint found and fixed (craig leres).
+
+38. illegal enum compare fixed in named/ns_stats.c (vixie).
+
+37. missing ')' added in SUNSECURITY section of res/gethnamaddr.c (h miller).
+
+ ****** 4.9.3-prealpha released ******
+
+36. ***REMOVED***
+
+35. various bugs were fixed in the negative caching (vixie; mark andrews).
+
+34. several debugging and dump output problems were fixed (mark andrews).
+
+33. TXT RR's can now be read from zone files even if they lack quotes;
+ the RFC doesn't say quotes are needed (jim martin).
+
+32. limited support for AIX-3 is now included (christoph wolfhugel).
+
+31. SUNSECURITY is now an obvious default in ./Makefile (p killey; b beecher).
+
+30. VC queries that time out are now GC'd and SERVFAIL'd (mark andrews).
+
+29. HP-UX 9.0's top-level makefile variables have been changed (don lewis).
+
+28. various fixes for tools/host.c (jim martin; mark andrews).
+
+27. syslog messages logged by SUNSECURITY will now include the address of
+ the host that's having problems (david morrison).
+
+26. systems whose connect() calls fail if a socket is already connect()'d
+ will now have their sockets closed and recreated in res_send() (piete
+ brooks; mark andrews; vixie).
+
+25. res_send() will now corrected reset its "connected" variable when the
+ connectedness of a socket changes (mark andrews).
+
+24. SERVFAIL responses will no longer terminate the res_search() inner loop,
+ thus catastrophic problems with early search elements will no longer
+ prevent res_search() from trying later search elements (bryan beecher;vix).
+
+23. non-NS RR's for delegated subzones will no longer be accepted in a zone
+ transfer (alan p barrett).
+
+22. the setting for _PATH_PIDFILE is now overridden by the Makefile (l hume).
+
+21. named.restart.sh now has a smaller path with %DESTSBIN% first therein;
+ this should prevent the vendor version of named from being exec'd by
+ accident (leigh hume).
+
+20. big change: statistics are now kept "per name server" rather than as
+ a single global array. the /var/tmp/named.stats file format has changed
+ quite a bit, so older awk/perl scripts are likely to stop working.
+
+19. big change: every RR now keeps a pointer to a "nameser" struct; this
+ currently permits SIGINT-initiated dumps to include the address of all
+ non-zone data, which will help with tracking down corrupt data.
+
+18. db_load.c was missing two #ifdef/#endif's for CRED (mike minnich).
+
+17. don't aggregate SOA or WKS RR's in the cache (vixie).
+
+16. minor cosmetic changes (vixie).
+
+15. fixed typo in compat/Makefile ("LIBDIR" -> "DESTDIR") (rob davies).
+
+14. fixed spurious "accept: interrupted system calls" (vixie).
+
+13. named will now start as many named-xfer's as it should; previously it
+ lost track of the need for transfers at the beginning of each maint
+ cycle. also, we don't bother asking for an SOA if we know that our
+ zone is out of date. i've changed the transfer metrics so that more
+ transfers can happen concurrently, and maint cycles come more often.
+ (andrew partan; vixie).
+
+12. a number of LOG_ERR and LOG_CRIT syslogs were downgraded to LOG_NOTICE
+ (rob davies; vixie).
+
+11. sequence number checking now treats "zero" as a special case.
+ (craig leres; andrew partan; vixie).
+
+10. MFLAGS no longer used explicitly, since it is often used implicitly
+ (mark andrews; vixie).
+
+9. ADDAUTH is no longer considered experimental (tony stoneley; vixie).
+
+8. several obscure type bugs fixed (don lewis).
+
+7. signal handlers all now preserve errno (don lewis).
+
+6. TTL deprecation made more portable (don lewis).
+
+5. now compiles on Apollo DomainOS and is generally more POSIX-ish (don lewis).
+
+4. bryan beecher's "query" tool has been promoted to tools/ and renamed to
+ dnsquery. minor changes were required in several Makefiles (vixie).
+
+3. "make links" at the top level will now make a higher resolution link tree,
+ which makes porting easier on some systems (ian dickinson).
+
+2. Convex feof() bug now has a workaround (jukka ukkonen).
+
+1. gethostby*() will no longer overwrite its fixed-size array if a host with
+ too many addresses is handled (reported by piete brooks, fixed by vixie).
+
+-------------------------------------- 4.9.3 above, 4.9.2 below
+
+4.9.2 ------------------ FINAL ----------------- Paul Vixie
+
+57. updated TODO, README files.
+
+56. fix to contrib/sunlibc/Makefile.
+
+55. several new items in contrib/.
+
+54. Corrected bad command line parsing bug in tools/dig.c; also added the
+ old query timing code back in (thanks to Havard Eidnes).
+
+53. Ported contrib/decwrl/host.c to the modern interfaces.
+
+4.9.2 ------------------ BETA5 ----------------- Paul Vixie
+
+52. A number of optimizations that fell out of negative caching and/or the
+ validation code have been turned off in order to avoid confusing older
+ nameservers and their unfortunate assumptions about co-invariants.
+ Mark Andrews and Robert Elz were the principle debuggers and contributors
+ to this part of the effort.
+
+51. We're now much more portable to systems without Posix or BSD signals,
+ thanks to Bill Wisner.
+
+50. tools/host.c now has more reasonable error messages and can deal with
+ negative caching servers.
+
+49. Lots of Makefile gaffes are now fixed.
+
+48. New "host" in contrib/host/, complements of Eric Wassenaar.
+
+47. AFSDB support is now complete, thanks to Chris Everhart.
+
+46. The bug whereby named would sporadically return NXDOMAIN when it should
+ have sent back a referral has been fixed.
+
+4.9.2 ------------------ BETA3, BETA4 ----------------- Paul Vixie
+
+45. Robert Elz has provided updated LOCALDOMAIN environment variable
+ processing, making it more like resolv.conf's "search" than "domain".
+ In the spirit of this I have added a RES_OPTIONS environment variable
+ and a corresponding "options" keyword to resolv.conf. All of this is
+ documented in the man pages and in the BOG. Robert has also contributed
+ several bug fixes to the validation and negative caching code.
+
+4.9.2 ------------------ ALPHA ----------------- Paul Vixie
+
+44. BETA1, BETA2, and three patches to BETA2 have all come and gone without
+ itemized descriptions in this file. I'll provide the RCS history on the
+ code to anyone who asks, but basically what's been happening is that some
+ core dumps were fixed, others added, then those were fixed too. Meanwhile
+ RFC 1535 has been published, codifying CERT's concerns and our answer to
+ them. BIND is now RFC 1535 compatible. RFC's 1535, 1536, and 1537 are
+ now included in the doc/ directory. Note that Mark Andrews supplied many
+ of the fixes to the core dumps, some of which were introduced by me and
+ some by ISI's negative caching and/or validation code.
+
+43. patch05 to ALPHA2 (930908) released: this includes new DNSRCH logic to
+ correct a serious problem that CERT called me with today. the change is
+ subtle and will have the effect that names which could match either as
+ fully qualified names or partially qualified names using the local search
+ list will be found as fully qualified. previous releases would have found
+ them first through the local search list. local search lists are a bad
+ idea in my opinion; see new SEARCH_DEFAULT option in OPTIONS file for more
+ information. also in this release: limited Solaris support, in the form
+ of POSIX-style signal handling used on systems which support (or require)
+ it. as of this patch, 4.9.2 has a good chance of compiling out of the box
+ on Solaris, modulo makefile edits. dig and host should be more portable
+ now, too.
+
+42. patch04 to ALPHA2 (930908) released: this corrects several borderline
+ syntax errors in various Makefiles (Sun and Ultrix makes complained);
+ it corrects a coredump on Ultrix systems (which aren't really as POSIX
+ as i thought they were); it lets dig and nslookup compile again on SunOS;
+ and it cleans up some dirty junk in named-xfer.c. this stuff is really
+ really minor but i would like to see it tested on a Sun system before the
+ beta.
+
+41. patch03 to ALPHA2 (930908) released: this uses compat/include by default
+ which is helpful on BSD/386 systems and shouldn't hurt any others except
+ perhaps real 4.4BSD systems (and maybe not even those); it removes Bryan
+ Beecher's SHUFFLE_ADDRS option since he and I agree that Marshall Rose's
+ ROUND_ROBIN stuff is more general and cleaner; it includes various patches
+ to the documentation sent in by several folks (please print the BOG and
+ let me know if you find problems in it); it fixes "make depend" problem
+ in "man/" subdirectory; it fixes several outright bugs in Gregory Shapiro's
+ SECURE_ZONES code; it removes an obscure syslog() that should have been a
+ dprintf() ("validate_count -> 0"); it fixes a bug in NCACHE whereby a T_ANY
+ query for a name which was negatively cached but had children would return
+ _answers_ with the T_ANY type for subsequent queries; several newer syslog
+ messages were reworded to make them clearer; a portability bug in the
+ SUNSECURITY logic was fixed; another in the RFC1101 logic was fixed;
+ support for the PAGER environment variable was added to nslookup (sorry,
+ i know we're in functional freeze but this will enable development in the
+ next cycle and it was pretty simple) and only affects the "view" and "help"
+ commands.
+
+40. patch02 to ALPHA2 (930908) released; this includes more fixed from Mark
+ Andrews, this time to Anant's NCACHE stuff (memory leak and functional
+ bug). Also included is a patch from Gregory Neil Shapiro to his SECURE_
+ ZONES code, which I hadn't noticed since I don't run it here.
+
+39. patch01 to ALPHA2 (930908) released; this includes some fixes from Mark
+ Andrews to his "clev" and ADDAUTH stuff. The "clev" patch fixes a problem
+ on all servers; the ADDAUTH stuff is still experimental so most users will
+ not be affected by it. Dave Morrison also sent a patch for the USE_UTIME
+ logic, which is important for ULTRIX systems.
+
+38. 4.9.2-ALPHA2 released on 930908.
+
+37. Mark Andrews sent an initial attempt at implementing ADDAUTH, which will
+ eventually allow named to include authority and glue RR's with all
+ authoritative answers. I am not sure that the design goal is right, and
+ the implementation currently sends back glue RR's but no authority RR's,
+ so I'm recommending against using this for now. But since it changes some
+ internal interfaces in a harmless enough way, I'm including the changes.
+
+36. Marshall Rose's ROUND_ROBIN code snuck in at the last hour. This is the
+ best answer I've seen to the problems purported to be solved by SA RR's,
+ and my wording in the OPTIONS file shows this.
+
+35. These items from TODO is now done:
+
+ [vixie@pa.dec.com 25apr93]: clean up debugging
+ replace all "#ifdef DEBUG...fprintf(...)...#endif" with dprintf(...)
+ which would be a macro that only expands to an fprintf() if DEBUG is
+ set. dprintf(x, (args)) with x as the log level. perhaps change log
+ levels to be symbolic, and perhaps make them a mask instead of a limit.
+
+ [vixie@pa.dec.com 25apr93]: clean up #ifdef's and portability
+ add and use function prototypes. make everything static that can be.
+ externs should only be in .h files (add more .h files, per module if
+ needed, to cover these). add "export" keyword (null define) to make
+ it clear which names are exported and which are static. all top-blevel
+ names in a module must be "export" or "static".
+
+ [gshapiro@wpi.edu and vixie@pa.dec.com 26apr93]: access control
+ "xfrnets" is ok but what we really need is full access control per
+ zone rather than a global list of acceptable client nets. this is
+ especially important if you send /etc/passwd via zone transfer.
+
+ [postel@isi.edu anant@isi.edu jaffe@noc.rutgers.edu
+ 28apr93]: negative caching
+ Paul:
+ We'ed like to have included in 4.9.1
+ our implemention for negative caching.
+ --jon & Anant.
+
+ [vixie@pa.dec.com 16may93]: inet_addr needs to die
+ to be replaced by calls to inet_aton, which doesn't confuse the
+ broadcast address with bad addresses.
+
+ [Paul: I know you said that you'd like to wait for the IETF DNS WG to
+ "bless" an official load balancing scheme, but I'll be adding my
+ shuffle A records to BIND 4.9 for use here at U-M anyhow. The code
+ mods to existing source files are minimal since the bulk of the work
+ is done in a separate .c I added. If you don't want SA records to
+ move into 4.9.1 unless they become official, please just toss this
+ first entry. --bryan@umich.edu]
+
+ [bryan@umich.edu 25apr93]: add "shuffle A" records
+ There are several schemes for adding some kind of load balancing
+ capability to the DNS. Our "Shuffle Address" (SA) records are one
+ stab at this, and since they're in use at U-M, I need to add them
+ so we can use BIND 4.9 here.
+
+ [bryan@umich.edu 25apr93]: add AFSDB records
+ AFSDB records were proposed in RFC xxxx. We use them here at the
+ University of Michigan, so I need to add them for our copy of
+ BIND 4.9.
+
+ [bryan@umich.edu 25apr93]: small fix to resolver's p_cdname()
+ The current copy of p_cdname() in the resolver does not work
+ for query responses larger than 512 bytes (which can happen when
+ using TCP). A very small modification changes the "sanity check"
+ argument (the second one) to dn_expand() from "msg + 512" to
+ "cp + MAXCDNAME". (This showed up very recently.)
+
+34. While waiting for some last minute changes from volunteers, I looked
+ at my work queue and saw that asp@uunet.uu.net had asked a while ago
+ that named not fork/exec a named-xfer unless it had already determined
+ that the serial number was out of date. This is important to sites like
+ UUNET and DECWRL, which have thousands of "secondary" lines in their
+ named.boot and can take hours to check all the serial numbers at boot
+ time if named forks/execs named-xfer and lets named-xfer compare the
+ serial numbers, rather than comparing them in named and only fork/exec'ing
+ a named-xfer if it's actually neccessary to do a transfer. In spite of
+ C's lack of threads, this only took a few hours to do. So it's in.
+
+33. Gregory Shapiro's "secure_zone" changes are in. See the BOG.
+
+32. Internals changes: STATS is no longer optional; ns_req() has been split
+ into three functions for readability. Convex systems are now supported.
+ You can now define LOG_FAC in conf/options.h if you want to syslog as
+ LOG_LOCAL1 or some other non-LOG_DAEMON value. The mkstemp() problem on
+ ULTRIX has been fixed. More dead code has been eliminated.
+
+31. Large TCP queries are now printable in debug mode (which is used by
+ "dig" and "nslookup"), thanks to a patch and a lot of patient explain-
+ ations from Bryan Beecher.
+
+30. Data from subdomains ("deeper zones") is now considered more credible
+ than data from parent zones, if both are authoritative. This permits
+ a subdomain's data to differ from its parents delegation information
+ and have the most-local information supercede the least-local. Mark
+ Andrews <marka@syd.dms.csiro.au> sent this in, and it is nonoptional.
+
+29. rossc@ucc.su.oz.au's SUNSECURITY patch is now included, along with
+ marka@syd.dms.csiro.au's performance improvement to it. Note that
+ I am violating my own policies by including this, since it came
+ without a corresponding patch to OPTIONS, conf/options.h, and the BOG.
+
+28. Interfaces with multiple addresses were not being handled properly.
+ This is an issue for 4.3-Reno and later BSD systems, including BNR2
+ ("Net-2") and 4.4BSD. Multiple addresses are not properly handled
+ as if they were all aliases for the localhost.
+
+27. Jukka Ukkonen <ukkonen@csc.fi> sent me some patches for the Convex,
+ which I've put it but cannot test.
+
+26. sob@tmc.edu (Stan Barber) sent me new versions of contrib/host/host.c
+ and contrib/host/send.c, which I have installed but not tested. I am
+ still waiting for someone to update the version in tools/host.c, which
+ is going to be a lot more work. Contact me via e-mail if you want to
+ help.
+
+25. My credibility stuff from the original 4.9 (and before that, KJB)
+ was operating under a ``scorched earth'' policy due to a brain fault
+ on my part when I wrote the code originally. Tim.Goodwin@pipex.net
+ discovered this and sent in a patch. Note that throwing out glue is
+ generally OK since glue is generally NOT OK, but disposing of it after
+ ~20 references is a lot better than disposing of it after 1 reference.
+
+24. NS RR sorting on forwarded and system queries was not happening
+ unless more than 1024 milliseconds of RTT variance existed among
+ the servers. This was a good value for development and testing
+ but not for production use. The value is now 128 milliseconds.
+ No, this should not be a configurable in the boot file.
+
+23. I am including a file doc/FAQ which was posted to usenet as:
+ From: craig@ecel.uwa.edu.au (Craig Richmond - division)
+ Newsgroups: comp.protocols.tcp-ip.domains
+ Subject: FAQ: Setting up a basic DNS server for a domain
+ Date: 3 Aug 1993 10:53:51 GMT
+ Organization: The University of Western Australia
+ Lines: 1088
+ Message-ID: <23lg3v$1go@uniwa.uwa.edu.au>
+ Summary: Step by Step implementation of a DNS server
+ Keywords: FAQ DNS setup
+
+22. named-xfer now syslogs if the remote server's serial number is _lower_
+ than ours, which does seem like a bad thing. per@erix.ericsson.se
+ (Per Hedeland) sent this in.
+
+21. man/resolver.3 had a typo on the exp_dn argument to dn_expand. fixed.
+ (Steve Alexander <stevea@lachman.com> sent this in.)
+
+20. include/sys/cdefs.h moved to compat/include/sys/cdefs.h since some
+ systems have their own which must be used. the top-level makefile
+ must be edited if you are on one of these systems, since the default
+ CFLAGS includes this new directory as a -I directive. sys/bitypes.h
+ has also moved.
+
+19. A neccessary bug fix for ISI's VALIDATE/NCACHE code has been incorporated.
+ If you had to rebuild without these turned on in options.h to get your
+ CNAME lookups to work again in an earlier 4.9.2 ALPHA, you can turn them
+ on again now.
+
+18. The q_system field of the query structure has been removed in favor of
+ a q_type field containing bit definitions. The old PRIMING_CACHE magic
+ cookie is no longer used. Go to the end of the universe, do not pass go.
+
+17. Converted to ANSI C. All functions are static unless they are actually
+ needed outside the current module ("file" in C terminology); static
+ functions are declared with prototypes if they are forward-referenced.
+ Externally visible functions are declared in separate header files, with
+ prototypes. ns.h and db.h have been split into four new header files:
+ db.h -> db_defs.h db_glob.h db_func.h
+ ns.h -> ns_defs.h ns_glob.h ns_func.h
+
+ The *_defs files contain only structure and type definitions, and macro
+ definitions. Nothing that generates text or data space in the executable
+ is declared here.
+
+ The *_glob files contain only global variable declarations, which used to
+ be defined in the various *.c files in a more or less random fashion. The
+ declarations are "extern" if included from non-main()-containing files, but
+ are defined globally and given initial values in main()-ish files. This
+ reuse of the same declarations insures that the type and size declarations
+ match between definitions and external references to them.
+
+ The *_func files contains function prototypes for global ("extern")
+ functions. The prototypes are all optional so will not break non-ANSI
+ systems. Note that I don't have such a system any more so I may be wrong.
+
+16. Removed all remaining references to "short" or "long" that did not
+ depend on the vague semantics of those types. Most uses were actually
+ depending on a size of 16 bits for short and 32 bits for long, and there
+ are processors/compilers where each of these types is different. This
+ work was begun in 4.9 and is now complete. Note that some structs that
+ are used in large data structures use "char" for 8-bit integers. It helps.
+
+05Jul93 - ALPHA Released
+
+This is the cleanup release after 4.9. I'm going to try the TCSH style of
+logging the changes; let me know if you think it's a bad way of doing it.
+
+15. the resolver now includes an implementation of RFC 1101, which allows
+ network names to be encoded in the DNS tree rather than in /etc/networks.
+ this implementation is by rps@matuc2.mat.uc.pt (Rui Pedro Mendes Salgueiro)
+ i put the test program and original documentation in contrib/rfc1101/. i
+ would like to see their main.c ("nettest") turned into a tools/nettest,
+ but i'm not willing to do the work myself. it needs a man page, etc.
+
+14. as expected the initial HS zone transfer stuff didn't work that well.
+ thanks to <per@ericsson.se>, retries after failed SOA queries will use
+ C_IN rather than falling through to C_HS inappropriately.
+
+13. ns_init.c was fcntl(SETFL)'ing in a destructive way. it now does a
+ fcntl(GETFL) to get the old option mask and then |'s in the new flag.
+ this patch came from Eduard Vopicka <Eduard.Vopicka@vse.cz>.
+
+12. there are two new conf/Info.* files; check 'em out.
+
+11. ultrix (some versions, especially the vax ones) libc.a had some bad
+ naming conventions for some resolver routines. getshort/putshort just
+ have to be real functions, not just macros, or you can't link anything
+ with this resolver. patch was sent by <aas@brain.physics.swin.oz.au>.
+
+10. sethostent(x) for host files was sticky for nonzero 'x' (avalon@anu.edu.au)
+
+9. hp9000s700 is now supported in include/arpa/nameser.h (avalon@anu.edu.au)
+
+8. statistics dumps now print the time in decimal-seconds-since-1970 in
+ addition to the old "ctime" format, for ease of debugging. (Peter Koch).
+
+7. systems with 14-character filename limitations have apparently been
+ having trouble in named-xfer since its temporary file names are bigger
+ than they can handle. ash@hp sent in some patches a while ago, enabled
+ with SHORT_FNAMES in conf/options.h, to deal with this appropriately.
+ We should probably just generate short names always.
+
+6. Some security stuff from ISI. According to Anant Kumar <anant@isi.edu>:
+
+ The validation procedure is the major change here. Currently, we
+ accept anything from a server, as long as we had asked it a question.
+ This implies that a malicious server can really send us any data and
+ we not only pass it on, we also cache it for as long as the TTL
+ holds. This can be really bad for our health and for that of those
+ who use the DNS.
+
+ We add this procedure to verify for each RR returned by a server
+ that it is indeed authoritative for either that zone, or for a
+ parent zone. We end up trusting the root servers for everything!
+ Also, the more rich our cache is the more choosy we become about the
+ data we add on to it. This stuff is all ifdef'd with "#ifdef VALIDATE"
+
+ The negative caching stuff adds on a d_rcode field to the databufs.
+ Any positive entry now shows a NOERROR there while negative entries
+ have either a NXDOMAIN or NOERROR_NODATA. NOERROR_NODATA rcode is
+ never returned. It is used only to differentiate, within the
+ internal database, between negative and positive entries. We use the
+ regular hash table (hashtab) to store negative entries, too. Only
+ authoritative answers are negative cached, for NTTL (parameterized,
+ currently 10 minutes) seconds. Non-authoritative NXDOMAINs or
+ NOERROR with zero RR count, now generated, are now accepted but
+ never cached. This is ifdef'd with "#ifdef NCACHE".
+
+5. "make install" now has a prayer of working for the man pages. an observation
+ was made that net2++ systems _require_ formatted "cat" pages and that older
+ systems are _able_ to use them, so that's all we install.
+
+4. i wrote man pages for named.reload, named.restart, and named-xfer. these
+ were actually in 4.9.1 for 4.4BSD.
+
+3. unneeded functions in compat/lib will now generate placeholder symbols, to
+ make sure that the linker doesn't generate ugly-but-harmless warnings.
+
+2. my ignorance of the true meaning of _POSIX_SOURCE has been corrected,
+ along with the ugly-but-working code in conf/portability.h and elsewhere.
+
+1. non-resolver routines moved from res/ to compat/lib/. this will shorten
+ libresolv.a and make it easier to integrate new BIND releases into Net-2
+ descendents such as 4.4BSD and BSD/386.
+
+4.9.1 ------------------
+
+This is the integration of the changes that were made for 4.4BSD. This
+release will not be published. Changes include:
+
+doc/BOG/*: many changes to improve appearance of the output, including
+ orphan-avoidance and better tab stops. Sent to me by someone on
+ the net who deserves thanks but I've lost the original mail. Oops.
+
+include/*: the CSRG people weren't entirely pleased with the interface
+ changes i made to the res_*() and inet_*() functions. in particular,
+ the changes from "long" to "u_int32_t" were too sweeping in their
+ opinion since Posix is already working on standardizing them and
+ might look unkindly on an apparently-still-evolving interface. also,
+ the possibility that all the vendors will change their implementations
+ to match the new interface is apparently rather dim. therefore most
+ externally-visible occurances of the int32_t type have been changed
+ back to "long" in the resolver interface. we believe that this should
+ still be portable to Cray and AXP machines, but i'll wait to hear from
+ someone who can actually try it out and let me know.
+
+tools/*: the "net2" version of "lex" requires some additional flags and libs,
+ and this had implications for the Makefiles and the dig.c source file.
+ nslookup's man page is now in man/ rather than tools/nslookup, for
+ consistency.
+
+named/*: last-minute 4.9-FINAL changes to named-xfer.c and db_load.c resulted
+ in corruption of TXT records on zone transfers, and a high number of
+ useless syslog(SYS_ERR) messages about zones already being up to date.
+ these last-minute changes have been massaged into better shape and are
+ now a lot readier for prime time than they were. a lesson was learned.
+
+ the inet_aton() function is now used where appropriate, rather than the
+ old inet_addr(). this is just an evolutionary move that should have no
+ practical implications. bad addresses in the "tcplist", "bogusns", and
+ "sortlist" directives (from named.boot) are now syslogged.
+
+ some open files are still inherited by named-xfer from named, but they
+ are properly closed now.
+
+ the SIGXFSZ signal is now accepted as an alias for SIGHUP, in support
+ of the wierd DEC Hesiod implementation. no practical significance.
+
+res/*: one important bug fix in the gethostent() stuff, and a whole bunch of
+ evolutionary include file changes.
+
+include/*: include/sys was moved to compat/include/sys, since systems that
+ do not need it really really really need to get their own instead.
+ at some point i'm going to move the res/*.c files that are needed for
+ compatibility but not really part of the resolver, into compat/lib.
+
+general: there are more settable parameters in the top-level Makefile, and
+ they are propagated downward into the subdirectories' Makefiles. you
+ should not have to edit any Makefile except the top-level one. Note
+ that "make links" still creates local Makefiles in the build directory
+ because "mkdep" still edits the Makefiles on most systems.
+
+4.9-FINAL -------------------
+
+Kevin Dunlap sent in some changes for the BOG. So did a lot of other folks.
+
+Someone asked about AXP-OSF, so I did a trivial 64-bit port. Porting to
+other 64-bit systems should be simple now. Someone also sent in some MIPS
+RISCOS portability changes, which were simple and therefore were put in.
+Note that some type names have been added to BSD 4.4 as a result of this
+work; they are going to be in <sys/types.h> in BSD 4.4 but they are in a
+local include file called <sys/bitypes.h> in this distribution, with
+appropriate #ifdef's in the include files that depend on them. Those of you
+who are porting to 64-bit platforms where "long" isn't 32 bits should be
+using these new names for your types; there was no standard before this,
+but the names we've added for BIND 4.9 and BSD 4.4 are going to be proposed
+to Posix at some point. Sometimes it's just not OK for "int" to be the
+"natural integer size of the machine" and you just _have_ to tell the compiler
+how many bits you want.
+
+The NIC added a new root server, thus pushing the size of a nonauthoritative
+root server response (which includes the root server list in the answer as
+well as the authority sections) over the 512-byte limit. This showed up a
+long-term BIND bug wherein it failed to set the TC ("truncation occurred")
+bit if truncation occurred anywhere but the answer section. Since truncation
+was occuring at the end of the packet, in the additional data section, this
+meant that BIND was generating truncated responses without setting TC in the
+response header. Upon further investigation, I found that BIND ignored TC
+on responses it received from other name servers. RFC 1035 states that RR's
+from truncated responses should not be cached; with creative interpretation
+of the exact 1035 wording, I found a way to reach this goal while still
+caching the answer section (as long as the truncation occurred in some other
+section, which 1035 gives no definitive way to determine but I'm happy with
+my guess).
+
+While researching the above, I finally broke down and added credibility
+output to the zone dump files. They are in the comments so should cause
+no trouble. There's more work to be done on the dump output; in particular,
+Phil Almquist proposed and even prototyped a "tagging" of all RR's with the
+A RR of the nameserver that sent them to us; this feature should be added
+and the dump output should include it. This would add a lot to our ability
+to track down corrupt data.
+
+Don Lewis and I had more discussions about TC and ended up agreeing that the
+right thing to do is to set TC on responses that overflow in the answer or
+authority section, truncating at an RR boundary, but do not set TC on responses
+that overflow in the additional-data section (truncating at a {name,type}
+boundary). This actually solves the root server problem pretty well, since
+BIND 4.9 will, when it tries to use an NS whose A isn't in the cache, generate
+a sysquery() for the missing A. (Heck, additional data TTL's are depreciated
+at the rate of 5% per use, so this would end up happening pretty quickly even
+if we did cache a partial {name,type} -- but now we won't have to.)
+
+While trying to fix all of this stuff I ended up moving some functions around
+to avoid duplicating them in different source files, and I reformatted some
+source lines that went over 80 characters. I also made a few things "static"
+that used to be unneccessarily global. More of that will happen in 4.9.1.
+
+DEC's product version of MIT Hesiod uses SIGXFSZ for what we do with SIGHUP;
+since the default for SIGXFSZ is to exit, it seemed prudent to wire it up to
+do what SIGHUP does instead, so that this BIND can run on DEC Hesiod servers.
+
+At the request of several people, I integrated the USC "dig" and Rutgers
+"host" tools into the distribution. This required some changes to the
+resolver library's debugging output formats, which will be visible in
+nslookup, nsquery, and any other tool that sets the RES_DEBUG option.
+Note that there is no support for "DEFNAMES" in this version of dig, due
+to design changes between 4.8 (from which "dig" is derived) and 4.9. there
+is no reason in principle why it can't be made to work, but it doesn't work
+now. therefore only fully-qualified names can be looked up with this "dig".
+
+I had to change the name of the resolver "state" structure to be "__res_state"
+for standards conformance (really, it is not reasonable to expect that because
+a program includes <resolv.h> it will never define its own structure called
+"state". This change highlights the imperative that any application which is
+relinked against this resolver must first be recompiled against these include
+files (notably <resolv.h>). This is true for almost all versions of libresolv.
+
+I asked for items for the "TODO" list and got quite a few. Check them out
+before you hack; someone else may already have started doing what you want to
+do. I also asked for tools for the "contrib" subdirectory and got 650KB worth.
+They make the BIND 4.9 distribution a lot larger than 4.8.3 was, but the extra
+bytes are well worth their weight.
+
+Kenneth Almquist (no relation to Phil, as far as I know) posted a patch for
+res_send() that lets it keep track of servers that are responding "SERVFAIL"
+or some other fatal condition; these servers are NOT used for retries of the
+current query. This information is not persistent between calls to res_send()
+since future calls will probably be for different {name,type} queries, which
+will not neccessarily fail in the same way. This change is trivial and makes
+a measurable difference in the amount of DNS traffic on my local net.
+
+4.9-BETA ------------------- April 17, 1993 -- Paul Vixie -- DECWRL
+
+"Peter Koch" <pk@TechFak.Uni-Bielefeld.DE>'s previous patch caused core
+dumps on some systems. I fixed part of it and Peter sent me a fix for
+the rest of it. All is now well.
+
+The Bind Operations Guide in doc/BOG has been updated to 4.9. Also, the
+man page in man/named.8 has had some patches applied. The copyrights are
+all fixed now. Let's get this thing OUT of here!
+
+4.9-ALPHA ------------------- March 15, 1993 -- Paul Vixie -- DECWRL
+
+There was a really bad bug affecting wildcards. I received a patch
+from "Peter Koch" <pk@TechFak.Uni-Bielefeld.DE> which fixes some of
+it, but I can't quite motivate myself to fix the rest of it since I
+know that what's _really_ wrong is going to require chainsaws and
+dynamite to fix and that'll add another year to the release. I think
+that this patch will hold us for a while.
+
+There are a LOT of portability changes that I'm holding onto, especially
+including 64-bit fixes. Do not submit any more portability changes
+until 4.9.1 opens. Go ahead and make them, but be prepared to remake
+them later. Let me know what you are doing but don't send me any diffs
+for portability until I ask for them. 4.9 has been stuck in the barrel
+for way too long already -- patches that don't fix RFC-noncompliance or
+core dumps will just go into my "todo" folder (which is presently a
+black hole of great mass).
+
+4.9-ALPHA ---------------- Febrtuary 2, 1992 -- Paul Vixie -- DECWRL
+
+Mostly portability fixes. The nslookup "lex" problem is BSDI-specific
+and I'm not going to hold up release because of it. This will be the
+last alpha release before the public beta. It is, as usual, running
+the DEC.COM primary name service and has done so for more than a week
+without any problems.
+
+4.9-ALPHA ---------------- January 10, 1993 -- Paul Vixie -- DECWRL
+
+Once I get the known bug in nslookup (see below) fixed, this version is going
+to go into public beta. I would appreciate it if everyone would try it out.
+
+KNOWN BUG IN THIS RELEASE: something wild is going on inside of the yylex()
+routing on BSD/386 systems. It only affects nslookup. I'm still trying to
+figure out how I'm going to debug this; lex experts, please see what's going
+on. None of the changes since the 930105 release should have been capable
+of producing this change, but something is sure doing it.
+
+I finally fixed the {GET,PUT}{SHORT,LONG} macros to stop issuing warnings
+on HP-UX systems. They are also warning-free on Ultrix(SPIM,VAX), BSDI(386),
+and SunOS(SPARC) systems. I took the plunge and changed the internal functions
+in res/res_comp.c to depend on these macros instead of duplicating the code,
+and everything still works.
+
+Tom Limoncelli found three ancient memory leaks. I fixed two of them
+but the last one looks too much like a "cannot happen" for me to be
+willing to experiment with it. Besides which, it's "very" minor.
+
+Uses setsid() on POSIX systems. PID file is now optional. (arc@sgi)
+
+Comments (";" or "#") are now allowed in resolv.conf (arc@sgi).
+
+Documentation and copyright changes in README.
+
+Known to compile on NeXT machines.
+
+Some portability changes for AIX, whose CC is very picky.
+
+I forgot to mention in the 921227 release that T_RP is supported (arc@sgi).
+
+I included a number of changes that Alan Barrett has been trying to get
+in since the 921221 version. Most are portability-related, and the few
+things that are functional are changes to my own previous additions :-),
+so I'm fairly sure that they are doing the right thing. Alan's changes
+include:
+
+ include/arpa/nameser.h
+ improved error diagnosis in the BYTE_ORDER configuration.
+
+ changed hp9000 test to hp9000s300. As far as I know, there is
+ no hp9000 preprocessor symbol. Should probably add other
+ hp9000s<whatever> tests, but have not done so.
+
+ named/ns.h
+ Moved the XFER-related stuff from the end of the file to near
+ the top, where it is grouped with similar stuff.
+
+ Makefiles:
+ Add SYSLIBS variable, so folk can compile with -lBSD easily.
+
+ Changed install targets to make them easier to customise.
+
+ make links wasn't handling named.{reload,restart}*
+
+ Add ${CDEBUG} flag to link step. Some debuggers don't work
+ right if the program isn't linked with the -g flag.
+
+ struct timeval members are declared as unsigned long on some systems.
+ Add casts to (long) in several if statements that appear to assume
+ that tv_sec is signed.
+
+ PID_FIX in ns_main.c controlled more than just whether or not the
+ pid file gets fixed.
+ Changed it to control only that one feature.
+
+ For debugging, it is useful for a nameserver to listen to non-standard
+ port, but to forward requests to a standard port.
+ Add "-p remote/local" option to named/ns_main.c.
+ Also needed some other changes elsewhere.
+
+ Don't forward back to the host that asked us a question, unless they
+ asked from some port other than their nameserver port. This allows a
+ dig or nslookup user on a host to ask us questions with
+ recursion-desired, where we are willing to recursively ask the
+ nameserver on their host. However, if a nameserver asks us something
+ we will not recurse back to them.
+ nslookup() in named/ns_forw.c checks for this and returns -1.
+ ns_forw() and sysquery() notice this and return SERVFAIL.
+
+ Moved the nsContainsUs functionality from a separate routine
+ into nslookup(). No need to do the same tree walk several times.
+
+ While trying to track down various problems, added detection
+ and logging of errors in several syscalls in ns_main.c.
+
+ Avoid integer overflow in roundtrip time calc in ns_resp.
+ This needs a definition for INT_MAX.
+
+ Fixed root zone transfer bug. Also corrected some slightly misleading
+ comments in the doaxfr() code, and added some more comments.
+
+4.9-ALPHA ---------------- January 5, 1993 -- Paul Vixie -- DECWRL
+
+This one was built and tested on Ultrix 4.2 (SPIM, MIPS CC and GCC),
+BSD/386 (Gamma.4), Sun SPARC (4.0.3, sorry, that's the latest I have),
+4.3BSD Reno (VAX, PCC), and Ultrix 3.0 (VAX PCC).
+
+Moved res/defs.h to conf/portability.h; named/options.h to conf/options.h.
+
+Portability changes for O_NDELAY. SUNOS is really strange about this.
+
+Removed some unneccessary goto's added to ns_main.c on 1jan. Oops.
+
+Art Harkin of HP sent in a number of small (read: obviously correct)
+improvements, some related to portability, some to functionality.
+
+4.9-ALPHA ---------------- January 1, 1993 -- Paul Vixie -- DECWRL
+
+Changed all O_NONBLOCK to O_NDELAY. Changed all {r}index to str{r}chr.
+
+Added some SysV support in the form of bcopy->memcpy, bzero->memset.
+
+Added C_HS support to named-xfer (greg@duke.cs.unlv.edu).
+
+Fixed a line-number problem in asp's "include" logic (asp@uunet.uu.net).
+
+streamq's were being used after free(). bug report from fuat@ans.net
+and jpe@ee.egr.duke.edu. bug fix by vixie.
+
+In the resolver, we now default to address 127.0.0.1 rather than 0.0.0.0.
+There's a comment in the code that explains why.
+
+In the resolver, arc@xingping.esg.sgi.com changed it to use inet_aton()
+and included that function for those not running 4.4bsd.
+
+arc@xingping.esg.sgi.com also provided lots of portability fixes and
+general cleanups, in particular to nslookup which he maintains for CSRG.
+
+4.9-ALPHA ---------------- December 27, 1992 -- Paul Vixie -- DECWRL
+
+Added strtoul() to libresolv.a since it's yet another neccessary function
+that older systems don't have. If we can stomach strcasecmp() we can sure
+handle this.
+
+Moved res/named/gethostnamadr.c to res/gethnamaddr.c (note basename change)
+and res/named/sethostent.c to res/sethostent.c. Since the host table stuff
+isn't in separate files any more I saw no reason to retain the subdirectory.
+
+Updated all the copyrights and applied the small lint changes that bring
+the baseline of this version from "4.8.3 as seen on ucbarpa" up to "4.8.3
+as released with net-2". Thanks to the alpha testers for pointing this out
+to me and for sending in the diffs.
+
+With much howling and screaming, I ported this to UMIPS (MIPS System V).
+There are a lot of really bad things going on in their libc.a, and now
+they're going on in BIND as well.
+
+I added a "res/defs.h" file and then proceeded to include it from all kinds
+of files that aren't in res/. I'm thinking of moving it but I'm also trying
+to figure out where -- include/ is the wrong place. res/defs.h has in it all
+the ugly ifdef's needed to figure out whether this is a late-model BSD system,
+a POSIX system, or just old.
+
+All the "#endif" and "#else" cpp directives now have comments around their
+annotations. It turns out that System V CPP complains about "#endif DEBUG"
+but has no problem with "#endif /*DEBUG*/". In many cases where the #ifdef
+was obviously visible and unambiguous, I simply removed the annotation.
+
+The "l" is now a ";". Thanks to all who replied :-).
+
+There was a very bad bug in the named-xfer interface. 'nuff said.
+
+AIX needs a 32-bit field for PID's. I can't imagine. But it's fixed.
+
+The "domain" directive in named.boot is now an option, defaulting to off.
+
+There was a benign bug in sqrm().
+
+doaxfr() is now shorter and clearer.
+
+There is an "include" directive in the named.boot file now. Its syntax is
+simple: "include somefile". No quotes, no "#", no <brackets>. This feature
+was in 4.9-ALPHA as well, courtesy of Andrew Partan. I forgot to document it.
+
+4.9-ALPHA ---------------- December 21, 1992 -- Paul Vixie -- DECWRL
+
+This release incorporates fixes from a lot of people, including many from
+DECWRL. Some fixes are just lint; some are to avoid dumping core on non-VAX
+computers; many are to fix promiscuity, corruption, and rudeness.
+
+Various internal DEC programmers have ported the old 4.8.3 code to various
+not-entirely-BSD-like platforms and turned up some interesting lint. All
+of this has been fixed. Also, we fixed a bad bug in the handling of timeouts
+and SERVFAIL's when forwarders and slave are both used.
+
+I have made major changes to the code inside the ALLOW_UPDATES ifdef's, but
+I don't use it and have never compiled with that option turned on so I don't
+know if it still works. Given that SNMP has come and there is an IETF WG for
+SNMP management of the DNS, I am thinking very seriously of purging all of the
+ALLOW_UPDATES code in 4.9.1. I suspect that Mike Schwartz will let me know if
+this is ok..
+
+(interrim "KJB" notes) ------------------- March, 1992 -- Paul Vixie -- DECWRL
+
+If we are about to forward a query for some zone for which we are one of the
+servers, we send back a SERVFAIL instead. If we don't have it, chances are
+good that the other name servers won't have it either. This is the major
+cause of "network meltdown" when the root servers declare you as a name server
+for some zone you don't know about and havn't configured yourself for.
+
+Fixed a memory leak such that if db_update() fails to update the database
+from a response packet, a databuf will no longer be orphaned. Also fixed
+what looks like a similar leak in the ALLOW_UPDATES code but I don't use it
+that hasn't been tested.
+
+Fixed a memory sponge such that if we forward a query to someone who is not
+ever going to answer it, we will eventually expire it from our query queue.
+Previously it would expire after N retries to N' different servers, which
+could be a very long time. Particularly in the case of lame delegations and
+other forwarding loops, we feel that 90 seconds (two max-retry intervals) is
+enough time for a query to be answered. While we were into this code we made
+several fields in the query structure into "short"'s since they were only
+being used to store smallish integers. The query list gets Very Long during
+a forwarding loop -- even 90 seconds worth of queries is a lot of queries.
+
+This version includes my hacks that assign a "credibility index" to each
+<name,type> such that when more credible data arrives for a given
+<name,type>, all old data is purged. When equally-credible data arrives it
+is aggregated in the way we all know and love; when less credible data
+arrives it is completely ignored. Credibility, from best to worst, is:
+ 1. zone files (primary or secondary)
+ 2. authoritative answers
+ 3. non-authoritative answers and authority records
+ 4. additional data
+ 5. zone files ("cache" or "bootstrap" information)
+You need this version of bind if you still show any A RR's in network
+32.0.0.0 when you look up uucp-gw-1.pa.dec.com's A or adobe.com's NS.
+
+I have also added some extra code to prevent pollution of the internal
+"hint cache." In all versions of BIND that I was able to test, any IN_A
+response to any sysquery() would cause the IN_A RR to be added to the
+fcachetab ("hint cache"). This resulted in lots of extra cruft in the hint
+cache, that wasn't timed out properly, which in turn resulted in lots of
+strange answers ('nuff said, take my word for it.)
+
+Though changes have been made to make the Ultrix and GNU (2.1) C compilers
+stop complaining about the source, it should still compile and run just
+about anywhere. In fact, after I cleaned up lots of old lint, this version
+of BIND is known to compile and run on:
+
+ Ultrix 4.2 (MIPS or VAX)
+ SunOS 4.0.3
+ BSD/386 (BSDi beta)
+
+This was being released as King James Bind because, like KJ Sendmail, it is
+a merge of every major variant of Bind that we know about. It was
+assembled and tested by Paul Vixie of DEC NSL/WRL, with generous donations
+of code and advice from Win Treese of DEC CRL. Changes from Don Lewis of
+Harris, Andrew Partan of UUNET, and Piet Beertema of EUNet are also included.
+See the OPTIONS file for a description of the changes you can control with
+#ifdef's.
+
+This server has been run on UUCP-GW-{1,2}.PA.DEC.COM, which are in the UUCP
+Zone. Our named.boot file has ~1900 lines in it. Before we instituted the
+changes in this release, our name server usually ran at about 16MB virtual,
+15MB physical, growing slowly but constantly until we restarted it.
+Whenever a new zone was added to the NIC's root zone listing us as a name
+server, our servers would kill themselves and eachother (and NS.UU.NET, one
+of the other UUCP Zone name servers) with forwarding loops. After these
+changes, we run at a fairly constant 8MB virtual and physical size, and our
+apparent CPU utilization is always 0.0% since we never finish a quantum and
+the scheduler always sees us as waiting for I-O. In other words, life is good.
+
+Notes from UCB version 4.8.3 follow:
+
+-------------------
+
+This is version 4.8.3 of bind. It is a test release that updates
+versions 4.8 and 4.8.1 with fixes, and is essentially the same as
+the version of named on the 4.3BSD Reno release. Although it is
+currently described as a test release, it is believed to be reasonably
+stable and more usable than the previously-released versions.
+Here are some of the more important changes:
+
+ o A list of domains may be specified for searching in resolv.conf instead
+ of just the local domain name.
+
+ o gethostbyname() will accept a dotted quad.
+
+ o Support has been added for the the T_TXT data type and for the class
+ C_HS. These are both used by Hesiod from Project Athena at MIT.
+
+ o All of the pathnames have been put into one header file. This
+ makes it easier to change the location based upon your local
+ configuration.
+
+ o Responses are only accepted from an address to which we might of sent
+ the request. This might cause problems if some server is multihomed
+ and is still running BIND 4.3, but it prevents attacks induced by
+ sending responses from another address.
+
+ o Numerous bugs have been fixed: Adding a new authoritative zone now
+ works when the server has a cached SOA record. Comparisons in the
+ db now look at type and class as well instead of dropping records
+ with identical data. Scheduling of maintenance interrupts has been
+ moved to one routine avoid spurious ones. Named goes into the background
+ after more of the initialization is done. Stream connection queue
+ handling was cleaned up including a bug that caused data corruption
+ and core dumps. Sys5 no longer can have multiple transfers of the
+ same zone occuring at the same time. Handle CNAME -> CNAME loops
+ more gracefully. Avoid making one server never get queried. Border
+ conditions in resolver are checked more accurately.
+
+ o Nslookup has been updated.
+
+There are several bug reports that have yet to be integrated into this
+version. Hopefully they will be dealt with in the next release. Please
+send feedback on this release.
+
+Notes from versions 4.8.1 and 4.8 follow:
+
+------------------
+
+This is version 4.8.1 of bind. It is a test release that includes
+version 4.8 with fixes, asynchronous zone transfer and better reload
+capabilities. Although it is currently described as a test release,
+it is believed to be reasonably stable and more usable than the currently-
+released version, 4.8. The changes of note are:
+
+ o The asynchronous zone transfer code previously posted to the bind
+ mailing list has been integrated, completed and tested. There are
+ a number of changes from the version posted, including fixes to
+ allow top-level domains to work and a simplification of the timer
+ code.
+
+ o The code for reloading the server has been changed so that only
+ primary zones master files that have changed are reloaded. The
+ cache and secondary zones are not flushed, and the sortlist, domain,
+ etc. are reset to correspond to the boot file contents.
+
+ o Several bugs have been fixed: the name "*" is not interpreted as
+ a wildcard in cached zones, only in primary zones. Secondary servers
+ no longer decrement the time-to-live of records by the time since
+ they verified the zone with the master; as a result, they never
+ hand out nameserver referrals with too short a TTL to be usable.
+ A bug was fixed that caused secondary servers with out-of-date
+ zones to return empty answers between the actual expiration time
+ and the next timeout.
+
+There are several other bugs that have been reported but have not yet
+been fixed. In addition, the next regular release of named will
+support negative caching, but this has not been integrated.
+
+I would appreciate receiving feedback on this release; in particular,
+problems (or lack of problems) when installing on various systems.
+I attempted to update the SysV code when integrating the zone-transfer,
+but haven't tested it.
+
+The notes from version 4.8 follow.
+
+----------
+Welcome to version 4.8 of bind.
+
+There have been several changes to the named boot file (/etc/named.boot)
+of which you should be aware. The "domain" line for each zone is no longer
+needed, but one such line may still be used to specify a default domain
+to be used for queries containing names with only a single component.
+The term "suffixes", which was added in version 4.7alpha, has been removed.
+
+The manual page on named (named.8) has been updated to reflect all
+these changes. Please read this and look at the example files
+before installation. You should also note the changes in the
+resolver code to support non-fully-qualified addresses and per-user
+host aliases. See hostname(7) for an overview. Two new routines
+have been added to the resolver library since the last test release:
+res_query formulates a query, sends it, waits for a response and does
+preliminary error checking; res_search implements the search rules
+of gethostbyname using res_query.
+
+The MX lookup routine in sendmail has been modified to use res_search.
+Also, dn_skip takes an additional parameter and has been renamed
+to dn_skipname. While old sendmail binaries will work with the new
+version of bind, because of these changes, it is desirable to install
+new sendmail sources and recompile sendmail. Do not rebuild sendmail
+from old sources. The new sendmail is on ucbarpa.Berkeley.EDU for
+anonymous FTP from pub/4.3/sendmail.MX.tar and pub/4.3/sendmail.MX.tar.Z.
+
+There have been numerous changes to named, fixing most of the known
+bugs that can be fixed without major structural changes in the server.
+Several server configurations that failed before should now work.
+Certain robustness problems have been fixed, in particular bounds-
+checking when processing incoming packets. Two changes have been made
+in preparation for negative caching: SOA records are sent in the authority
+section in negative responses with NXDOMAIN set, and a bug was fixed that
+caused confusion and repeated requests if a response had no error, no answer
+and an SOA in the authority section. As such responses are already sent
+by other servers, and will be sent by the next release of BIND, it is
+important that all sites upgrade to this version as quickly as possible.
+
+The root "hint" cache and cache file remain the largest problem area,
+along with named's naivete in accepting bogus server's data.
+These will be addressed in the next release, along with asynchronous
+zone transfers, intelligent reloading of zone files, faster startup,
+and caching of negative responses.
+
+This version (4.8) will replace the last officially released version (4.5).
+Version 4.5 has a serious bug that causes the generation of a continuous
+stream of bogons to the root domain servers (bogus queries with the query
+response bit set and possibly garbage for nsid and rcode). It is imperative
+that these versions of named be replaced as fast as possible. We urge you to
+field 4.8 quickly, for the sake of the root domain servers.
+
+ Mike Karels
+ Jean Wood
+ bind@ucbarpa.Berkeley.EDU
+
+## ++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--
diff --git a/contrib/bind/INSTALL b/contrib/bind/INSTALL
new file mode 100644
index 0000000..69d572a
--- /dev/null
+++ b/contrib/bind/INSTALL
@@ -0,0 +1,74 @@
+$Id: INSTALL,v 8.6 1995/12/24 06:43:57 vixie Exp $
+
+THE FILES:
+----------
+INSTALL -- This file
+README -- Release announcements, tips and traps (some out of date)
+OPTIONS -- The options that can be turned on and off
+RUNSON -- What machines/compilers is BIND known to build on
+TODO -- Have spare time? Consider contributing to the project!
+doc/info/* -- Platform-dependent build hints
+
+HOW TO BUILD:
+-------------
+4.9.3 is considerably easier to build than previous releases. These
+are the instructions on how to compile the software. For information
+on how to create your configuration files (resolv.conf, named.boot, and
+zone files) see the doc/bog directory and/or get "DNS and BIND" by C.
+Liu and P. Albitz from O'Reilly & Associates, Sebastopol, CA, ISBN
+0-937175-82-X 1992
+
+Note: If you maintain a BSD or are otherwise running a 4.4BSD-based system
+ and want to integrate BIND into it, check out BSD/README.
+
+1. (optional) If you are going to compile for multiple platforms, you
+can make a symbolic link tree for each platform to save disk space. To
+create a directory called "sun4.dir", do:
+ make DST=sun4.dir links
+Now "cd sun4.dir" and you can do everything as if you had a complete
+copy of the source. Just be careful if you are modifying a file, make
+sure you turn any links into files:
+ mv file file.tmp ; cp file.tmp file ; rm file.tmp
+
+2. Edit "conf/options.h" and turn on any options that you want. The
+defaults are pretty reasonable for most installations.
+
+3. Edit "Makefile". Go to the section that describes your operating
+system and uncoment it out. Add any other variables (for example,
+I added a line "DISTHELP=/usr/local/lib".) If in doubt, use the
+default!
+
+4. "make" should build everything. Consider putting "./bin" in your
+path if "make depend" fails and you think bin/mkdep will help you out.
+
+ *** NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE ***
+
+ The next step (#5) will burn down files which were supplied with
+ your operating system. You should run the suggested "-n" first
+ and make sure you have saved any files you want to save.
+
+ *** NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE ***
+
+5. "make install" will install everything. You might first do
+"make -n install" to see what commands would be executed by "make install"
+to make sure you understand where everything is about to be installed.
+
+6. (optional, SunOS 4.1.x/NetBSD-1.x/Solaris 2.x only): You can integrate
+the new resolver (client-side) code into the shared libraries of your
+operating system so that all dynamicly linked programs take advantage of
+the new resolver. Read shres/<osname>/INSTALL to find out how to do it.
+
+
+
+HOW TO GET HELP:
+----------------
+If you have any problems or fixes send them to
+ bind@uunet.uu.net
+
+To be added to that mailing list, send mail to
+ bind-request@uunet.uu.net
+
+
+
+This INSTALL was originally written on 15Jul94 by Tom Limoncelli <tal@plts.org>
+Minor changes 23Dec95 by Christopher Davis <ckd@kei.com>
diff --git a/contrib/bind/Makefile b/contrib/bind/Makefile
new file mode 100644
index 0000000..1f01a42
--- /dev/null
+++ b/contrib/bind/Makefile
@@ -0,0 +1,783 @@
+# Makefile for BIND>=4.9 top level
+# vixie@decwrl December, 1992 [original]
+#
+# $Id: Makefile,v 8.39 1996/08/05 08:31:20 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--
+
+VER = 4.9.4-P1
+SHELL = /bin/sh
+MAKE = make
+DESTDIR =
+
+INCL = include
+RES = res/libresolv.a
+COMPLIB = compat/lib/lib44bsd.a
+
+# The default build parameters are given for 4.4 BSD. They should
+# be overridden for other operating systems as indicated below.
+
+#(BSD4.4, BSD/OS, FreeBSD, NetBSD, other net2-alikes)
+#
+# DO NOT COMMENT THESE OUT. OVERRIDE THEM BELOW.
+#
+CC = cc $(CPPFLAGS)
+LDFLAGS =
+CDEBUG = -O -g
+CPPFLAGS=
+INDOT =
+XFER_INDOT =
+LEX = lex -I
+LIBS = -ll -lutil
+PIDDIR = /var/run
+DESTBIN = /usr/bin
+DESTSBIN = /usr/sbin
+DESTEXEC = /usr/libexec
+DESTMAN = /usr/share/man
+DESTHELP = /usr/share/misc
+DESTLIB = /usr/lib
+DESTINC = /usr/include
+COMPINCL = compat/include
+LDS =
+CATEXT = 0
+INSTALL_COMPAT = install
+INSTALL = install
+RANLIB = ranlib
+AR = ar cru
+MANROFF = ( tbl | nroff -man )
+MANDIR = cat
+PS = ps
+IOT = ABRT
+SHCC =
+SHLD =
+
+# (NetBSD - for details on shared library building, see shres/netbsd/INSTALL)
+#uncomment next three lines to build a shared library version of libresolv
+#SHRES = shres/netbsd
+#SHCC = cc
+#PIC = -fpic
+
+#(Linux - on modern systems, all you need to do is rename or remove
+# compat/include/sys/cdefs.h. See doc/info/Linux for more information.)
+#CC = gcc $(CPPFLAGS)
+#CDEBUG = -g
+#CPPFLAGS = -DSYSV
+#LIBS = -lfl
+#DESTEXEC = /usr/sbin
+#DESTMAN = /usr/man
+#DESTHELP = /usr/lib
+#CATEXT = $$$$N
+#PS = ps -p
+#IOT = IOT
+
+#(CRAY)
+#CDEBUG = -g
+#LEX=lex
+#IOT = IOT
+
+#(DEC AXP OSF/1 Version 2.1 and earlier)
+#CC = cc $(CPPFLAGS)
+#CDEBUG = -g3 -O2 -Olimit 2000
+#CPPFLAGS =
+#LEX = lex
+#LIBS = -ll -lutil
+#DESTEXEC = /usr/sbin
+#COMPINCL = compat/include
+#INSTALL_COMPAT = install-compat
+#INSTALL = installbsd
+#MANDIR = man
+#MANROFF = cat
+#CATEXT = $$$$N
+#PS = ps -p
+#IOT = IOT
+
+#(DEC AXP OSF/1 Version 3.0 and after)
+#CC = cc $(CPPFLAGS) -std
+#CDEBUG = -g3 -O2 -Olimit 2000
+#CPPFLAGS =
+#LEX = lex
+#LIBS = -ll -lutil
+#DESTEXEC = /usr/sbin
+#COMPINCL = compat/include
+#INSTALL_COMPAT = install-compat
+#INSTALL = installbsd
+#MANDIR = man
+#MANROFF = cat
+#CATEXT = $$$$N
+#PS = ps -p
+#IOT = IOT
+
+#(irix4)
+#CC = cc $(CPPFLAGS) -xansi -signed
+#CDEBUG = -g
+#CPPFLAGS = -D__STDC__ -D_BSD_SIGNALS -DSIG_FN=int
+#LEX = lex
+#LIBS = -ll
+#DESTSBIN = /usr/etc
+#DESTEXEC = /usr/etc
+#DESTMAN = /usr/catman/local
+#DESTHELP = /usr/lib
+#INSTALL = bsdinstall.sh
+#RANLIB = :
+#PS = ps -p
+#(bsdinstall.sh is in conf/)
+#IOT = IOT
+
+#(irix5)
+#CC = cc $(CPPFLAGS) -xansi -signed
+#CDEBUG = -g
+#CPPFLAGS = -D__STDC__ -D_BSD_SIGNALS -DSIG_FN=void -D__BIT_TYPES_DEFINED__
+#LEX = lex
+#LIBS = -ll
+#DESTSBIN = /usr/etc
+#DESTEXEC = /usr/etc
+#DESTMAN = /usr/share/catman/local
+#DESTHELP = /usr/lib
+#INSTALL = bsdinstall.sh
+#RANLIB = :
+#PS = ps -p
+#(bsdinstall.sh is in conf/)
+#IOT = IOT
+
+#(sunos4.x)
+#CC = /usr/bin/cc
+#CDEBUG = -g
+#CPPFLAGS = -DSUNOS4 -DSPRINTF_CHAR
+#INDOT = in.
+#XFER_INDOT = in.
+#LEX = lex
+#LIBS = -ll
+#(add "-ldl" to LIBS if your links fail with "dlopen" problems. this indicates
+# that your libc.so file is screwed up, but it's easier to fix this than that.)
+#PIDDIR = /etc
+#DESTSBIN = /usr/etc
+#DESTEXEC = /usr/etc
+#DESTHELP = /usr/lib
+#COMPINCL = compat/include
+#MANDIR = man
+#CATEXT = $$$$N
+#MANROFF = cat
+#INSTALL_COMPAT = install-compat
+#INSTALL = install
+#IOT = IOT
+# (for details on shared library building, see shres/sunos/INSTALL;
+# note that shres/solaris/INSTALL has some good testing notes for sunos)
+#uncomment next line to build a shared library version of libresolv
+#SHRES = shres/sunos
+# uncomment only one of the pairs of lines below
+# -- if you use gcc (recommended)
+# (if -fpic doesn't work, see shres/sunos/PROBLEMS)
+#SHCC = gcc -DSUNSECURITY $(CPPFLAGS)
+#PIC= -fpic -D_res=_res_shlib
+# -- if you use Sun's cc
+#SHCC = /usr/bin/cc -DSUNSECURITY $(CPPFLAGS)
+#PIC = -pic -D_res=_res_shlib
+
+#(ULTRIX/RISC - also see below)
+#CC = cc $(CPPFLAGS) -Olimit 2000 -YPOSIX
+
+#(ULTRIX, other 4.[23]bsd-alikes)
+#CDEBUG = -g
+#CPPFLAGS =
+#LEX = lex
+#LIBS = -ll
+#PIDDIR = /etc
+#DESTSBIN = /usr/etc
+#DESTEXEC = /usr/etc
+#DESTHELP = /usr/lib
+#COMPINCL = compat/include
+#CATEXT = $$$$N
+#INSTALL_COMPAT = install-compat
+#INSTALL = install
+#DESTMAN = /usr/man
+#MANDIR = man
+#MANROFF = cat
+#IOT = IOT
+
+#(solaris2.x/sunos5.x)
+#be careful with installation - note in particular that the system ships
+#with /usr/sbin/in.named (with in.) and /usr/sbin/named-xfer (without in.)
+#to emulate this naming, INDOT should be set to 'in.' while XFER_INDOT
+#should be empty. also, under solaris2.x, use 'make install' at your own risk.
+#don't include sys/stream.h via netinet/in.h by defining _SYS_STREAM_H.
+#->and note that sun moved their nslookup to /usr/sbin for some odd reason;
+# when you install this one in /usr/bin you should delete sun's or else you
+# will get confusing results since you never know which nslookup you're using.
+#PIDDIR = /etc
+#LEX = lex
+#uncomment next line for Sun C compiler
+#CC = /opt/SUNWspro/bin/cc $(CPPFLAGS) -R$(DESTLIB)
+#uncomment next line for GNU C compiler
+#CC = gcc $(CPPFLAGS) -Xlinker -R$(DESTLIB)
+#otherwise uncomment the next line and hope for the best
+#CC = cc $(CPPFLAGS)
+#CDEBUG = -g
+#CPPFLAGS = -DSVR4 -D_SYS_STREAM_H $(SOLCOMPAT)
+#INDOT = in.
+#XFER_INDOT =
+#LIBS = -ll -lnsl -lsocket
+#DESTEXEC = /usr/sbin
+#DESTHELP = /usr/lib
+#LDS = :
+#INSTALL = /usr/ucb/install
+#RANLIB = :
+#ARPREF = `lorder
+#ARSUFF = | tsort`
+#MANDIR = man
+#MANROFF = cat
+#CATEXT = $$$$N
+#PS = ps -p
+#IOT = IOT
+#uncomment next line for link-compatibility with Solaris resolver library
+#SOLCOMPAT = -Dgethostbyname=res_gethostbyname \
+# -Dgethostbyaddr=res_gethostbyaddr -Dgetnetbyname=res_getnetbyname \
+# -Dgetnetbyaddr=res_getnetbyaddr -Dsethostent=res_sethostent \
+# -Dendhostent=res_endhostent -Dgethostent=res_gethostent \
+# -Dsetnetent=res_setnetent -Dendnetent=res_endnetent \
+# -Dgetnetent=res_getnetent
+# for details on shared library building, see shres/solaris/INSTALL
+#uncomment next line to build a shared library version of libresolv
+#SHRES = shres/solaris
+#uncomment next line to build tools and named with shared libresolv
+#if you do so, you *must* define SOLCOMPAT as well (and it must be in CPPFLAGS)
+#RES = $(SHRES)/libresolv.so
+# uncomment only one of the triplets of lines below
+# -- if you use gcc (recommended)
+# (if -fpic doesn't work, see shres/solaris/ISSUES)
+#SHCC = gcc -DSVR4 -D_SYS_STREAM_H
+#PIC= -fpic
+#SHLD = /usr/ccs/bin/ld -G
+# -- if you use Sun's cc
+#SHCC = /opt/SUNWspro/bin/cc -DSVR4 -D_SYS_STREAM_H
+#PIC = -Kpic
+#SHLD = /opt/SUNWspro/bin/cc -G
+
+#(hpux7.0,hpux8.0,hpux9.0,)
+#CC = cc $(CPPFLAGS)
+#CDEBUG = -g
+#CPPFLAGS =
+#LEX = lex
+#LIBS = -ll -lBSD
+#PIDDIR = /etc
+#DESTSBIN = /etc
+#DESTEXEC = /etc
+#DESTMAN = /usr/man
+#DESTHELP = /usr/lib
+#INSTALL = bsdinstall.sh
+#RANLIB = :
+#MANROFF = cat
+#PS = ps -p
+#(bsdinstall.sh is in conf/)
+
+#(apollo domainos)
+#CC = cc $(CPPFLAGS)
+#CDEBUG = -g
+#CPPFLAGS = -U_APOLLO_SOURCE -D_BSD_SOURCE -DSPRINTF_CHAR -D_CLASSIC_BSD_SPRINTF
+#LIBS = -ll
+#DESTSBIN = /etc
+#DESTEXEC = /etc
+#DESTHELP = /usr/lib
+#DESTMAN = /usr/man
+#PIDDIR = /etc
+#LEX = lex
+#PS = /bsd4.3/bin/ps
+#IOT = IOT
+
+#(AIX3)
+#CC = bsdcc $(CPPFLAGS)
+#CDEBUG = -g
+#CPPFLAGS = -DBSD=43
+#LIBS = -ll
+#DESTEXEC = /usr/sbin
+#INSTALL = /usr/ucb/install
+#CATEXT = $$$$N
+#LEX = lex
+#PS = ps -p
+#IOT = IOT
+
+# (ConvexOS-10.x)
+#CC = gcc $(CPPFLAGS) -g -O2 -fpcc-struct-return -fno-builtin -funsigned-char
+#CDEBUG = -g
+#CPPFLAGS =
+#INDOT =
+#LEX = flex -8 -I
+#LIBS = -lfl
+#PIDDIR = /usr/local/etc
+#DESTBIN = /usr/local/bin
+#DESTSBIN = /usr/local/bin
+#DESTEXEC = /usr/local/etc
+#DESTMAN = /usr/local/man
+#DESTHELP = /usr/local/etc
+#DESTLIB = /usr/local/lib
+#DESTINC = /usr/local/include
+#COMPINCL = compat/include
+#LDS =
+#INSTALL_COMPAT = install
+#INSTALL = install
+#RANLIB = ranlib
+#IOT = IOT
+
+#(NEC EWS4800 EWS-UX/V Rel4.0/Rel4.2,UX/4800)
+#be careful with installation - note in particular that the system ships
+#with /usr/sbin/in.named (with in.) and /usr/sbin/named-xfer (without in.)
+#to emulate this naming, INDOT should be set to in. and XFER_INDOT should be
+#set to empty. also, under EWS4800, use 'make install' at your own risk.
+#CC = /usr/necccs/bin/cc $(CPPFLAGS)
+#CC = /usr/abiccs/bin/cc $(CPPFLAGS)
+#CDEBUG = -g
+#CPPFLAGS = -DSVR4 -DUSE_POSIX
+#INDOT = in.
+#XFER_INDOT =
+#LEX = lex
+#LIBS = -ll -lnsl -lsocket
+#DESTBIN = /usr/local/bin
+#DESTSBIN = /etc
+#DESTEXEC = /etc
+#DESTHELP = /usr/local/lib
+#DESTLIB = /usr/local/lib
+#DESTINC = /usr/local/include
+#DESTMAN = /usr/local/man
+#PIDDIR = /etc
+#LDS = :
+#RANLIB = :
+#COMPINCL = compat/include
+#CATEXT = $$$$N
+#INSTALL_COMPAT = install-compat
+#INSTALL = /usr/ucb/install
+#PS = ps -p
+#IOT = IOT
+
+# SCO Unix 3.4.2 / ODT 3.0 using gcc (the only choice for now)
+#CC = gcc $(CPPFLAGS)
+#CPPFLAGS = -DSYSV -DSYSV3
+#CDEBUG=-O6
+#LDFLAGS=-s
+#INDOT=
+#LEX=lex
+#LIBS=-ll -lnsl_s -lsocket -lc_s
+#DESTBIN=/usr/bin
+#DESTSBIN = /etc
+#DESTEXEC=/etc
+#DESTHELP=/usr/lib
+#DESTMAN=/usr/local/man
+#PIDDIR = /etc
+#LDS=:
+#RANLIB=:
+#COMPINCL=compat/include
+#CATEXT = $$$$N
+#INSTALL_COMPAT = install-compat
+#INSTALL = scoinst
+#MANROFF= (tbl | groff -man -Tascii)
+#PS = ps -p
+#IOT = IOT
+
+#(UNIXWARE)
+#CC = cc $(CPPFLAGS)
+#CPPFLAGS = -DSVR4 -DBSD_COMP -DUSE_POSIX -D_SYS_STREAM_H
+#CDEBUG = -O
+#LEX = lex
+#INDOT = in.
+#XFER_INDOT =
+#INSTALL = /usr/ucb/install
+# (1.X)
+#LIBS = -ll -lsocket -lnsl
+# (2.X)
+#LIBS = -ll -lsocket -lnsl -lgen
+#DESTSBIN = /usr/sbin
+#DESTEXEC = /usr/sbin
+#ARPREF = `lorder
+#ARSUFF = | tsort`
+#CATEXT = $$$$N
+#PS = ps -p
+#PIDDIR = /etc/inet
+#INSTALL_COMPAT = install-compat
+#RANLIB = :
+#LDS = :
+#DESTHELP=/usr/lib
+#IOT = IOT
+
+#(NeXTstep 2.0ff, single architecture make)
+#CC = cc $(CPPFLAGS) #you can use -O2 for 3.2ff
+#CPPFLAGS = -Dpid_t=int
+#CDEBUG = -g
+#LIBS = -ll
+#LEX = lex
+#DESTEXEC = /usr/etc
+#DESTHELP = /usr/lib
+#DESTMAN = /usr/man
+#DESTSBIN = /usr/etc
+#PIDDIR = /etc
+#MANDIR = man
+#CATEXT = $$$$N
+#MANROFF = cat
+#INSTALL_COMPAT = install-compat
+#IOT = IOT
+
+#(NeXTstep 3.3 Multi Architecture Binaries)
+#CC = cc $(CPPFLAGS) -arch i386 -arch m68k -arch hppa -arch sparc
+#CDEBUG = -O2
+#CPPFLAGS = -Dpid_t=int
+#LDS = :
+#AR = libtool -o
+#RANLIB = :
+#LIBS = -ll
+#LEX = lex
+#DESTEXEC = /usr/etc
+#DESTHELP = /usr/lib
+#DESTMAN = /usr/man
+#DESTSBIN = /usr/etc
+#PIDDIR = /etc
+#MANDIR = man
+#CATEXT = $$$$N
+#MANROFF = cat
+#INSTALL_COMPAT = install-compat
+#IOT = IOT
+
+#(Pyramid dcosx)
+#CC = cc $(CPPFLAGS)
+#CDEBUG = -g
+#CPPFLAGS = -DSVR4 -DPOSIX_SIGNALS
+#LEX = lex
+#LIBS = -ll -lnsl -lsocket
+#RANLIB = :
+#PS = ps -p
+#IOT = IOT
+
+#(Sequent Dynix/PTX)
+#CC = cc $(CPPFLAGS) -Wc,-pw
+#CDEBUG = -g
+#CPPFLAGS = -Du_int=\"unsigned int\" -DSYSV
+#RANLIB = :
+#LIBS = -ll -lsocket -linet -lnsl -lseq
+#PIDDIR = /etc
+#DESTSBIN = /usr/local/etc
+#DESTEXEC = /usr/local/etc
+#DESTHELP = /usr/local/lib
+#LEX = lex
+#PS = ps -p
+#IOT = IOT
+
+#(dgux)
+#LEX = lex
+#RANLIB =
+#CC = gcc $(CPPFLAGS)
+#CDEBUG = -g
+#CPPFLAGS = -D__STDC__ -DDGUX
+#LIBS = -ll
+#DESTBIN = /usr/bin
+#DESTSBIN = /usr/bin
+#DESTEXEC = /usr/bin
+#DESTMAN = /usr/local/man
+#DESTHELP = /usr/lib
+#DESTLIB = /usr/lib
+#DESTINC = /usr/include
+#PIDDIR = /etc
+#PS = ps -p
+#IOT = IOT
+
+#(epix) Has to be compiled and loaded with -systype bsd43
+# Epix 2.x.x requires /bsd43/bin in front of the PATH variable
+#CC = cc $(CPPFLAGS) -signed -systype bsd43
+#CDEBUG = -g
+#CPPFLAGS = -DSTDIN_FILENO=0
+#LEX = lex
+#LIBS = -ll
+#DESTSBIN = /etc/local
+#DESTEXEC = /etc/local
+#DESTMAN = /usr/local/man
+#DESTHELP = /usr/lib
+#INSTALL = install.sh
+#RANLIB = :
+#PS = ps -p
+#IOT = IOT
+
+#Mips RISC/os 4.52
+#CC = cc $(CPPFLAGS) -systype bsd43
+#CPPFLAGS = -Dpid_t=int
+#CDEBUG = -O -g3 -Olimit 1000
+#LEX = lex
+#LIBS = -ll
+#PIDDIR = /etc
+#DESTBIN = /usr/local/bin
+#DESTSBIN = /usr/etc
+#DESTEXEC = /usr/etc
+#DESTMAN = /usr/local/man
+#DESTHELP = /usr/local/lib
+#DESTLIB = /usr/local/lib
+#DESTINC = /usr/local/include
+#PS = ps -p
+#IOT = IOT
+
+#Esix SVR4.0.4 with gcc
+# also works for Dell 2.2 and other i386 SVR4.0. Probably Unixware 1.1 as well.
+#Be careful with installation - note in particular that the system ships
+#with /usr/sbin/in.named (with in.) and /usr/sbin/named-xfer (without in.)
+#to emulate this naming, INDOT should be set to in. and XFER_INDOT should be
+#set to empty. also, use 'make install' at your own risk.
+#don't include sys/stream.h via netinet/in.h by defining _SYS_STREAM_H.
+#CC = gcc $(CPPFLAGS)
+#CPPFLAGS = -DSVR4 -DBSD_COMP -DUSE_POSIX -D_SYS_STREAM_H
+#CDEBUG = -O
+#LEX = lex
+#INDOT = in.
+#XFER_INDOT =
+#PIDDIR = /etc
+#INSTALL = /usr/ucb/install
+#LIBS = -ll -lsocket -lnsl
+#DESTSBIN = /usr/sbin
+#DESTEXEC = /usr/sbin
+#LDS = @:
+#RANLIB = @:
+#ARPREF = `lorder
+#ARSUFF = | tsort`
+#CATEXT = $$$$N
+#PS = ps -p
+#IOT = IOT
+
+#(ISC4.0 using GCC)
+#CC = gcc -DISC -posix
+#CPPFLAGS =
+#CDEBUG = -g
+#LEX = flex -I
+#LIBS = -lbsd
+#PIDDIR = /etc
+#DESTBIN = /usr/bin
+#DESTSBIN = /etc
+#DESTEXEC = /etc
+#DESTHELP = /etc
+#DESTMAN = /usr/catman/l_man
+#CATEXT = $$$$N
+#RANLIB = @:
+#LDS = @:
+#PS = ps -p
+#ARPREF = `lorder
+#ARSUFF = | tsort`
+#IOT = IOT
+
+# AUX 3.x (I used 3.1.1)
+#CC = gcc $(CPPFLAGS)
+#CDEBUG = -O2
+#CPPFLAGS = -D_POSIX_SOURCE -DSYSV
+#LEX = lex
+#LIBS = -ll -lposix -lmalloc -s
+#PIDDIR = /etc
+#DESTBIN = /etc
+#DESTSBIN = /etc
+#DESTEXEC = /etc
+#DESTMAN = /usr/local/man
+#DESTHELP = /etc
+#COMPINCL = compat/include
+#CATEXT = $$$$N
+#INSTALL_COMPAT = install-compat
+#INSTALL = install
+#RANLIB = @:
+#PS = ps -p
+#IOT = IOT
+
+#NCR System V/MLS
+#use same definitions as for sunos4.x except for the following
+#be careful with installation - note in particular that the system ships
+#with /usr/sbin/in.named (with in.) and /usr/sbin/named-xfer (without in.)
+#to emulate this naming, INDOT should be set to 'in.' while XFER_INDOT
+#should be empty. also, under solaris2.x, use 'make install' at your own risk.
+#don't include sys/stream.h via netinet/in.h by defining _SYS_STREAM_H.
+#PIDDIR = /usr/local/lib
+#LEX = lex
+#CC = cc $(CPPFLAGS)
+#CDEBUG = -g
+#CPPFLAGS = -DSVR4 -D_SYS_STREAM_H -Hnocopyr -DPOSIX_SIGNALS -DNCR -w
+#INDOT = in.
+#XFER_INDOT =
+#LIBS = -ll -lnsl -lsocket
+#DESTEXEC = /usr/local/bin
+#LDS = :
+#RANLIB = :
+#ARPREF = `lorder
+#ARSUFF = | tsort`
+#CATEXT = $$$$N
+#PS = ps -p
+#IOT = IOT
+
+####################################################################
+############ no user servicable parts beyond this point ############
+####################################################################
+
+MANARGS = \
+ "SHELL=${SHELL}" "INDOT=${INDOT}" "XFER_INDOT=${XFER_INDOT}" \
+ "DESTDIR=${DESTDIR}" "DESTMAN=${DESTMAN}" "INSTALL=${INSTALL}" \
+ CATEXT='${CATEXT}' MANDIR='${MANDIR}' MANROFF='${MANROFF}'
+
+MARGS = "VER=${VER}" "CC=${CC}" "CDEBUG=${CDEBUG}" "LIBS=${LIBS}" \
+ "INCL=../${INCL}" "RES=../${RES}" "LEX=${LEX}" "LDFLAGS=${LDFLAGS}" \
+ "PIDDIR=${PIDDIR}" "DESTBIN=${DESTBIN}" "DESTSBIN=${DESTSBIN}" \
+ "DESTEXEC=${DESTEXEC}" "COMPINCL=../${COMPINCL}" \
+ "COMPLIB=../${COMPLIB}" "DESTLIB=${DESTLIB}" "DESTINC=${DESTINC}" \
+ "DESTHELP=${DESTHELP}" "PIC=${PIC}" "SHCC=${SHCC}" "SHLD=${SHLD}" \
+ "AR=${AR}" "RANLIB=${RANLIB}" "LDS=${LDS}" 'ARPREF=${ARPREF}' \
+ 'ARSUFF=${ARSUFF}' $(MANARGS) PS="${PS}" "IOT=${IOT}" \
+ "CPPFLAGS=${CPPFLAGS}"
+
+MACHINE = native
+DST = $(MACHINE).b
+SRC = ..
+
+SUBDIRS = res $(SHRES) include compat named tools man
+
+all:: FRC
+
+all clean depend:: FRC
+ @for x in $(SUBDIRS); do \
+ (cd $$x; pwd; $(MAKE) $(MARGS) $@); \
+ done
+
+$(SUBDIRS):: FRC
+ @for x in $@; do \
+ (cd $$x; pwd; $(MAKE) $(MARGS) all); \
+ done
+
+clean:: FRC
+ -test -d doc/bog && (cd doc/bog; pwd; $(MAKE) $(MARGS) $@)
+ (cd conf; rm -f *~ *.CKP *.BAK *.orig)
+ rm -f *~ *.CKP *.BAK *.orig
+
+depend:: FRC
+
+mkdirs: FRC
+ -set +e; for x in $(DESTBIN) $(DESTSBIN) $(DESTEXEC) \
+ $(DESTMAN) $(DESTHELP) $(DESTLIB) $(DESTINC); do \
+ test -d $$x || mkdir -p $$x; \
+ done
+
+install: FRC
+ @for x in $(SUBDIRS); do \
+ y=`if [ "X$$x" = "Xcompat" ]; \
+ then echo ${INSTALL_COMPAT}; \
+ else echo install; \
+ fi`; \
+ (cd $$x; pwd; $(MAKE) $(MARGS) $$y); \
+ done
+
+D = OPTIONS master bin doc named CHANGES README compat include res \
+ Makefile TODO conf man tools
+
+copyright: FRC
+ bin/copyright <conf/copyright `find ${D} -type f ! -name '*,v' -print`
+
+tar: FRC
+ ( cd doc/bog; make file.psf file.lst )
+ find * '(' -name RCS -o -name obj -o -name .depend ')' \
+ -print >/tmp/bindXf
+ gnutar -c -z -f ../bind-${VER}.tar.gz -X /tmp/bindXf .
+ rm -f /tmp/bindXf
+
+links: $(DST)
+
+$(DST): FRC
+ @set -ex; mkdir $(DST); cd $(DST); \
+ ln -s $(SRC) SRC; \
+ cp SRC/Makefile .; chmod +w Makefile; \
+ ( mkdir include; cd include; ln -s ../SRC/include SRC; \
+ cp SRC/Makefile .; chmod +w Makefile; \
+ ln -s SRC/*.h SRC/arpa .; \
+ ); \
+ ( mkdir conf; cd conf; ln -s ../SRC/conf SRC; \
+ ln -s SRC/*.h .; \
+ ); \
+ ( mkdir tools; cd tools; ln -s ../SRC/tools SRC; \
+ ln -s SRC/*.[ch] .; \
+ cp SRC/Makefile .; chmod +w Makefile; \
+ ( mkdir nslookup; cd nslookup; ln -s ../SRC/nslookup SRC; \
+ cp SRC/Makefile .; chmod +w Makefile; \
+ ln -s SRC/[a-z]* .; \
+ ); \
+ ); \
+ ( mkdir res; cd res; ln -s ../SRC/res SRC; \
+ cp SRC/Makefile .; chmod +w Makefile; \
+ ln -s SRC/*.[ch] .; \
+ ); \
+ ( mkdir compat; cd compat; ln -s ../SRC/compat SRC; \
+ cp SRC/Makefile .; chmod +w Makefile; \
+ ln -s SRC/include .; \
+ ( mkdir lib; cd lib; ln -s ../SRC/lib SRC; \
+ cp SRC/Makefile .; chmod +w Makefile; \
+ ln -s SRC/*.c .; \
+ ); \
+ ); \
+ ( mkdir named; cd named; ln -s ../SRC/named SRC; \
+ cp SRC/Makefile .; chmod +w Makefile; \
+ ln -s SRC/*.[ch] SRC/*.sh .; \
+ ); \
+ ( mkdir shres; cd shres; ln -s ../SRC/shres SRC; \
+ ( mkdir sunos; cd sunos; ln -s ../../SRC/shres/sunos SRC; \
+ cp SRC/Makefile .; chmod +w Makefile; \
+ ln -s SRC/makeshlib SRC/*.patch* .; \
+ ); \
+ ( mkdir netbsd; cd netbsd; ln -s ../../SRC/shres/netbsd SRC; \
+ cp SRC/Makefile .; chmod +w Makefile; \
+ ln -s SRC/makeshlib SRC/lorder-sparc.sed SRC/shlibname.awk .; \
+ ); \
+ ( mkdir solaris; cd solaris; ln -s ../../SRC/shres/solaris SRC; \
+ cp SRC/Makefile .; chmod +w Makefile; \
+ ); \
+ ); \
+ ( mkdir man; cd man; ln -s ../SRC/man SRC; \
+ cp SRC/Makefile .; chmod +w Makefile; \
+ ln -s SRC/*.[0-9] .; \
+ )
+
+gcc2-lint: FRC
+ @-make CC="gcc2 -Wall -Wno-comment -Wno-parentheses -Dlint" all \
+ 2>&1 | grep '\.[ch]:[0-9]'
+
+FRC:
diff --git a/contrib/bind/OPTIONS b/contrib/bind/OPTIONS
new file mode 100644
index 0000000..8255244
--- /dev/null
+++ b/contrib/bind/OPTIONS
@@ -0,0 +1,412 @@
+OPTIONS
+ Original: Paul Vixie, 28Mar92
+ Revised: $Id: OPTIONS,v 8.6 1996/05/21 07:32:31 vixie Exp $
+
+Options available in this version of BIND are controlled by conf/options.h,
+rather than by $(DEFS) in the Makefile. The options are:
+
+DEBUG (origin: U C Berkeley)
+ enables the -d command line option, and allows SIGUSR1 to increment
+and SIGUSR2 to clear the internal variable "debug", which in turn controls
+hundreds of fprintf()'s out to /usr/tmp/named.run.
+ you probably want this. it makes the binary bigger but not slower (or
+at least not much slower), but SIGUSR[12] are the only way you'll track down
+misconfigured name servers that hose you down with billions of bogus requests.
+ you may need this, it is on by default.
+
+ALLOW_T_UNSPEC (origin: MIT Project Athena)
+ enables the "unspec" RR type for ancient Athena software that does not
+know about TXT RR's.
+ you probably do not care about this, it is off by default.
+
+ALLOW_UPDATES (origin: Mike Schwartz, University of Washington)
+ enables "dynamic updates", described in "doc/DynamicUpdate". this lets
+you update named's in-memory database on the fly if you have the right client.
+there is absolutely no security around this; if you enable it, anyone who can
+reach your server can update your database.
+ this code doesn't compile any more and will be removed shortly.
+
+INVQ (origin: U C Berkeley, with #ifdef's by Paul Vixie)
+ enables "inverse queries", which in all of the internet only one
+client ever uses: ancient nslookup. if you build named with INVQ defined,
+you get the time-honored behaviour of supporting this whole class of queries
+for no real purpose other than to waste a few hundred kilobytes of your
+memory and about 3% of named's total CPU time. if you build with INVQ
+undefined, old nslookups will not be able to reach your server in their
+startup phase, and you will have to use the "server" command after it fails
+over to some other server, or use "nslookup - 0" to get in from the shell.
+ if you need to support old nslookups try "options fake-iquery"
+instead of enabling this option.
+ you probably do not want this.
+
+DSTORAGE (origin: U C Berkeley, with #ifdef's by Paul Vixie)
+ enables a malloc-debugger that checks for overruns on both ends of
+each allocated block of memory. used when debugging since C has no bounds
+or type checking.
+ you probably do not want this, it is off by default.
+
+DMALLOC (origin: Paul Vixie of Digital)
+ enables a malloc-debugger that traces all allocated blocks of memory
+such that SIGIOT's output (see STATS option) includes a list of all mallocs
+in the program, how many times each has been called, how many blocks of memory
+allocated by that malloc are not yet free, and how many bytes they use up.
+under each one will be a list of each free/realloc that has deallocated a block
+of that malloc's memory, and how many times it has done so.
+ this is extremely helpful for finding memory leaks. as such, you
+probably do not want this unless you are debugging named.
+ you probably do not need this, it is off by default.
+
+XFRNETS (origin: Paul Vixie of Digital)
+ enables the "xfrnets" command in named.boot. this has the same
+syntax as "forwarders" and "sortlist" -- that is, a list of dotted quads.
+each one is a network (16.0.0.0 and 130.180.0.0 are examples) or a host.
+if you put any xfrnets commands into your named.boot, then zone transfers
+will only be honored if they come from inside one of the specified
+networks. this is very useful if you want to keep people outside from
+being able to trivially map your entire network, but it doesn't stop them
+from iterating so it's more annoying than secure.
+ this feature was once called "tcplist" out of ignorance on my part,
+but with advice from phil almquist i decided to rename it "xfrnets" and make
+it only control zone transfers -- previously it controlled all TCP connections
+which made certain TCP-only resolvers unable to use our servers. the "tcplist"
+syntax still works; it is a synonym for "xfrnets".
+ it is also nice if you want to keep the outside world from making your
+nameserver fork and swap trying to do unauthorized zone transfers. if you have
+large zone files or use BIND for TXT records you will find this useful.
+ you probably want this, it is on by default.
+
+PID_FIX (origin: Don Lewis of Harris)
+ tells named that if it starts up but can't keep going because another
+nameserver is already running (and sitting on the server port), it should
+put the /etc/named.pid (/var/run/named.pid) file back the way it found it.
+ you probably want this, it is on by default.
+
+FWD_LOOP (origin: Don Lewis of Harris)
+ tells named that if you list any of your own IP addresses in a
+"forwarders" command in your named.boot file, you should be scolded.
+ you probably want this, it is on by default.
+
+NO_GLUE (origin: Don Lewis of Harris, and Andrew Partan of UUNET)
+ tells named-xfer that incoming zone transfers should be checked
+for "glue" that comes from a zone outside the zone being transfered, and
+comment this garbage out in the zone file so that when named reads in the
+zone file after named-xfer exits, the garbage will not be entered into the
+memory-resident database.
+ also tells named that when it is performing an outgoing zone
+transfer, it should not send any of these "glue" records.
+ you definitely want this, it is on by default.
+
+BOGUSNS (origin: Piet Beertema of EUNet)
+ enables the "bogusns" command in named.boot. this has the same
+syntax as forwarders and sortlist. any NS RR's that come in whose addresses
+are on the list of "bogusns" addresses will be ignored. this is the last
+resort when someone is bogusly advertising themselves as a root server.
+ just in case, though you won't use it often.
+ you probably want this, it is on by default.
+
+QRYLOG (origin: Bryan Beecher of UMich)
+ enables "query logging", such that SIGWINCH toggles tracing of all
+incoming queries. the trace is sent to syslog, and is huge, but when you
+need this you will need it bad and it does not slow named down or make it
+larger.
+ If you define QRYLOG you may also start up named in query logging
+mode by using the -q flag. If you do so you will probably want to analyze
+the logs produced, the dnsstats and lamers scrips (in the contrib/umich
+and contrib/lamers directories) will do it for you.
+ you probably want this, it is on by default.
+
+LOGFAC (origin: various people)
+ If you start up named with the -q flag you will be logging
+large amounts of data, and probably will not want them logged to the
+default logging facility, which is LOG_DAEMON. You will want to
+redefine LOGFAC, presumably to LOC_LOCALn (0 <= n <= 7). Remember to
+modify /etc/syslog.conf appropriately.
+ This only works on a system with a modern syslogd.
+ as such, it is on by default.
+
+YPKLUDGE (origin: Piet Beertema of EUNet)
+ certain versions of NIS/YP are capable of using the DNS for names
+that cannot be found in the YP servers. of these, certain versions can't
+tell the difference between a dotted quad and a domain name, and they send
+queries to the DNS for dotted quads as if they were domain names. if your
+named does not do anything special with these queries, they will end up
+getting forwarded to other servers, effectively hosing all of you down with
+endless useless network traffic. YPKLUDGE enables some checking in named
+that lets it catch these bogus queries and send back immediate errors.
+ If you run "ypserv -i" you definitely want this, as a malconfigured
+NIS server can cause DNS "flood" queries otherwise. Trust me.
+ this is off by default.
+
+TRACEROOT (origin: pma@cnd.hp.com and Bryan Beecher of UMich)
+ enables some checking in named for bogus root nameservers. This
+code has been in use at U-M for years, so it is pretty well tested, plus we
+have never been burned by the "bogus root NS scares" that have plagued the
+DNS off and on.
+ this feature people will very much want to use, it is on by default.
+
+LOCALDOM (origin: Berkeley)
+ if set, the "domain" directive is recognized in the named.boot file.
+this causes us to retry queries with the specified domain appended to the
+name if the first lookup fails. this is a very bad idea since a given name
+server will often be used by clients in more than one domain -- a name server
+should _not_ make any presumptions as to the "home domain" of a requestor.
+ you almost certainly do not want this, it is off by default.
+
+SLAVE_FORWARD (origin: pma@sdd.hp.com)
+ if set, "slave" servers behave in an arguably more-correct way. this
+is an experimental addition to BIND 4.9 that causes slaves to time out queries
+in 60/N seconds where N is the number of forwarders defined. previously a
+query would time out almost immediately, which caused a lot of unnecessary
+network traffic.
+ you probably want this, it is on by default.
+
+FORCED_RELOAD (origin: pma@sdd.hp.com)
+ if set, then when a HUP signal is received, all secondary zones are
+scheduled for serial-number comparison with the primaries. this has the effect
+that if you HUP your server, it will refresh any zones which have changed,
+even if those zones' refresh times have not been reached.
+ you probably want this, it is on by default.
+
+WANT_PIDFILE (origin: berkeley, parameterized by arc@sgi)
+ if set, a file called named.pid will be created in /etc or /var/run
+when the name server has started. this file can be used to send signals to
+BIND, as in "kill -HUP `cat /etc/named.pid`".
+ unless you are only on an SGI (where killall(1M) makes the pid file
+unnecessary);
+ you probably want this, it is on by default.
+
+DOTTED_SERIAL (origin: berkeley; parameterized by vixie)
+ if set, allows a somewhat arcane n.m syntax in the serial number
+field of an SOA. this is officially deprecated for 4.9; you should use
+straight integer values and find an encoding that does not depend on
+scaled-integer pseudodecimals. i suggest YYYYMMDDnn where YYYY is the
+four-digit year, MM is the two-digit month, DD is the two-digit day-of-month,
+and nn is a daily version number in case you change your serial number more
+than once in a day. this encoding will overflow in the year 4294 gregorian.
+ you almost certainly do not want this, but if you have old zone files
+lying around and you don't want to think your way through converting their
+serial numbers, this deprecated behaviour is available.
+ graciously, it is on by default.
+
+SENSIBLE_DOTS (origin: kagotani@cs.titech.ac.jp; parameterized by vixie)
+ if set, changes the semantics of an "n.m" serial number from
+ n*10^(3+int(0.9+log10(m))) + m
+to
+ n*10000+m
+ if you are using DOTTED_SERIAL in spite of its deprecated status,
+and you are interested in a more predictable and sensible interpretation of
+dotted numbers, then you probably want this.
+ it is off by default.
+
+VALIDATE (origin: USC/ISI)
+ enables a validation procedure to provide some security in an
+otherwise insecure environment. Any RRs are accepted from a server only if
+the server is authoritative over that domain. We consider a server
+authoritative (for validation purposes) for even the sub-domains that it has
+delegated to others. RRs are validated against the data we have in cache
+already. Invalid records are neither cached nor returned.
+ it is off by default because it is hopeless, and the code will all
+be ripped out of BIND in the near future.
+
+NCACHE (origin: USC/ISI)
+ enables negative caching. We cache only authoritative NXDOMAIN or
+authoritative NOERROR with zero RR count. Non-authoritative NXDOMAIN answers
+now contain NS records in the authority section. Non-authoritative NOERROR
+responses have no authority or additional records to differentiate them from
+referrals. They are cached for NTTL secs (currently 10 minutes) and are timed
+out when the ttl expires.
+ you probably want this, it is on by default.
+
+RESOLVSORT (origin: marka@syd.dms.csiro.au)
+ enable sorting of addresses returned by gethostbyname. Sorting order
+is specified by address/netmask pairs. This enables a host to override the
+sortlist specified in the nameserver.
+ you probably want this, it is on by default.
+
+STUBS (origin: marka@syd.dms.csiro.au)
+ enable transfer and loading of NS records only for a zone.
+still experimental. it won't hurt to enable it, but it may not work perfectly
+so using it could lead to some confusion.
+ you probably don't care, it is on by default.
+
+SUNSECURITY (origin: rossc@ucc.su.oz.au)
+ enable checking of PTR records in gethostbyaddr() to detect
+spoofing. Forced on SunOS 4 shared library as rlogin etc. depend on this.
+ you should probably not set this by hand.
+
+SECURE_ZONES (origin: gshapiro@guest.wpi.edu)
+ enables support for secure zones. This restricts access to
+information in the zone according to the information found in the
+secure_zone TXT RR found in the zone. If none is found, the zone is
+world-readable. For information on the format of the secure_zone TXT
+RR, see the Name Server Operations Guide for BIND.
+ you probably want this, it is on by default.
+
+ROUND_ROBIN (origin: Marshall Rose of TPC.INT)
+ if set, causes the databuf list in a namebuf to be rotated by one
+slot after each access to it. this has the effect that if multiple RR's
+of a given type are present, they will be given in "round robin" order
+instead of always being given in the same order.
+ you probably want this, it is on by default.
+
+ADDAUTH (origin: marka@syd.dms.csiro.au)
+ if set, cause NS and glue A records to be returned with authoritative
+answers. this causes slightly larger replies but less DNS traffic overall.
+ unless you have Mac's with an older version of Mac/TCP;
+ you probably want this, it is on by default.
+
+RFC1535 (origin: paul@vix.com)
+ if set, the resolver's default "search" list will be just the entire
+"domain" name rather than the sliding window it had before 4.9.2. this will
+make the default search list shorter, so folks who are saying "domain a.b.c"
+and relying on the implicit "search a.b.c a.b c" will miss "a.b" and "c".
+ this option is on for compatibility with RFC 1535.
+ you should NOT turn it off, it is on by default.
+
+GEN_AXFR (origin: mark@comp.vuw.ac.nz, tytso@ATHENA.MIT.EDU, gdmr@dcs.ed.ac.uk)
+ if set, allows specification of zones in classes other than "IN" in
+the named.boot file. Allows an optional "/class" on the "primary" and
+"secondary" directives. Also fixes zone transfers so only data in the class
+requested is transfered.
+ you probably want this, it is on by default.
+
+DATUMREFCNT (origin: mark andrews)
+ you want this. it will not be optional in future releases.
+
+LAME_DELEGATION (origin: don lewis; reworked by bryan beecher and don lewis)
+ this will detect the condition where some other server has told you
+that a given set of servers is authoritative for some domain, and at least
+one of those "delegated" servers disagrees (i.e., answers non-authoritatively).
+ you probably want this, it is on by default.
+
+LAME_LOGGING (origin: don lewis)
+ enable logging of lame delegations and set the log level
+ you may want this, it is on by default.
+
+RETURNSOA (origin: mark andrews)
+ This allows negative caching to work. Without this, older
+pre-4.9.3 nameservers will not accept -ve cached anwsers. We actually
+store the SOA record from the authority section rather that what was
+requested because it is the existence of the NXDOMAIN that matters not
+the type of data. The zone of the SOA record is tagged to the end of
+the SOA record to allow it to be reconstructed.
+ You probably DO NOT WANT THIS, it's experimental and dangerous.
+ it is off by default.
+
+CLEANCACHE (origin: mark andrews)
+ Bind consumes memory without bound without this option. This
+patch allows bind to periodically remove any stale entries in the
+cache. Bind's memory usage should stabilize after approximately 1 day of
+operation, as most TTL's are <= 1 day. Without this option stale entries
+are only removed when they are looked up.
+ You probably want this, it is on by default.
+
+PURGE_ZONE (origin: mark andrews)
+ Various junk below a zone tends to hang around and corrupt future
+zone data if a zone grows deeper. PURGE_ZONE will remove all traces of or
+data which could be part of zone before loading a new one.
+ You probably want this, it is on by default.
+
+STATS (origin: Paul Vixie)
+ Named's internal statistics can take a fair amount of memory and
+if you aren't interested in looking at these numbers you should disable
+the feature. Future versions may require this.
+ You probably want this, it is on by default.
+
+RENICE (origin: bp@deins.informatik.uni-dortmund.de)
+ if set, the process priority of the AXFR subprocesses is changed to
+"normal". If you are planning to raise the priority of the main nameserver
+process, you will use this.
+ You probably want this, it is on by default.
+
+GETSER_LOGGING (origin: Paul Vixie)
+ if set, errors that occur during the fetch of serial numbers for zone
+transfer consideration will be syslog()'d. this can lead to a lot of logging,
+but is very helpful if you don't know why a zone isn't transfering.
+ You may not want this, but it is on by default.
+
+SHORT_FNAMES (origin: pma@sdd.hp.com)
+ on systems whose file names can only be 14 characters long, the temp
+files created by named-xfer need to be constructed somewhat differently. this
+should probably become the default since it is harmless.
+ you probably don't care one way or the other, it is off by default.
+
+XSTATS (origin: Benoit.Grange@inria.fr)
+ if set, the name server keeps more STATS about requests
+received, and logs to syslog total counters from time to time. If you
+aren't interested in looking at these numbers you should not enable
+the feature. Requires STATS.
+ You may want this, but it is off by default.
+
+BIND_NOTIFY (origin: paul@vix.com)
+ experimental at this time; an internet draft is circulating. this
+option informs slaves ("secondary" servers in BIND's erroneous terminology)
+instantly when the master (primary, or another slave) loads a new zone. it
+works fine and seems to cause no problems with slaves that don't support it,
+but it does not implement the current internet draft (it lacks some necessary
+delays) and causes a lot of extra syslog traffic, especially at startup. if
+you don't mind running code that will absolutely NOT be compatible with the
+eventual standard when the RFC is released, go ahead and turn this on.
+ vendors should not enable this in versions shipped to customers.
+ You will want this when it becomes compliant, it is off by default.
+
+LOC_RR (origin: ckd@kei.com)
+ incorporates support for the (RFC 1876) LOC RR type.
+ You may want this, it is on by default.
+
+SORT_RESPONSE (legacy)
+ should responses be sorted in what the server considers an optimal
+order for the client? this is on by default but it does very little good.
+
+## ++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--
diff --git a/contrib/bind/README b/contrib/bind/README
new file mode 100644
index 0000000..cc3d980
--- /dev/null
+++ b/contrib/bind/README
@@ -0,0 +1,483 @@
+The official way to get BIND is: ftp ftp.vix.com
+ cd pub/bind/release
+ binary
+ get bind.tar.gz
+
+The official mailing lists are: bind-users@vix.com - users/admins
+ (use *-request@* for admin mail) bind-workers@vix.com - developers
+
+The official Usenet newsgroups are: comp.protocols.tcp-ip.domains
+
+BIND is currently sponsored by: The Internet Software Consortium
+ (send to <info@isc.org> for details.)
+
+----- 4.9.3 BETA33 - December, 1995 - paul@vix.com
+
+Take a look around in doc/misc/ and contrib/. Reread INSTALL. Have fun.
+
+----- 4.9.3 BETA11, BETA12 release - December, 1994 - paul@vix.com
+
+If you maintain a BSD or are otherwise running a 4.4BSD-based system and want
+to integrate BIND into it, check out BSD/README.
+
+Read the top of CHANGES for interesting stuff.
+
+Don't forget to purge all your secondary zone files before upgrading to this
+BIND if your existing one came from a vendor.
+
+The NOTIFY feature is turned off by default, but it's really cool and you
+should consider turning it on if you are willing to risk having it not work
+after the RFC process is complete (if the protocol has to change at all.)
+It already does not conform to the draft protocol so you should consider it
+"experimental" even if it happens to work fine.
+
+----- 4.9.3 BETA10 release - August, 1994 - paul@vix.com
+
+I recommend reading this ENTIRE FILE before you attempt to build or use BIND.
+However, you can get started quickly by scanning down this file for "QUICK" in
+the right margin and just reading those sections. You can also look at the
+INSTALL file. You should look at doc/info/* if you have trouble building.
+
+There are at least two known bugs in this BIND:
+
+1. if you have two authoritative zones (primary or secondary) where
+ one is a subzone of the other, e.g.,
+ primary pa.dec.com z/pa.dec.com
+ primary dec.com z/dec.com
+ and you remove or comment out the subzone (pa.dec.com in our example)
+ and SIGHUP named, the delegation and other RR's at "pa.dec.com" will
+ be missing from your cache. to avoid this, you should "named.restart"
+ rather than SIGHUP ("named.reload") when making changes of this kind.
+
+2. the /HS qualifier doesn't work on "cache" directives. you will have
+ to put your hesiod root information into your main "root.cache" file.
+
+Also, you may find that your utilities will not link with this -lresolv
+unless you also install lib44bsd.a and link with -lresolv -l44bsd. This
+is because older systems do not include inet_aton() and other functions.
+
+----- 4.9.3 BETA6 release - June, 1994 - paul@vix.com
+
+Several private beta test releases have come and gone, and we've fixed a
+number of things. See CHANGES for details.
+
+There is a new Sun Shared Library update mechanism in place, and it works
+quite well. See shres/*.
+
+Versions of NSLOOKUP up through BIND 4.8.3's used IQUERY to ask the local
+server for information about the server's own name. I assume that this was
+done in a "what the heck, nothing uses these, how can we contrive a need?"
+sort of spirit. I removed this code as of BIND 4.9's NSLOOKUP and had it
+use the standard gethostbyaddr() mechanisms (which depend on normal queries
+of PTR data). Disabling INVQ and putting "options fake-iquery" in the boot
+file will cause IQUERY to be answered bogusly but in a way that old nslookup
+programs won't trip on. INVQ is disabled by default in conf/options.h.
+
+----- 4.9.3 BETA2 release - June, 1994 - paul@vix.com
+
+News flash! BIND development is now funded by the Internet Software Consortium.
+
+Look at CHANGES to see what's new. Check out doc/misc to see some interesting
+papers from Purdue (and Bell Labs, if we're lucky) on DNS security that
+motivated many of the security-related changes present in this release.
+
+Check out shres/Makefile for SunOS4 shared library support.
+
+INVQ now defaults to "undef". See OPTIONS and conf/options.h.
+
+ALLOW_UPDATES is no longer available, and will be removed next release.
+
+You should look hard at the SENSIBLE_DOTS option and convert your serial
+numbers either to "sensible" ones or ones without dots (YYYYMMDD## preferred).
+SENSIBLE_DOTS will be the default in the next release.
+
+NCACHE and VALIDATE are _working_ now.
+
+Read the BOG! It's been updated since the previous release.
+
+If you are a vendor and are including some or all of this code in your product,
+please drop me a line to let me know. I field a lot of questions about BIND
+and it is helpful for me to know which vendor releases contain which versions
+of BIND. It's also helpful for me to have contacts within the engineering
+groups of the various vendors, since when I find a heinous bug I can let you
+know.
+
+----- 4.9.2 FINAL (940221) release - February, 1994 - paul@vix.com
+
+If you look at the last entry in TODO, you'll see that there are a lot
+of things in the queue waiting to go in. However, I'm holding the line
+so that 4.9.2-FINAL can be the same as what goes out with 4.4BSD-Lite.
+I expect to open 4.9.3-ALPHA fairly soon, with patches comprising new
+work; 4.9.2-FINAL will have patches released for it only to correct bugs.
+
+The official way to get BIND 4.9.2 is: ftp gatekeeper.dec.com OUT OF DATE!!!
+ cd pub/misc/vixie OUT OF DATE!!!
+ binary OUT OF DATE!!!
+ get bind-940221.tar.gz OUT OF DATE!!!
+ or: get bind-940221.tar.Z OUT OF DATE!!!
+
+The official mailing lists are: bind-users@vix.com - users/admins
+ (use *-request for admin mail) bind-workers@vix.com - developers
+
+The official Usenet newsgroups are: comp.protocols.tcp-ip.domains
+
+My official e-mail address is: paul@vix.com
+
+----- 4.9.2 BETA5 (931205) release - December, 1993 - paul@vix.com
+
+no comments; see CHANGES file.
+
+----- 4.9.2 BETA4 (931104) release - November, 1993 - paul@vix.com
+
+All reported portability problems have been fixed. All core dumps have
+had changes made for them and we are ready to have them tested again. As
+usual, I am running this in production on my own zones and I am rather
+confident in it. Note, again, that this is a BETA release and you should
+not put it up for anon-ftp or otherwise republish it in any way.
+
+----- 4.9.2 ALPHA2 (930908) release - September, 1993 - paul@vix.com
+
+4.9.2 has fixes for most of the bugs that smb@bellcore's white paper talked
+about, and CERT is going to be knocking on vendor's doors to get it shipped
+with as many operating systems as possible.
+
+----- 4.9.2 ALPHA1 (930506) release - July, 1993 - Paul Vixie <paul@vix.com>
+
+I don't work for DEC any more, so note the new e-mail address. The old
+<bind-4.9@pa.dec.com> list has been moved to <bind-workers@vix.com>; if
+you intend to help hack BIND and you want to be advised of alpha-testing
+releases, send mail to <bind-workers-request@vix.com> and ask to be added
+to the list.
+
+Note that 4.9.1 was an interrim, nonpublished release intended to catch
+the porting changes needed for 4.4BSD. It never really existed separately.
+
+----- 4.9 release - April, 1993 - Paul Vixie <vixie@pa.dec.com>
+
+For information on what's new in 4.9, see OPTIONS and CHANGES. Also note
+that the man page for named(8) in man/named.8, and the entire Bind Operations
+Guide in doc/BOG/*, has been updated for 4.9. Both make excellent reading.
+
+Those of you who are thinking of adding features should first read TODO to
+see if someone else has already indicated an intention to work on the same
+thing. If your feature is significant you should ask <bind-workers@vix.com>
+before you hack, if for no other reason than to tell other maintainers to
+expect a patch soon.
+
+Note that the resolver has a number of routines that may already be present
+on your system. Efforts have been made to avoid generating code for them on
+systems where they aren't needed; don't worry about them if they're
+generated unneccessarily since the linker will sort things out.
+
+This software is protected under the U C Regents' copyright. Changes made
+by or released through Digital Equipment Corporation are subject to a
+subsidiary copyright. The entire copyright is as follows:
+
+++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--
+
+To build this: QUICK
+
+ (on SUNOS, use the BSD build environment or you will
+ get the wrong definition for O_NDELAY)
+
+ look at conf/options.h and edit to your tastes.
+ The OPTIONS file here in this directory will help you
+ figure out what to do.
+
+ You should also look at the Makefile to select the proper set
+ of definitions depending on whether you are using Ultrix,
+ SunOS, and other 4.[23] BSD-alikes or using BSD 4.4, BSD/386,
+ and other net2-alikes.
+
+ "make links" will build a shadow source tree full
+ of symbolic links. the default name of this tree
+ is "./native.b", but you can override it by setting
+ the DST variable on the "make" command line, as in:
+ make DST=vax.b SRC=..
+ if your DST is not a subdir of "here", you will need to
+ override the SRC variable's default (which is ".."),
+ as in:
+ make DST=/tmp/vax.b SRC=`pwd`
+ note that the DST directory must be nonexistent at
+ the time that you run "make links".
+
+ after "make links", you can cd to the new build
+ directory, check the settings in the Makefile, and
+ run "make depend". if you aren't using "make links"
+ (shame on you), just use "make depend" from "here".
+ "make depend" may fail on your system; if so, look in
+ the bin/ directory and find a mkdep that does in fact
+ work for you.
+
+ if you skip the "make depend" phase, or after you run it,
+ you can do "make all" (from the build directory if you
+ used "make links" or from "here" if you're just hacking
+ around). you will get the following new things out of it:
+ res/libresolv.a
+ compat/lib/lib44bsd.a (optional)
+ include/{netdb,resolv}.h
+ include/arpa/{inet,nameser}.h
+ compat/include/sys/{cdefs,bitypes}.h
+ tools/{nstest,nsquery,dig,host}
+ tools/nslookup/nslookup
+ named/named
+ named/named-xfer
+ if you have trouble with "make all", check conf/portability.h
+ for things that your system needs, or doesn't need, or whatever.
+ it is preferable to add #ifdef's to conf/portability.h than to
+ add them anywhere else.
+
+ from the build directory (or "here" if you didn't
+ use "make links"), you can try "make -n install"
+ which will tell you what will be installed. it might
+ actually be right; however, what you will probably have to
+ do is copy the above files into the places you want
+ run them from. the other files you will need are:
+ tools/nslookup/nslookup.help
+ named/named.restart
+ named/named.reload
+
+ resolver library notes: to install it, either put the .a
+ file into /usr/local/lib or /usr/lib (if you use -lresolv
+ on all the links of your networking software), or use "ar"
+ to put all res/*.o directly into your /lib/libc.a file.
+ either way you will want to copy the include files
+ (including those from compat/include/sys) over to
+ /usr/include (or /usr/local/include if you're willing to
+ use -I/usr/local/include on all your network-software
+ compiles). something like this:
+ cp res/libresolv.a /usr/lib; ranlib /usr/lib/libresolv.a
+ tar chf - include | (cd /usr/include; tar xvpf -)
+ cp compat/include/sys/*.h /usr/include/sys
+
+ installing the man pages is left as an exercise for the
+ reader. there are just too many different versions of
+ "man" floating around for me to be able to help you figure
+ out what to do for the one you happen to be using.
+
+ WARNING: If you were running a BIND 4.8.3 or earlier based
+ named you should remove all cache files prior to starting
+ named. It would generally be a good idea to remove all cache
+ files regardless when installing a new version. The creadability
+ code depends upon the cache files having been made with the
+ latest named-xfer for correct operation.
+
+(special compilation-related warning about SunOS systems:)
+
+ From: Tom Limoncelli
+ To: vixie (Paul A Vixie)
+ Date: Mon, 11 Jan 93 11:30:39 EST
+
+ Sun compiler v2.0.1 hates bind4.9 code.
+
+ Sun has 3 compilers:
+
+ /usr/ucb/cc -- the default for SunOS 4.1.[123],
+ dropped in Solaris 2.0.
+ /usr/lang/cc -- the "unbundled" cc v1.0
+ (pretty good, but expensive), only
+ generates code for SunOS 4.1.x.
+ /usr/lang/cc.2.0.1 -- the latest "unbundled" cc,
+ for when they stop shipping the
+ bundled version altogether. This
+ generates code for SunOS 4.1.x and Solaris 2.x.
+
+ Sun's 2.0.1 C compiler (the one with the floating licenses) for SunOS
+ 4.1.x outputs a HUGE number of warnings. They can be ignored.
+
+--------------------- (4.8.3 README -- mostly obsolete now)
+
+This directory contains all the info and sources
+for the Berkeley Internet Name Domain server.
+You should read and understand these directions before starting
+to install the libraries and nameserver. Some of these steps
+replace existing source and binary files; you should make backups
+of all existing files before you begin this installation.
+Two installation procedures are described. The first is for 4.3BSD
+and other similar systems that are already configured to use earlier
+versions of the nameserver, and which have the new version of <netdb.h>
+(containing a h_addr_list field in the hostent structure). The second
+procedure is for 4.2BSD and derived systems. This procedure requires
+more decisions to be made, and may have to be varied due to system
+or operation constraints.
+
+The subdirectories and their contents are:
+
+bin - shell scripts used by current Berkeley makefiles
+man - manual pages & documentation
+doc - copy of Bind Operations Guide, and other documents
+include - include files to go in /usr/include
+named - name server sources
+res - source for C library resolver routines (and other libc additions)
+ (may be used as separate library, resolv.a)
+conf/master - Sample data files
+tools - some test programs
+
+
+Here is how to install the name server on 4.3BSD:
+
+0) cp bin/mkdep.append /usr/ucb/mkdep
+ cp bin/manroff /usr/man/manroff
+1) cp include/arpa/nameser.h /usr/include/arpa
+2) cp include/*.h /usr/include
+3) cp man/*.1 /usr/man/manl
+ cp man/*.3 /usr/man/man3
+ cp man/*.5 /usr/man/man5
+ cp man/*.7 /usr/man/man7
+ cp man/*.8 /usr/man/man8
+4) NOTE: Don't install the Makefiles on 4.3 Tahoe Release
+ cp res/{res*.c,herror.c} /usr/src/lib/libc/net
+ cp res/Makefile.libc.net /usr/src/lib/libc/net/Makefile
+ cp res/strcasecmp.c /usr/src/lib/libc/gen
+ cp res/strpbrk.c /usr/src/lib/libc/compat-sys5
+ cp res/named/{*.c,Makefile} /usr/src/lib/libc/net/named
+5) add strcasecmp.[co] to the Makefile in /usr/src/lib/libc/gen
+6) add strpbrk.[co] to the Makefile in /usr/src/lib/libc/compat-sys5
+7) rebuild and install /lib/libc.a.
+8) edit named/pathnames.h to correpond with your system's configuration
+9) cd named; make depend; make all; make install
+10) cd tools/nslookup; make nslookup; make install
+11) create the master files (samples in conf/master/*)
+12) edit /etc/rc.local to include:
+
+if [ -f /etc/named ]; then
+ /etc/named; echo -n ' named' >/dev/console
+fi
+
+13) recompile network client and server programs that use gethostbyname, etc.
+
+
+Here is how to install the name server on 4.2BSD or similar systems.
+First, a few notes on the choices that must be made.
+
+Rather than building libresolv.a, you may wish to integrate the resolver
+routines into /lib/libc.a. This is recommended to make it easy to recompile
+network programs once named is running. This procedure may require hand-
+tayloring on some systems.
+
+You will have to choose a version of mkdep from the bin directory
+that will work on your system:
+If you've modified make(1) to use .depend files as described
+in the current sendmail distribution, use mkdep; otherwise,
+if you have the 4.3BSD cc -M option, use mkdep.append; on ultrix,
+use mkdep.ultrix (uses cc -Em); otherwise, use mkdep.old.compiler.
+The mkdep script is used by "make depend" to regenerate Makefile dependency
+lists.
+
+You will need to chose a version of netdb.h. First, check /usr/include/netdb.h
+on your system. If the hostent structure has a h_addr_list entry, you can
+probably use your existing netdb.h or the one in include/netdb.h.
+If the existing netdb.h in /usr/include does not have a h_addr_list field,
+you will have to decide whether to update to the 4.3BSD format of the hostent
+structure. This is the best approach, but cannot be used unless you plan
+to upgrade entirely: if you use the new structure in /usr/include/resolv.h,
+you must recompile everything that uses the hostent structure, including
+the rest of the C library and all networking programs, without using
+any pre-existing object files. If this isn't possible or desirable,
+and /usr/include/netdb.h doesn't have an h_addr_list line, use
+include/netdb.h.4.2 instead of netdb.h. The other version of netdb.h
+(include/netdb.h.4.2.compat) may be used instead of include/netdb.h.4.2.
+This version along with a change in res/named/gethostnamadr.c.compat
+provide for using the new format of the hostent structure while having
+binary compatibility with existing libraries.
+
+On systems with Sun RPC, you will have to merge include/netdb.h or
+include/netdb.h.4.2 with /usr/include/netdb.h; copy the rpc-related lines
+into the appropriate copy of netdb.h. Alternatively, use an alternate
+include path when compiling the resolver library and programs that use it.
+
+0) cp bin/{whatever} /usr/ucb/mkdep (see above)
+ cp bin/manroff /usr/man/manroff
+1) cp include/arpa/nameser.h /usr/include/arpa
+ Also, on ultrix 2.x, if you haven't fixed
+ the inet_addr definition in inet.h, do
+ cp include/arpa/inet.h /usr/include/arpa
+2) cp include/resolv.h /usr/include
+3) cp include/netdb.h /usr/include/netdb.h
+OR
+ cp include/netdb.h.4.2 /usr/include/netdb.h
+OR
+ edit /usr/include/netdb.h
+4) cp man/*.1 /usr/man/manl
+ cp man/*.3 /usr/man/man3
+ cp man/*.5 /usr/man/man5
+ cp man/*.7 /usr/man/man7
+ cp man/*.8 /usr/man/man8
+5) cd res; make depend;
+ make libresolv.a;
+ make install
+OR
+ update the libc sources as in the 4.3BSD instructions above
+ and use res/Makefile as a guide for integration
+ and omit the RES=-lresolv in the next two steps
+OR
+ compile the .o files in res according to Makefile,
+ then use place those object files in /lib/libc.a (keeping a backup!)
+ and omit the RES=-lresolv in the next two steps
+6) edit named/pathnames.h to correpond with your system's configuration
+7) cd named; make depend; make RES=-lresolv all; make install
+ (if your system defines signal-catching routines to return int
+ instead of void, use "make DEFINES=-DSIG_FN=int RES=-lresolv all")
+8) edit tools/nslookup/pathnames.h to correpond with your system's
+ configuration
+9) cd tools/nslookup; make RES=-lresolv nslookup install
+10) create the master files (samples in conf/master/*)
+11) edit /etc/rc.local to include:
+
+if [ -f /etc/named ]; then
+ /etc/named; echo -n ' named' >/dev/console
+fi
+
+12) eventually, recompile network client and server programs that use
+gethostbyname, etc.
diff --git a/contrib/bind/TODO b/contrib/bind/TODO
new file mode 100644
index 0000000..5f6a453
--- /dev/null
+++ b/contrib/bind/TODO
@@ -0,0 +1,187 @@
+$Id: TODO,v 8.3 1995/06/19 08:34:22 vixie Exp $
+
+Things to do. Each entry should contain the proposer, date proposed, and an
+explaination of what's being proposed. New ones are added at the bottom.
+Note that the author/coordinator of BIND does not neccessarily endorse all
+of the proposals listed herein; if you did not get explicit "buy-in" then
+your changes may not be accepted even if they appear in proposal form here
+in this file.
+
+[Mark.Andrews@dms.CSIRO.AU 14dec94]: rfc952/rfc1123 host name compliance:
+ -> Test domain names to ensure that the name conforms to the form
+ specified by RFC952 as modified by RFC1123.
+ -> WARN if the domain name does not meet the conditions set by
+ rfc952/rfc1123 for the following resource records.
+ class == C_IN && type == T_A
+ class == C_IN && type == T_MX
+ -> REJECT this records on the primary server.
+ -> CNAME which doesn't match pointing to the above is also
+ illegal but harder to check.
+
+[paul@vix.com 30nov94]: cause NOTIFY to track the IETF process for it;
+ reorder ns_resp() again so that "Notify notimp" causes qdelete()
+ but the host source address checking and so on is still done.
+
+[paul@vix.com 25apr93]: clean up #ifdef's and portability
+ feature #ifdef's should be limited to whole functions, which will be
+ called no matter what and would only be non-empty if the feature is
+ enabled. allow feature ifdef's in .h files, though.
+
+ portability #ifdef's should be limited to whole functions, too. add
+ a new portability.c module that implements anything which varies from
+ system to system.
+
+ add a second portability.h-like file that is included _before_ all the
+ system includes. portability.h as it stands is included _after_ all
+ system includes, which is convenient for most things but not all.
+
+[sater@cs.vu.nl 26apr93]: sortlist improvement
+ Improve the code around the sortlist area to better cope with parallel
+ networks of different speeds. The -i hack I sent to you could function
+ as inspiration only.
+
+[kre@munnari.oz.au 26apr93]: add an INN style control interface
+ to replace sending signals. With that expand debugging to
+ permit monitoring of actions taken on a single query
+ (query through control port, full traced as it occurs)
+ or all queries that reference some particular name or
+ zone, or which are forwarded, or asked, of some
+ particluar server. Allow reloads & dumps of a single
+ zone, rather than the whole universe. Allow selective
+ cache pruning (to edit away bad data that's been obtained
+ from somewhere)
+
+[kre@munnari.oz.au 26apr93]: add a syntax to zone files (non rfc
+ standard, but I don't care) to permit RR's to age away
+ at some particular time, and others to become active at
+ some particular time (probably with a syntax something
+ like "<[date]" or "@[date]" preceding, or in the
+ former case, replacing, the TTL field of the record).
+ Approaching "date" in the "<[date]" case, the TTL's on
+ the record would be decreased, so no data cached anywhere
+ will remain valid after "date", after "date", this RR
+ would simply be inoperative (essentially identical to
+ a comment). In the "@[date]" case (or perhaps ">[date]"
+ for symmetry) the RR would be ignored until "date" at
+ which time the "@[date]" field would simply be ignored.
+ Both annotations could be used together (with
+ appropriate interpretations depending on which date is
+ earlier than the other). Annotations on RR's in a zone
+ would cause the SOA parameters to be automatically
+ adjusted in zone transfers (and SOA requests) so that
+ secondary servers would also hand out the same values
+ (dropping the TTL down low as a "<[date]" approaches,
+ and forcing a new zone transfer at "date").
+
+[steve@uunet.uu.net 26apr93]: TXT RR improvements
+ - fix TXT records so that they can deal properly with multiple
+ strings (e.g., ``foo IN TXT "aaa" "bbb"''). This
+ results in a fair number of smallish changes throughout the
+ code and also throughout various tools (e.g., nslookup).
+
+[kyle@uunet.uu.net 16may93]: need an option to die if primary zone file missing
+ as of 4.9, a server will not forward a query if it is itself on the
+ NS list for the relevant domain. this means that if a primary server
+ cannot load its zone file, it will not be able to answer queries in
+ that zone -- it won't even forward them. this is arguably correct,
+ since it prevents bad forwarding loops when two or more servers are
+ all unable to load the zone (primary or secondary, with secondary
+ failures being the more common). what is needed is real loop detection
+ such that reasonable non-looping queries can be forwarded. what we're
+ likely to actually get is an option that causes named to just syslog
+ and die if it can't load a primary zone file. note that at present,
+ named is running somewhat bare-assed since an expired zone in a
+ secondary (or missing zone file in a primary) will cause that named
+ to return SERVFAIL for all queries to that zone. if your screwed up
+ primary/secondary server is also the forwarding server for a collection
+ of hosts, those hosts will get SERVFAIL's back from queries to the
+ affected domains, and depending on the age of their resolvers, they
+ might not try other servers after they get the first SERVFAIL.
+ [ this entry was written by Paul Vixie after getting a problem report
+ from Kyle after uu.net disappeared in a brief but ugly way. --vix ]
+
+[paul@vix.com 05jun94]: things i'm expecting to fix someday:
+ -> finish STATS (b+tree?), remove older A_RR-based tagging
+ -> (more?) svr4 changes from wisner@well, marc@cam, istewart@datlog
+ -> switch completely to posix-style signals
+ -> xfrnets directives should aggregate
+ -> syntactic sugar to use "mtime" of file as soa serial number
+ -> better support for "firewalls" (zohar@ibm, minnich@dupont)
+ -> attributes in TXT RR (cpw@lanl)
+ -> fix database consistency problems during zone reloads (Bob Heiney)
+ -> preliminary support for variable width subnet masks
+ -> failover isn't working very well for hesiod queries (gshapiro)
+ -> dig needs to be able to turn on RES_INSECURE{1,2} options
+ -> clean out old RR's that lay within a newly loaded zone file (heiney)
+ -> automatically refresh root.cache from the root servers periodically
+ -> Makefiles should use/pass CFLAGS rather than modifying CC
+ -> use Berkeley DB rather than malloc() for all database ops
+ -> include files should be generated from templates
+ -> use nvi-style port/* hierarchy, fewer portability #ifdef's
+ -> make __res static, add procedural interface to replace "extern"'ing
+ -> add hesiod/yp capable versions of get{pw,serv,???}by*()
+ -> add hesiod/yp to get{net,host}by*()
+ -> do something like solaris' /etc/nsswitch.conf (but in resolv.conf)
+ -> we should only need one copy of binary->text, text->binary, and
+ packet marshalling/unmarshalling. add general routines to -lresolv,
+ and rearrange the code to use them.
+ -> apps that want to do DNS queries should not have to learn res_query;
+ a higher level interface should be provided, that has its own cache
+ and/or shares with the server's DB-based one.
+ -> implement or integrate the next round of RFC's (coming soon).
+
+[paul@vix.com 05jun95]: more things i'm expecting to fix someday:
+ -> add "ndc checkconf" (i.e., "named -v")
+
+## ++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--
diff --git a/contrib/bind/conf/bsdinstall.sh b/contrib/bind/conf/bsdinstall.sh
new file mode 100755
index 0000000..58f87de
--- /dev/null
+++ b/contrib/bind/conf/bsdinstall.sh
@@ -0,0 +1,251 @@
+#! /bin/sh
+
+## (From INN-1.4, written by Rich Salz)
+## $Revision: 8.1 $
+## A script to install files and directories.
+
+PROGNAME=`basename $0`
+
+## Paths to programs. CHOWN and WHOAMI are checked below.
+CHOWN=chown
+CHGRP=chgrp
+CHMOD=chmod
+CP=cp
+LN=ln
+MKDIR=mkdir
+MV=mv
+RM=rm
+STRIP=strip
+WHOAMI=whoami
+
+## Some systems don't support -x, so we have to use -f.
+if [ ${CHOWN} = chown ] ; then
+ if [ -f /etc/chown ] ; then
+ CHOWN=/etc/chown
+ else
+ if [ -f /usr/etc/chown ] ; then
+ CHOWN=/usr/etc/chown
+ fi
+ fi
+fi
+
+if [ ${WHOAMI} = whoami ] ; then
+ if [ -f /usr/ucb/whoami ] ; then
+ WHOAMI=/usr/ucb/whoami
+ fi
+fi
+
+## Defaults.
+CHOWNIT=false
+CHGROUPIT=false
+CHMODIT=false
+STRIPIT=false
+BACKIT=false
+TOUCHIT=true
+SAVESRC=false
+ROOT=unknown
+
+## Process JCL.
+MORETODO=true
+while ${MORETODO} ; do
+ case X"$1" in
+ X-b)
+ BACKIT=true
+ BACKUP="$2"
+ shift
+ ;;
+ X-b*)
+ BACKIT=true
+ BACKUP=`expr "$1" : '-b\(.*\)'`
+ ;;
+ X-c)
+ SAVESRC=true
+ ;;
+ X-g)
+ GROUP="$2"
+ CHGROUPIT=true
+ shift
+ ;;
+ X-g*)
+ GROUP=`expr "$1" : '-g\(.*\)'`
+ CHGROUPIT=true
+ ;;
+ X-G)
+ case ${ROOT} in
+ unknown)
+ case `${WHOAMI}` in
+ root)
+ ROOT=true
+ ;;
+ *)
+ ROOT=false
+ ;;
+ esac
+ ;;
+ esac
+ GROUP="$2"
+ shift
+ ${ROOT} && CHGROUPIT=true
+ ;;
+ X-G*)
+ case ${ROOT} in
+ unknown)
+ case `${WHOAMI}` in
+ root)
+ ROOT=true
+ ;;
+ *)
+ ROOT=false
+ ;;
+ esac
+ ;;
+ esac
+ if ${ROOT} ; then
+ GROUP=`expr "$1" : '-g\(.*\)'`
+ CHGROUPIT=true
+ fi
+ ;;
+ X-m)
+ MODE="$2"
+ CHMODIT=true
+ shift
+ ;;
+ X-m*)
+ MODE=`expr "$1" : '-m\(.*\)'`
+ CHMODIT=true
+ ;;
+ X-n)
+ TOUCHIT=false
+ ;;
+ X-o)
+ OWNER="$2"
+ CHOWNIT=true
+ shift
+ ;;
+ X-o*)
+ OWNER=`expr "$1" : '-o\(.*\)'`
+ CHOWNIT=true
+ ;;
+ X-O)
+ case ${ROOT} in
+ unknown)
+ case `${WHOAMI}` in
+ root)
+ ROOT=true
+ ;;
+ *)
+ ROOT=false
+ ;;
+ esac
+ ;;
+ esac
+ OWNER="$2"
+ shift
+ ${ROOT} && CHOWNIT=true
+ ;;
+ X-O*)
+ case ${ROOT} in
+ unknown)
+ case `${WHOAMI}` in
+ root)
+ ROOT=true
+ ;;
+ *)
+ ROOT=false
+ ;;
+ esac
+ ;;
+ esac
+ if ${ROOT} ; then
+ OWNER=`expr "$1" : '-o\(.*\)'`
+ CHOWNIT=true
+ fi
+ ;;
+ X-s)
+ STRIPIT=true
+ ;;
+ X--)
+ shift
+ MORETODO=false
+ ;;
+ X-*)
+ echo "${PROGNAME}: Unknown flag $1" 1>&2
+ exit 1
+ ;;
+ *)
+ MORETODO=false
+ ;;
+ esac
+ ${MORETODO} && shift
+done
+
+## Process arguments.
+if [ $# -ne 2 ] ; then
+ echo "Usage: ${PROGNAME} [flags] source destination"
+ exit 1
+fi
+
+## Making a directory?
+if [ X"$1" = X. ] ; then
+ DEST="$2"
+ if [ ! -d "${DEST}" ] ; then
+ ${MKDIR} "${DEST}" || exit 1
+ fi
+ if ${CHOWNIT} ; then
+ ${CHOWN} "${OWNER}" "${DEST}" || exit 1
+ fi
+ if ${CHGROUPIT} ; then
+ ${CHGRP} "${GROUP}" "${DEST}" || exit 1
+ fi
+ if ${CHMODIT} ; then
+ umask 0
+ ${CHMOD} "${MODE}" "${DEST}" || exit 1
+ fi
+ exit 0
+fi
+
+## Get the destination and a temp file in the destination diretory.
+if [ -d "$2" ] ; then
+ DEST="$2/$1"
+ TEMP="$2/$$.tmp"
+else
+ DEST="$2"
+ TEMP="`expr "$2" : '\(.*\)/.*'`/$$.tmp"
+fi
+
+## If not given the same name, we must try to copy.
+if [ X"$1" != X"$2" -o $SAVESRC ] ; then
+ if cmp -s "$1" "${DEST}" ; then
+ ## Files are same; touch or not.
+ ${TOUCHIT} && touch "${DEST}"
+ else
+ ## If destination exists and we wish to backup, link to backup.
+ if [ -f "${DEST}" ] ; then
+ if ${BACKIT} ; then
+ ${RM} -f "${DEST}${BACKUP}"
+ ${LN} "${DEST}" "${DEST}${BACKUP}"
+ fi
+ fi
+ ## Copy source to the right dir, then move to right spot.
+ ## Done in two parts so we can hope for atomicity.
+ ${RM} -f "${TEMP}" || exit 1
+ ${CP} "$1" "${TEMP}" || exit 1
+ ${MV} -f "${TEMP}" "${DEST}" || exit 1
+ fi
+fi
+
+## Strip and set the modes.
+if ${STRIPIT} ; then
+ ${STRIP} "${DEST}" || exit 1
+fi
+if ${CHOWNIT} ; then
+ ${CHOWN} "${OWNER}" "${DEST}" || exit 1
+fi
+if ${CHGROUPIT} ; then
+ ${CHGRP} "${GROUP}" "${DEST}" || exit 1
+fi
+if ${CHMODIT} ; then
+ umask 0
+ ${CHMOD} "${MODE}" "${DEST}" || exit 1
+fi
+exit 0
diff --git a/contrib/bind/conf/copyright b/contrib/bind/conf/copyright
new file mode 100644
index 0000000..a441ff8
--- /dev/null
+++ b/contrib/bind/conf/copyright
@@ -0,0 +1,50 @@
+-
+Copyright (c) XYZZY
+ 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.
+-
diff --git a/contrib/bind/conf/master/README b/contrib/bind/conf/master/README
new file mode 100644
index 0000000..4e49af6
--- /dev/null
+++ b/contrib/bind/conf/master/README
@@ -0,0 +1,45 @@
+
+How to add new hosts to the name server data base:
+
+1) Edit 'named.hosts' file:
+
+ For each machine you need to enter the following information:
+ machine name, all its network addresses, host information, and common
+ aliases for it.
+
+ This is the entry for calder.
+
+CALDER IN A 128.32.130.1
+ IN A 128.32.129.3
+ IN HINFO VAX-11/750 UNIX
+UCBCALDER IN CNAME CALDER
+
+ For the machine you are adding:
+ 1) replace 'CALDER' with the new machine name
+ 2) replace '128.32.130.1' with the new machines address
+ if there is more then one address for the machine
+ then add lines like the one with '128.32.129.3'
+ 3) replace 'VAX-11/750' with the machine type
+ 4) If it doesn't run 'UNIX' then replace UNIX with its
+ operating system.
+
+2) Edit 'named.rev' file:
+
+ For each address of a machine you need to enter the reverse
+ address notation for the machine:
+
+ For calder the lines look as follows:
+
+12.0 IN PTR CALDER.BERKELEY.EDU.
+3.129 IN PTR CALDER.BERKELEY.EDU.
+
+ Calder has two address '128.32.0.12' and '128.32.129.3'
+
+ You take the two numbers after 128.32 and reverse them.
+ Then replace CALDER with the new machine name.
+
+ *** Note the trailing "." on "EDU." it needs to be there. Otherwise
+ BIND will add the current $ORIGIN to this name, which won't work.
+ ***
+
+3) Increment the serial number on both files.
diff --git a/contrib/bind/conf/master/named.boot b/contrib/bind/conf/master/named.boot
new file mode 100644
index 0000000..7d467f2
--- /dev/null
+++ b/contrib/bind/conf/master/named.boot
@@ -0,0 +1,18 @@
+;
+; @(#)named.boot.slave 1.13 (Berkeley) 87/07/21
+;
+; boot file for secondary name server
+; Note that there should be one primary entry for each SOA record.
+;
+;
+sortlist 10.0.0.0
+
+directory /usr/local/adm/named
+
+; type domain source host/file backup file
+
+cache . root.cache
+secondary Berkeley.EDU 128.32.137.8 128.32.137.3 ucbhosts.bak
+secondary 32.128.IN-ADDR.ARPA 128.32.137.8 128.32.137.3 ucbhosts.rev.bak
+primary 0.0.127.IN-ADDR.ARPA localhost.rev
+
diff --git a/contrib/bind/conf/master/named.boot.master b/contrib/bind/conf/master/named.boot.master
new file mode 100644
index 0000000..702ffcf
--- /dev/null
+++ b/contrib/bind/conf/master/named.boot.master
@@ -0,0 +1,16 @@
+;
+; boot file for authoritive master name server for Berkeley.EDU
+; Note that there should be one primary entry for each SOA record.
+;
+;
+sortlist 10.0.0.0
+
+directory /usr/local/adm/named
+
+; type domain source host/file backup file
+
+cache . root.cache
+primary Berkeley.EDU berkeley.zone
+primary 32.128.IN-ADDR.ARPA berkeley.rev
+primary 0.0.127.IN-ADDR.ARPA localhost.rev
+
diff --git a/contrib/bind/conf/master/named.hosts b/contrib/bind/conf/master/named.hosts
new file mode 100644
index 0000000..d31b3bd
--- /dev/null
+++ b/contrib/bind/conf/master/named.hosts
@@ -0,0 +1,22 @@
+; Authoritative data for Berkeley.EDU (ORIGIN assumed Berkeley.EDU)
+;
+@ IN SOA ucbvax.berkeley.edu kjd.ucbvax.berkeley.edu (
+ 1986020501 ; Serial
+ 10800 ; Refresh 3 hours
+ 3600 ; Retry 1 hour
+ 3600000 ; Expire 1000 hours
+ 86400 ) ; Minimum 24 hours
+ IN MX 10 ucb-vax
+ IN NS monet
+localhost IN A 127.1
+ucb-arpa IN A 10.0.0.78
+ IN A 128.32.0.4
+ IN HINFO VAX-11/780 UNIX
+arpa IN CNAME ucbarpa
+ucb-vax 9999 IN A 10.2.0.78
+ IN A 128.32.0.10
+ IN HINFO VAX-11/750 UNIX
+ucbvax IN CNAME ucb-vax
+monet IN A 128.32.0.7
+ IN HINFO VAX-11/750 UNIX
+ucbmonet IN CNAME monet
diff --git a/contrib/bind/conf/master/named.local b/contrib/bind/conf/master/named.local
new file mode 100644
index 0000000..e0270ea
--- /dev/null
+++ b/contrib/bind/conf/master/named.local
@@ -0,0 +1,13 @@
+;
+; @(#)named.local 1.1 (Berkeley) 86/01/21
+;
+
+@ IN SOA ucbvax.Berkeley.EDU. kjd.ucbvax.Berkeley.EDU. (
+ 1986012101 ; Serial
+ 3600 ; Refresh
+ 300 ; Retry
+ 3600000 ; Expire
+ 14400 ) ; Minimum
+ IN NS ucbvax.Berkeley.EDU.
+0 IN PTR loopback.ucbvax.Berkeley.EDU.
+1 IN PTR localhost.
diff --git a/contrib/bind/conf/master/named.rev b/contrib/bind/conf/master/named.rev
new file mode 100644
index 0000000..6d1fb58
--- /dev/null
+++ b/contrib/bind/conf/master/named.rev
@@ -0,0 +1,30 @@
+;
+; @(#)named.rev 1.1 (Berkeley) 86/02/05
+;
+
+@ IN SOA ucbvax.berkeley.edu kjd.ucbvax.berkeley.edu (
+ 1986020501 ; Serial
+ 10800 ; Refresh 3 hours
+ 3600 ; Retry 1 hour
+ 3600000 ; Expire 1000 hours
+ 86400 ) ; Minimum 24 hours
+ IN NS ucbvax.Berkeley.EDU.
+; RFC 1101 stuff
+0.0 IN PTR Berkeley-net.Berkeley.EDU.
+ IN A 255.255.255.0
+; real hosts
+0.130 IN PTR csdiv-net.Berkeley.EDU.
+2.129 IN PTR monet.Berkeley.EDU.
+2.140 IN PTR ucbarpa.Berkeley.EDU.
+3.132 IN PTR cad.Berkeley.EDU.
+4.0 IN PTR ucbarpa.Berkeley.EDU.
+5.0 IN PTR cad.Berkeley.EDU.
+6.0 IN PTR ernie.Berkeley.EDU.
+6.130 IN PTR monet-cs.Berkeley.EDU.
+7.0 IN PTR monet.Berkeley.EDU.
+7.130 IN PTR kim.Berkeley.EDU.
+9.0 IN PTR esvax.Berkeley.EDU.
+10.0 IN PTR ucbvax.Berkeley.EDU.
+11.0 IN PTR kim.Berkeley.EDU.
+11.156 IN PTR esvax-156.Berkeley.EDU.
+38.131 IN PTR monet.Berkeley.EDU.
diff --git a/contrib/bind/conf/master/root.cache b/contrib/bind/conf/master/root.cache
new file mode 100644
index 0000000..48abd78
--- /dev/null
+++ b/contrib/bind/conf/master/root.cache
@@ -0,0 +1,63 @@
+; This file holds the information on root name servers needed to
+; initialize cache of Internet domain name servers
+; (e.g. reference this file in the "cache . <file>"
+; configuration file of BIND domain name servers).
+;
+; This file is made available by InterNIC registration services
+; under anonymous FTP as
+; file /domain/named.root
+; on server FTP.RS.INTERNIC.NET
+; -OR- under Gopher at RS.INTERNIC.NET
+; under menu InterNIC Registration Services (NSI)
+; submenu InterNIC Registration Archives
+; file named.root
+;
+; last update: Nov 8, 1995
+; related version of root zone: 1995110800
+;
+;
+; formerly NS.INTERNIC.NET
+;
+. 3600000 IN NS A.ROOT-SERVERS.NET.
+A.ROOT-SERVERS.NET. 3600000 A 198.41.0.4
+;
+; formerly NS1.ISI.EDU
+;
+. 3600000 NS B.ROOT-SERVERS.NET.
+B.ROOT-SERVERS.NET. 3600000 A 128.9.0.107
+;
+; formerly C.PSI.NET
+;
+. 3600000 NS C.ROOT-SERVERS.NET.
+C.ROOT-SERVERS.NET. 3600000 A 192.33.4.12
+;
+; formerly TERP.UMD.EDU
+;
+. 3600000 NS D.ROOT-SERVERS.NET.
+D.ROOT-SERVERS.NET. 3600000 A 128.8.10.90
+;
+; formerly NS.NASA.GOV
+;
+. 3600000 NS E.ROOT-SERVERS.NET.
+E.ROOT-SERVERS.NET. 3600000 A 192.203.230.10
+;
+; formerly NS.ISC.ORG
+;
+. 3600000 NS F.ROOT-SERVERS.NET.
+F.ROOT-SERVERS.NET. 3600000 A 192.5.5.241
+;
+; formerly NS.NIC.DDN.MIL
+;
+. 3600000 NS G.ROOT-SERVERS.NET.
+G.ROOT-SERVERS.NET. 3600000 A 192.112.36.4
+;
+; formerly AOS.ARL.ARMY.MIL
+;
+. 3600000 NS H.ROOT-SERVERS.NET.
+H.ROOT-SERVERS.NET. 3600000 A 128.63.2.53
+;
+; formerly NIC.NORDU.NET
+;
+. 3600000 NS I.ROOT-SERVERS.NET.
+I.ROOT-SERVERS.NET. 3600000 A 192.36.148.17
+; End of File
diff --git a/contrib/bind/conf/options.h b/contrib/bind/conf/options.h
new file mode 100644
index 0000000..b5548af
--- /dev/null
+++ b/contrib/bind/conf/options.h
@@ -0,0 +1,167 @@
+/* options.h - specify the conditionally-compiled features
+ * vix 28mar92 [moved out of the Makefile because they were getting too big]
+ *
+ * $Id: options.h,v 8.9 1996/05/17 09:10:41 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--
+ */
+
+/* Key:
+ * ucb = U C Berkeley 4.8.3 release
+ * vix = Paul Vixie of Digital
+ * del = Don Lewis of Harris
+ * mcsun = Piet Beertema of EUNet
+ * asp = Andrew Partan of UUNet
+ * pma = Paul Albitz of Hewlett Packard
+ * bb = Bryan Beecher of UMich
+ * mpa = Mark Andrews of CSIRO - DMS
+ * rossc = Ross Cartlidge of The Univeritsy of Sydney
+ * mtr = Marshall Rose of TPC.INT
+ * bg = Benoit Grange of INRIA
+ * ckd = Christopher Davis of Kapor Enterprises
+ * gns = Greg Shapiro of WPI
+ */
+
+#define DEBUG /* enable -d flag and SIGUSR[12] support (ucb) */
+/*#define ALLOW_T_UNSPEC /* enable the "unspec" RR type for old athena (ucb) */
+/*#define INVQ /* enable inverse queries (nslookup) (ucb/vix) */
+/*#define DSTORAGE /* debug malloc overruns using storage.o (ucb/vix) */
+/*#define DMALLOC /* trace malloc orphans using dmalloc.o (vix) */
+#define XFRNETS /* enable "xfrnets" command in named.boot (vix) */
+#define PID_FIX /* be careful about overwriting named.pid file (del) */
+#define FWD_LOOP /* try to break out of forwarding loops (del) */
+#define NO_GLUE /* don't accept or send out-of-zone glue (del) */
+#define BOGUSNS /* detect bogus nameservers (mcsun) */
+#define QRYLOG /* enable SIGWINCH for query logging (bb) */
+/*#define YPKLUDGE /* deal effectively with broken "ypserv -i" (mcsun) */
+#define TRACEROOT /* trace bogus root servers and ignore them (pma,bb) */
+/*#define LOCALDOM /* permit "domain" directive in named.boot (ucb) */
+#define FORCED_RELOAD /* refresh secondary zones on SIGHUP (pma) */
+#define SLAVE_FORWARD /* use sensible timeouts on slave forwarders (pma) */
+#define WANT_PIDFILE /* if you want the named.pid file (ucb/arc) */
+#define DOTTED_SERIAL /* if you want to be able to specify dotted serial#s */
+/*#define SENSIBLE_DOTS /* if you want dotted serial#s to make numeric sense */
+#define NCACHE /* negative caching (anant@isi.edu) */
+/*#define VALIDATE /* validation procedure (anant@isi.edu) (BUGGY!) */
+/*#define SHORT_FNAMES /* file names used in named-xfer need to be short */
+#define RESOLVSORT /* allow sorting of addresses in gethostbyname (mpa) */
+#define STUBS /* allow transfers of NS only for a zone (mpa) */
+#ifndef LOGFAC
+#define LOGFAC LOG_DAEMON /* what syslog facility should named use? */
+#endif
+#define SECURE_ZONES /* if you want to inhibit world access to zones (gns)*/
+#define ROUND_ROBIN /* rotate databuf list after each access (mtr) */
+#define ADDAUTH /* return NS and glue w/ authorative answers (mpa) */
+#define RFC1535 /* use RFC 1535 default for "search" list (vix) */
+#define GEN_AXFR /* distinct zones within each class */
+#define DATUMREFCNT /* use reference counts on datums (mpa) */
+#define LAME_DELEGATION /* lame delegations (original-del,reworked-bb&del)*/
+#define LAME_LOGGING LOG_DEBUG /* log lame delegations, set log level */
+#define GETSER_LOGGING LOG_INFO /* log errors/timeouts getting serial number */
+/*#define RETURNSOA /* good code that the world isn't ready for yet */
+#define CLEANCACHE /* useful and necessary in the face of NCACHE */
+#define PURGE_ZONE /* remove all traces of a zone when reloading (mpa) */
+#define STATS /* keep nameserver statistics; uses more memory */
+#define RENICE /* named-xfer should run at normal priority */
+/*#define XSTATS /* extended statistics, syslogged periodically (bg) */
+/*#define BIND_NOTIFY /* experimental - do not enable in customer products */
+#define LOC_RR /* support for LOC record parsing (ckd/vix) */
+#define SORT_RESPONSE /* should we try to sort responses optimally? (vix) */
+
+/*--------------------------------------------*
+ * no user-servicable parts beyond this point *
+ *--------------------------------------------*/
+
+/* if DSTORAGE is defined, we need to disable DMALLOC and remap
+ * malloc and free to storage.o's exported names. storage.o also
+ * includes a calloc and a realloc, but once we drag in its malloc
+ * and free we'll get the others automatically and so will never
+ * pull in those routines from libc.a.
+ */
+#ifdef DSTORAGE
+# ifdef DMALLOC
+# undef DMALLOC
+# endif /*DMALLOC*/
+# define malloc rt_malloc
+# define free rt_free
+#endif /*DSTORAGE*/
+
+/* if DMALLOC is defined, grab the header file which will remap
+ * all the malloc-style names to those exported by dmalloc.o. note
+ * that DMALLOC also changes the function signatures of several
+ * functions in private named source modules, and that this file
+ * (options.h) must be included before any other private *.h files
+ * since those *.h files have some conditional remapping to do.
+ */
+#ifdef DMALLOC
+# include "dmalloc.h"
+#endif
+
+/* systems with killall(1M) don't need this
+ */
+#ifdef __sgi
+# ifdef WANT_PIDFILE
+# undef WANT_PIDFILE
+# endif
+#endif
+
+#ifdef LAME_LOGGING
+# define LAME_DELEGATION
+#endif
+
+#if defined(XSTATS) && !defined(STATS)
+# define STATS
+#endif
diff --git a/contrib/bind/conf/portability.h b/contrib/bind/conf/portability.h
new file mode 100644
index 0000000..388b5ff
--- /dev/null
+++ b/contrib/bind/conf/portability.h
@@ -0,0 +1,595 @@
+/* portability.h - include or define things that aren't present on all systems
+ * vixie@decwrl 26dec92 [new]
+ *
+ * $Id: portability.h,v 8.14 1996/06/06 20:19:09 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--
+ */
+
+/* XXX: this file has become a hopeless morass, and will be redone someday. */
+
+#include <string.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#ifndef TIME_H_INCLUDED
+# include <sys/time.h>
+# define TIME_H_INCLUDED
+#endif
+
+#ifdef ISC
+# ifndef _POSIX_SOURCE
+# define _POSIX_SOURCE
+# endif
+# define SYSV
+# define SVR3
+# define _SYSV3
+# define NEED_STRTOUL
+# define NEED_FTRUNCATE
+# define USE_POSIX
+# include <sys/bsdtypes.h>
+# include <sys/sioctl.h>
+# include <sys/stream.h>
+# include <net/errno.h>
+#endif
+
+#if defined(__convex__)
+# if !defined(_POSIX_SOURCE)
+# define _POSIX_SOURCE
+# endif
+# define USE_UTIME
+# define NEED_PUTENV
+#endif
+
+#if defined(_CRAY)
+# if !defined(_POSIX_SOURCE)
+# define _POSIX_SOURCE
+# endif
+# define writev(a,b,c) __writev(a,b,c)
+# define setitimer(a,b,c) __setitimer(a,b,c)
+#endif
+
+/* This is defined in the Makefile for ISC compiles. */
+#if defined(ISC)
+# define ftruncate(a,b) __ftruncate(a,b)
+# define USE_MEMCPY
+# define USE_UTIME
+# define HAVE_FCHMOD 0
+#endif
+
+/* SCO UNIX defines only this unique symbol, apparently. */
+#if defined(M_UNIX)
+/* XXX - why is this POSIX_SOURCE instead of _POSIX_SOURCE? */
+# undef POSIX_SOURCE
+# define POSIX_SIGNALS
+# define HAVE_FCHMOD 0
+# define writev(a,b,c) __writev(a,b,c)
+# define ftruncate(a,b) __ftruncate(a,b)
+#endif
+
+#ifdef NeXT
+# define NEED_PUTENV
+# define NEED_SETENV
+# define inet_addr(a) __inet_addr(a)
+#endif
+
+#if defined(__sgi)
+# define BSD 43
+# define vfork fork
+#endif
+
+#if defined(SUNOS4)
+# define BSD 43
+#endif
+
+#if defined(__osf__) && defined(__alpha)
+# undef BSD
+# define BSD 199103
+#endif
+
+#if defined(_AUX_SOURCE)
+# define vfork fork
+# define NEED_STRERROR
+# define NEED_STRTOUL
+# define SIG_FN void
+# define USE_MEMCPY
+#endif
+
+
+#if defined(SVR4) && !defined(SYSV)
+# define SYSV
+#endif
+
+#if defined(_POSIX_SOURCE) || defined(__sgi) || defined(__ultrix) || \
+ defined(__hpux) || (defined(BSD) && (BSD >= 199103)) || \
+ (defined(sun) && defined(SYSV))
+# define USE_POSIX
+#endif
+
+#if defined(__ultrix) && !defined(BSD)
+# define BSD 42
+#endif
+
+#if defined(host_mips) && defined(SYSTYPE_BSD43)
+# define RISCOS_BSD
+#endif
+
+#if defined(SYSV) || defined(__ultrix) || defined(__osf__) \
+ || (defined(BSD) && BSD >= 199306) || defined(linux)
+# define USE_UTIME
+# define HAVE_SETVBUF
+#endif
+
+#if defined(SYSV) && !defined(SVR4)
+# define vfork fork
+#endif
+
+#if defined(sun) || defined(SVR4)
+# define NETREAD_BROKEN
+#endif
+
+#if defined(BSD) && BSD >= 199006 && !defined(i386) && !defined(RISCOS_BSD)
+# define HAVE_DAEMON
+#endif
+
+#if !defined(BSD) || (BSD <= 199006)
+# if !defined(NeXT)
+# define NEED_INETADDR
+# endif
+# define NEED_INETATON
+#endif
+
+#if defined(__hpux)
+# if defined(__STDC__)
+# define select(a,b,c,d,e) select(a, (int *)b, (int *)c, (int *)d, e)
+# define ctime(x) ctime((const time_t *)x)
+# endif /*__STDC__*/
+# if !defined(SYSV)
+# define USE_UTIME
+# define setlinebuf(x) setvbuf(x, NULL, _IOLBF, BUFSIZ)
+# if !defined(SIGWINCH) /*pre 9.0*/
+# define SIGWINCH SIGWINDOW
+# endif
+# endif /*SYSV*/
+/* XXX: better autodetection of the need for "struct linger" would be nice */
+# if 0
+struct linger {
+ int l_onoff; /* option on/off */
+ int l_linger; /* linger time */
+};
+# endif
+#endif /*__hpux*/
+
+#if defined(_SEQUENT_)
+# include <netinet/in_systm.h>
+# define USE_UTIME
+# define USE_POSIX
+# define NEED_GETTIMEOFDAY
+# define _TIMEZONE timezoneBSD
+struct timezoneBSD {
+ int tz_minuteswest;
+ int tz_dsttime;
+};
+#endif
+
+#ifndef __P
+# if defined(__STDC__) || defined(__GNUC__)
+# define __P(x) x
+# else
+# define __P(x) ()
+# endif
+#endif
+
+#ifndef _TIMEZONE
+# define _TIMEZONE timezone
+#endif
+
+#if defined(USE_POSIX)
+# include <stdlib.h>
+# include <unistd.h>
+# include <limits.h>
+# if defined(__ultrix)
+# define NEED_STRDUP
+# endif
+
+#else
+
+# define NEED_STRTOUL
+# define NEED_STRDUP
+
+# define STDIN_FILENO 0
+# define STDOUT_FILENO 1
+# define STDERR_FILENO 2
+# ifndef NeXT
+extern char *getenv __P((char *));
+# else
+extern char *getenv __P((const char *));
+# endif
+extern int errno;
+
+# if !defined(DMALLOC) && !defined(NeXT)
+extern char *malloc(), *realloc(), *calloc();
+# if defined(sun)
+extern int free();
+# else
+extern void free();
+# endif
+# endif
+
+extern int getdtablesize __P((void));
+# ifdef SHORT_FNAMES
+extern long pathconf __P((const char *path, int name));
+# endif
+
+#endif /*USE_POSIX*/
+
+#ifndef UINT_MAX
+# ifdef __STDC__
+# define UINT_MAX 4294967295u /* max value of an "u_int" */
+# else
+# define UINT_MAX ((unsigned)4294967295) /* max value of an "u_int" */
+# endif
+# define ULONG_MAX UINT_MAX /* max decimal value of a "u_long" */
+#endif
+
+#ifndef INT_MAX
+# define INT_MAX 2147483647 /* max decimal value of an "int" */
+#endif
+
+#ifndef RAND_MAX
+# define RAND_MAX 0x7fffffff
+#endif
+
+#ifndef IN_LOOPBACKNET
+# define IN_LOOPBACKNET 127
+#endif
+
+#ifndef INADDR_NONE
+# define INADDR_NONE 0xffffffff
+#endif
+
+#if defined(apollo)
+ /* Defined in /usr/include/netinet/in.h but doesn't work */
+#undef IP_OPTIONS
+#endif
+
+#if !defined(__STDC__) && !defined(const)
+# define const /*constant*/
+#endif
+
+#if !defined(__convex__) && (!defined(BSD) || (BSD < 199103))
+int strcasecmp __P((const char *, const char *));
+#endif
+
+/* is USE_POSIX the right thing to use here? */
+#if (!defined(BSD) || (BSD <= 43)) && \
+ !defined(NeXT) && \
+ !defined(__convex__) && \
+ !defined(USE_POSIX)
+# if !defined(NCR)
+extern void syslog();
+# endif
+extern char *ctime __P((const time_t *clock));
+extern int close(), setitimer(), recv(), sendto(), sigsetmask(),
+ atoi(), getpid(), fork(), read(), ioctl(),
+ setsockopt(), socket(), bind();
+#endif
+
+#if !defined(bcopy) /* some machines have their own macros for this */
+# if defined(USE_POSIX) || \
+ (defined(__STDC__) && !defined(sun) && !defined(sequent) \
+ && !defined(M_UNIX))
+/* use ANSI C3.159-1989 (``ANSI C'') functions if possible;
+ * ideally we would change the code to use them and then
+ * define them in terms of bcopy et al if !defined(__STDC__)
+ * but that's more work.
+ */
+#if defined(USE_MEMCPY)
+# define bcopy(a,b,c) memcpy(b,a,c)
+#else
+# define bcopy(a,b,c) memmove(b,a,c)
+#endif
+# define bzero(a,b) memset(a,0,b)
+# define bcmp(a,b,c) memcmp(a,b,c)
+# else
+extern void bcopy();
+extern void bzero();
+extern int bcmp();
+# endif /* BSD */
+#endif /* bcopy */
+
+#if (!defined(BSD) || (BSD < 43) || defined(RISCOS_BSD)) \
+ && !defined(USE_POSIX) && !defined(apollo) && !defined(sequent) \
+ && !defined(M_UNIX)
+# define NEED_STRERROR
+#if !defined(ultrix) && !defined(NCR)
+# define NEED_PUTENV
+#endif
+#endif
+
+#if defined(SUNOS4)
+# define NEED_STRERROR
+# if defined(sun386)
+# define pid_t int
+# define NEED_STRCASECMP
+# endif
+#endif
+
+#if (!defined(BSD) || (BSD < 43))
+# define NEED_MKSTEMP
+# if !defined(__ultrix) && !defined(apollo)
+# define NEED_STRCASECMP
+# define NEED_MKTEMP
+# if !defined(SVR4)
+# define NEED_STRPBRK
+# endif
+# endif
+#endif
+
+#if defined(USE_POSIX)
+# define POSIX_SIGNALS
+#endif
+
+/*
+ * Attempt to configure for type of function returned by signal-catching
+ * functions (which signal and sigvec.sv_handler take a pointer to).
+ * This can guess for BSD; otherwise, define SIG_FN externally.
+ */
+#ifndef SIG_FN
+# ifdef BSD
+# if (BSD >= 199006) || defined(NeXT) || defined(__osf__) || defined(sun) \
+ || defined(__ultrix) || defined(apollo) || defined(POSIX_SIGNALS)
+# define SIG_FN void /* signal-catching functions return void */
+# else
+# define SIG_FN int /* signal-catching functions return int */
+# endif
+# else /*BSD*/
+# define SIG_FN void /* signal-catching functions return void */
+# endif /*BSD*/
+#endif
+
+#if !defined(SIGUSR1) && !defined(SIGUSR2)
+# define SIGUSR1 SIGEMT
+# define SIGUSR2 SIGFPE
+#endif
+#if !defined(SIGCHLD)
+# define SIGCHLD SIGCLD
+#endif
+
+#if !defined(ntohl) && !defined(htonl) && defined(BSD) && (BSD <= 43)
+/* if these aren't null macros in netinet/in.h, extern them here. */
+extern u_short htons(), ntohs();
+extern u_long htonl(), ntohl();
+#endif
+
+#if defined(USE_POSIX) && !defined(sun) && !defined(__sgi) \
+ && !defined(__convex__) && !defined(__ultrix) && !defined(_AUX_SOURCE)
+# define PORT_NONBLOCK O_NONBLOCK
+# define PORT_WOULDBLK EAGAIN
+#else
+# define PORT_NONBLOCK O_NDELAY
+# define PORT_WOULDBLK EWOULDBLOCK
+#endif
+
+#if defined(USE_POSIX)
+# define USE_SETSID
+#endif
+
+#if defined(USE_POSIX) || !defined(SYSV)
+#define USE_WAITPID
+#endif
+
+#if !defined(USE_POSIX)
+#define waitpid(x,y,z) (wait3(y,z,(struct rusage *)NULL))
+#endif
+
+#if defined(NeXT) || defined(_AIX) || defined(sun386)
+# undef WIFEXITED
+# undef WEXITSTATUS
+# undef WIFSIGNALED
+# undef WTERMSIG
+#endif /* NeXT */
+
+#if defined(sequent)
+#define WEXITSTATUS(x) ((x).w_retcode)
+#define WTERMSIG(x) ((x).w_termsig)
+#endif /* sequent */
+
+#if !defined(WIFEXITED)
+# define WIFEXITED(x) (!(x & 0177))
+#endif
+#if !defined(WEXITSTATUS)
+# define WEXITSTATUS(x) (x >> 8)
+#endif
+#if !defined(WIFSIGNALED)
+# define WIFSIGNALED(x) ((x & 0177) && ((x & 0377) != 0177))
+#endif
+#if !defined(WTERMSIG)
+# define WTERMSIG(x) (x & 0177)
+#endif
+
+#ifndef S_ISDIR
+# ifndef S_IFMT
+# define S_IFMT 0170000
+# endif
+# ifndef S_IFDIR
+# define S_IFDIR 0040000
+# endif
+# define S_ISDIR(m) ((m & S_IFMT) == S_IFDIR)
+#endif
+
+#ifndef S_ISREG
+# ifndef S_IFMT
+# define S_IFMT 0170000
+# endif
+# ifndef S_IFREG
+# define S_IFREG 0100000
+# endif
+# define S_ISREG(m) ((m & S_IFMT) == S_IFREG)
+#endif
+
+#ifndef S_ISFIFO
+# ifndef S_IFMT
+# define S_IFMT 0170000
+# endif
+# ifndef S_IFIFO
+# define S_IFIFO 0010000
+# endif
+# define S_ISFIFO(m) ((m & S_IFMT) == S_IFIFO)
+#endif
+
+#if defined(NEED_STRTOUL) && \
+ (defined(__ultrix) || defined(__osf__) || defined(NeXT))
+# undef NEED_STRTOUL
+#endif
+
+#if defined(__ultrix) || defined(__osf__)
+# define MAYBE_HESIOD
+#endif
+
+#ifndef FD_SET
+#define NFDBITS 32
+#define FD_SETSIZE 32
+#define FD_SET(n, p) ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
+#define FD_CLR(n, p) ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))
+#define FD_ISSET(n, p) ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))
+#define FD_ZERO(p) bzero((char *)(p), sizeof(*(p)))
+#endif
+
+#ifndef MIN
+# define MIN(x, y) ((x > y) ?y :x)
+#endif
+#ifndef MAX
+# define MAX(x, y) ((x > y) ?x :y)
+#endif
+
+#if !defined(PATH_MAX)
+# if defined(_POSIX_PATH_MAX)
+# define PATH_MAX _POSIX_PATH_MAX
+# else
+# if defined(MAXPATHLEN)
+# define PATH_MAX MAXPATHLEN
+# endif
+# endif
+#endif
+
+#if defined(BSD) || defined(__osf__) || defined(__convex__)
+# define HAVE_GETRUSAGE
+#endif
+
+/* May be set in the Makefile. */
+#if defined(HAVE_GETRUSAGE)
+# include <sys/resource.h>
+#endif
+
+/*
+ * Because Convex has true library function feof() which is
+ * patently wrong (it test bit _IOREAD) we need feof() as
+ * a macro.
+ */
+#if defined(__convex__) && !defined(feof)
+# define feof(p) ((p)->_flag&_IOEOF)
+#endif
+
+#if defined(M_UNIX) || defined(linux)
+# define SPURIOUS_ECONNREFUSED
+#endif
+
+/*
+ * Assume that a system has fchmod() unless something above says otherwise.
+ */
+#if !defined(HAVE_FCHMOD)
+# define HAVE_FCHMOD 1
+#endif
+
+
+/*
+ * Types needed for POSIX but missing on some systems.
+ */
+#if defined(SUNOS4)
+typedef int ssize_t;
+#endif
+
+/*
+ * We need to know the IPv6 address family number even on IPv4-only systems.
+ * Note that this is NOT a protocol constant, and that if the system has its
+ * own AF_INET6, different from ours below, all of BIND's libraries and
+ * executables will need to be recompiled after the system <sys/socket.h>
+ * has had this type added. The type number below is correct on most BSD-
+ * derived systems for which AF_INET6 is defined.
+ */
+#ifndef AF_INET6
+#define AF_INET6 24
+#endif
+
+/*
+ * Prototype the functions we'll be supplying.
+ */
+#ifdef NEED_PUTENV
+extern int putenv __P((char *));
+#endif
+
+#ifdef NEED_GETTIMEOFDAY
+extern int gettimeofday __P((struct timeval *, struct _TIMEZONE *));
+#endif
+
+#if defined(SVR4) && defined(sun)
+extern int gethostname __P((char *, size_t));
+#endif
+
+#ifdef NEED_STRDUP
+extern char *strdup __P((const char *));
+#endif
diff --git a/contrib/bind/doc/bog/00macs.me b/contrib/bind/doc/bog/00macs.me
new file mode 100644
index 0000000..8ce02a2
--- /dev/null
+++ b/contrib/bind/doc/bog/00macs.me
@@ -0,0 +1,51 @@
+.\" Copyright (c) 1986, 1988 Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms are permitted
+.\" provided that this notice is preserved and that due credit is given
+.\" to the University of California at Berkeley. The name of the University
+.\" may not be used to endorse or promote products derived from this
+.\" software without specific prior written permission. This software
+.\" is provided ``as is'' without express or implied warranty.
+.\"
+.\" @(#)00macs.me 6.3 (Berkeley) 2/28/88
+.\"
+.\" usage: troff -me myfile
+.nr EX 0
+.de BX
+.sp
+.ba +4
+.lp
+.nr EX +1
+.b
+.ta (\\n(.lu-\\n(.iu)R
+EXAMPLE \\n(EX: \(*D
+.r
+.lp
+..
+.de EX
+.br
+.ba
+.b
+.tl '''\(gr'
+.r
+.lp
+..
+.if \nl .ls 2
+.if t .nr bi 5m
+.nr si 3n
+.de $0 \" create a table of contents magically.
+.(x
+.ti (\\$3u-1u)*2m
+\\$2. \\$1
+.)x
+..
+.de $1
+.sp
+..
+.de BU
+.ip "\ \(bu" \w'\ \(bu\ 'u
+..
+.de SM
+\s-1\\$1\s0\\$2
+..
diff --git a/contrib/bind/doc/bog/00title.me b/contrib/bind/doc/bog/00title.me
new file mode 100644
index 0000000..616202b
--- /dev/null
+++ b/contrib/bind/doc/bog/00title.me
@@ -0,0 +1,94 @@
+.\" ++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--
+.\"
+.+c
+.(l C
+.sz 14
+.b "Name Server Operations Guide"
+.b "for \s-1BIND\s+1"
+.sz
+\fIRelease 4.9.4\fP
+.eh 'SMM:10-%''Name Server Operations Guide for \s-1BIND\s+1'
+.oh 'Name Server Operations Guide for \s-1BIND\s+1''\s-1SMM\s+1:10-%'
+.sp
+\fIReleases from 4.9\fP
+Paul Vixie\**
+.(f
+\** This author was employed by Digital Equipment Corporation's
+Network Systems Laboratory during the development and release of
+\s-1BIND\s+1 4.9. Release 4.9.2 was sponsored by Vixie
+Enterprises. Releases from 4.9.3 were sponsored by the Internet
+Software Consortium.
+.)f
+<paul@vix.com>
+.sp \n(psu
+Internet Software Consortium
+La Honda, CA
+.sp 2
+\fIReleases through 4.8.3\fP
+Kevin J. Dunlap\**
+Michael J. Karels
+.sp \n(psu
+Computer Systems Research Group
+Computer Science Division
+Department of Electrical Engineering and Computer Sciences
+University of California
+Berkeley, CA 94720
+.)l
+.sp 2
+.(f
+\** This author was an employee of Digital Equipment Corporation's
+\s-1ULTRIX\s+1 Engineering Advanced Development Group and was on loan to
+CSRG when this work was done. \s-1ULTRIX\s+1 is a trademark of Digital
+Equipment Corporation.
+.)f
diff --git a/contrib/bind/doc/bog/Makefile b/contrib/bind/doc/bog/Makefile
new file mode 100644
index 0000000..3cd50eb
--- /dev/null
+++ b/contrib/bind/doc/bog/Makefile
@@ -0,0 +1,90 @@
+# ++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--
+#
+# @(#)Makefile 6.3 (Berkeley) 2/28/88
+#
+FILES= 00macs.me 00title.me intro.me ns.me types.me\
+ files.me named.boot.primary\
+ named.boot.secondary named.boot.cache resolv.conf\
+ root.cache named.local ucbhosts.rev ucbhosts \
+ setup.me manage.me build.me ack.me
+ME= -me
+NROFF= nroff -rb3
+PRINTER= -Pdp
+TBL= dtbl $(PRINTER)
+TROFF= ditroff $(PRINTER)
+GROFF= groff -Tps -t $(ME)
+
+all: file.lst
+
+file.lst: $(FILES)
+ tbl $(FILES)| $(NROFF) $(ME) $(FLAGS) > file.lst
+
+file.psf: $(FILES)
+ $(GROFF) $(FILES) > file.psf
+
+troff: $(FILES)
+ $(TBL) $(FILES)| $(TROFF) $(ME) $(FLAGS)
+
+cat: $(FILES)
+ @cat $(FILES)
+
+clean:
+ rm -f *.psf *.lst *.BAK *.CKP *~ *.orig
+ rm -f file
+
+spell: $(FILES)
+ @for i in $(FILES); do \
+ echo $$i; \
+ spell $$i | sort | comm -23 - spell.ok > $$i.spell; \
+ done
diff --git a/contrib/bind/doc/bog/ack.me b/contrib/bind/doc/bog/ack.me
new file mode 100644
index 0000000..5c02c14
--- /dev/null
+++ b/contrib/bind/doc/bog/ack.me
@@ -0,0 +1,287 @@
+.\" ++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--
+.\"
+.\" @(#)ack.me
+.\"
+.sx 0
+.bp
+.ce
+.b "ACKNOWLEDGEMENTS \(em 4.9.3"
+.pp
+The \fI<bind-workers@vix.com>\fP mailing list was once again of great help;
+this release would not be nearly as ready for prime time if not for their
+efforts. Special commendations are owed to Robert Elz, Don "Truck" Lewis,
+Bob Halley, Mark Andrews, Berthold Paffrath, Ruediger Volk, and Peter Koch.
+.pp
+Digital Equipment Corporation, Hewlett Packard, Silicon Graphics, and SunSoft
+all made hardware available for integration testing; this made the release
+far more solid than it would otherwise have been. More hardware loans are
+welcome \(em if you are a system vendor and you would like \s-2BIND\s+2 to
+run ``out of the box'' on your platform and are willing to lend some rusty
+old hardware for the purpose, please contact me (\fI<paul@vix.org>\fP) to
+make the arrangements.
+.pp
+Special thanks to the Internet Software Consortium for funding this work.
+Contact \fI<isc-info@isc.org>\fP if your organization would like to
+participate in funding future releases of \s-2BIND\s+2 and other freely
+redistributable software packages that are in wide use on the Internet.
+.sp 2
+.ce
+.b "ACKNOWLEDGEMENTS \(em through 4.9"
+.pp
+The alpha-test group was extremely helpful in furnishing improvements,
+finding and repairing bugs, and being patient. I would like to express
+special thanks to Brian Reid of Digital Equipment corporation for funding
+this work. Robert Elz, Alan Barrett, Paul Albitz, Bryan Beecher, Andrew
+Partan, Andy Cherenson, Tom Limoncelli, Berthold Paffrath, Fuat Baran, Anant
+Kumar, Art Harkin, Win Treese, Don Lewis, Christophe Wolfhugel, and a cast
+of dozens all helped out above and beyond the call of duty. Special thanks
+to Phil Almquist, who got the project started and contributed a lot of the
+code and fixed several of the worst bugs.
+.sp 2
+.ce
+.b "ACKNOWLEDGEMENTS \(em through 4.8.3"
+.pp
+Many thanks to the users at U. C. Berkeley for falling into many of the holes
+involved with integrating BIND into the system so that others would be
+spared the trauma. I would also like to extend gratitude to Jim McGinness
+and Digital Equipment Corporation for permitting me to spend most of my time
+on this project.
+.pp
+Ralph Campbell, Doug Kingston, Craig Partridge, Smoot Carl-Mitchell, Mike
+Muuss and everyone else on the DARPA Internet who has contributed to the
+development of BIND. To the members of the original BIND project, Douglas
+Terry, Mark Painter, David Riggle and Songnian Zhou.
+.pp
+Anne Hughes, Jim Bloom and Kirk McKusick and the many others who have
+reviewed this paper giving considerable advice.
+.pp
+This work was sponsored by the Defense Advanced Research Projects Agency
+(DoD), Arpa Order No. 4871 monitored by the Naval Electronics Systems
+Command under contract No. N00039-84-C-0089. The views and conclusions
+contained in this document are those of the authors and should not be
+interpreted as representing official policies, either expressed or implied,
+of the Defense Research Projects Agency, of the US Government, or of Digital
+Equipment Corporation.
+.bp
+.ba 0
+.in 0
+.sp 2
+.ce
+.b REFERENCES
+.sp
+.nr ii 1i
+.ip [Birrell]
+Birrell, A. D.,
+Levin, R.,
+Needham, R. M.,
+and Schroeder, M.D.,
+.q "Grapevine: An Exercise in Distributed Computing."
+In
+.ul
+Comm. A.C.M. 25,
+4:260-274
+April 1982.
+.ip [RFC819]
+Su, Z.
+Postel, J.,
+.q "The Domain Naming Convention for Internet User Applications."
+.ul
+Internet Request For Comment 819
+Network Information Center,
+SRI International,
+Menlo Park, California.
+August 1982.
+.ip [RFC974]
+Partridge, C.,
+.q "Mail Routing and The Domain System."
+.ul
+Internet Request For Comment 974
+Network Information Center,
+SRI International,
+Menlo Park, California.
+February 1986.
+.ip [RFC1032]
+Stahl, M.,
+.q "Domain Administrators Guide"
+.ul
+Internet Request For Comment 1032
+Network Information Center,
+SRI International,
+Menlo Park, California.
+November 1987.
+.ip [RFC1033]
+Lottor, M.,
+.q "Domain Administrators Guide"
+.ul
+Internet Request For Comment 1033
+Network Information Center,
+SRI International,
+Menlo Park, California.
+November 1987.
+.ip [RFC1034]
+Mockapetris, P.,
+.q "Domain Names - Concept and Facilities."
+.ul
+Internet Request For Comment 1034
+Network Information Center,
+SRI International,
+Menlo Park, California.
+November 1987.
+.ip [RFC1035]
+Mockapetris, P.,
+.q "Domain Names - Implementation and Specification."
+.ul
+Internet Request For Comment 1035
+Network Information Center,
+SRI International,
+Menlo Park, California.
+November 1987.
+.ip [RFC1101]
+Mockapetris, P.,
+.q "DNS Encoding of Network Names and Other Types."
+.ul
+Internet Request For Comment 1101
+Network Information Center,
+SRI International,
+Menlo Park, California.
+April 1989.
+.ip [RFC1123]
+R. Braden, Editor,
+.q "Requirements for Internet Hosts -- Application and Support"
+.ul
+Internet Request For Comment 1123
+Network Information Center,
+SRI International,
+Menlo Park, California.
+October 1989.
+.ip [RFC1183]
+Everhart, C.,
+Mamakos, L.,
+Ullmann, R.,
+and
+Mockapetris, P.,
+.q "New DNS RR Definitions"
+.ul
+Internet Request For Comment 1183
+Network Information Center,
+SRI International,
+Menlo Park, California.
+October 1990.
+.ip [RFC1327]
+Hardcastle-Kille, S.,
+.q "Mapping between X.400(1988) / ISO 10021 and RFC 822"
+.ul
+Internet Request For Comment 1327
+Network Information Center,
+SRI International,
+Menlo Park, California.
+May 1992.
+.ip [RFC1664]
+Allocchio, C.,
+Bonito, A.,
+Cole, B.,
+Giordano, S.,
+Hagens, R.,
+.q "Using the Internet DNS to Distribute RFC1327 Mail Address Mapping Tables"
+.ul
+Internet Request For Comment 1664
+Network Information Center,
+SRI International,
+Menlo Park, California.
+August 1994.
+.ip [RFC1713]
+Romao, A.,
+.q "Tools for DNS debugging"
+.ul
+Internet Request For Comment 1713, also FYI27
+Network Information Center,
+SRI International,
+Menlo Park, California.
+November 1994.
+.ip [Terry]
+Terry, D. B.,
+Painter, M.,
+Riggle, D. W.,
+and
+Zhou, S.,
+.ul
+The Berkeley Internet Name Domain Server.
+Proceedings USENIX Summer Conference,
+Salt Lake City, Utah.
+June 1984, pages 23-31.
+.ip [Zhou]
+Zhou, S.,
+.ul
+The Design and Implementation of the Berkeley Internet Name Domain (BIND) Servers.
+UCB/CSD 84/177.
+University of California, Berkeley,
+Computer Science Division.
+May 1984.
+.ip [Mockapetris]
+Mockapetris, P.,
+Dunlap, K,
+.ul
+Development of the Domain Name System
+ACM Computer Communications Review 18, 4:123-133.
+Proceedings ACM SIGCOMM '88 Symposium,
+August 1988.
+.ul
+.ip [Liu]
+Liu, C.,
+Albitz, P.,
+.ul
+DNS and BIND
+O'Reilly & Associates, Sebastopol, CA,
+502 pages, ISBN 0-937175-82-X
+1992
diff --git a/contrib/bind/doc/bog/build.me b/contrib/bind/doc/bog/build.me
new file mode 100644
index 0000000..d6dab9f
--- /dev/null
+++ b/contrib/bind/doc/bog/build.me
@@ -0,0 +1,102 @@
+.\" ++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--
+.\"
+.\" @(#)build.me 6.3 (Berkeley) 9/19/89
+.\"
+.sh 1 "Building a System with a Name Server"
+.pp
+BIND is composed of two parts. One is the user interface called the
+\fIresolver\fP
+which consists of a group of routines that reside in the C library
+\fI/lib/libc.a\fP.
+Second is the actual server called \fInamed\fP.
+This is a daemon that runs in the background and services queries on a
+given network port. The standard port for UDP and TCP is specified in
+\fI/etc/services\fP.
+.sh 2 "Resolver Routines in libc"
+.pp
+When building your 4.3BSD system you may either
+build the C library to use the name server resolver routines
+or use the host table lookup routines to do host name and address resolution.
+The default resolver for 4.3BSD uses the name server. Newer BSD systems
+include both name server and host table functionality with preference given
+to the name server if there is one or if there is a \fI/etc/resolv.conf\fP
+file.
+.pp
+Building the C library to use the name server changes the way
+\fIgethostbyname\fP\|(3N), \fIgethostbyaddr\fP\|(3N), and
+\fIsethostent\fP\|(3N) do their functions. The name server renders
+\fIgethostent\fP\|(3N) obsolete, since it has no concept of a next line in
+the database. These library calls are built with the resolver routines
+needed to query the name server.
+.pp
+The \fIresolver\fP contains functions that build query
+packets and exchange them with name servers.
+.pp
+Before building the 4.3BSD C library, set the variable \fIHOSTLOOKUP\fP
+equal to \fInamed\fP in \fI/usr/src/lib/libc/Makefile\fP. You
+then make and install the C library and compiler and then compile the rest
+of the 4.3BSD system. For more information see section 6.6 of ``Installing
+and Operating 4.3BSD on the VAX\(dd''.
+.(f
+\(ddVAX is a Trademark of Digital Equipment Corporation
+.)f
+.pp
+If your operating system isn't VAX\(dd 4.3BSD, it is probably the case that
+your vendor has included \fIresolver\fP support in the supplied C Library.
+You should consult your vendor's documentation to find out what has to be
+done to enable \fIresolver\fP support. Note that your vendor's \fIresolver\fP
+may be out of date with respect to the one shipped with \s-1BIND\s+1, and that
+you might want to build \s-1BIND\s+1's resolver library and install it, and
+its include files, into your system's compile/link path so that your own
+network applications will be able to use the newer features.
diff --git a/contrib/bind/doc/bog/files.me b/contrib/bind/doc/bog/files.me
new file mode 100644
index 0000000..4a28da4
--- /dev/null
+++ b/contrib/bind/doc/bog/files.me
@@ -0,0 +1,1150 @@
+.\" ++Copyright++ 1986, 1988, 1995
+.\" -
+.\" Copyright (c) 1986, 1988, 1995
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\" -
+.\" Portions Copyright (c) 1993 by Digital Equipment Corporation.
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies, and that
+.\" the name of Digital Equipment Corporation not be used in advertising or
+.\" publicity pertaining to distribution of the document or software without
+.\" specific, written prior permission.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
+.\" WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
+.\" OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
+.\" CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+.\" DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+.\" PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+.\" ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+.\" SOFTWARE.
+.\" -
+.\" --Copyright--
+.\"
+.\" @(#)files.me 6.8 (Berkeley) 9/19/89
+.\"
+.sh 1 "Files
+.pp
+The name server uses several files to load its data base.
+This section covers the files and their formats needed for \fInamed\fP.
+.sh 2 "Boot File"
+.pp
+This is the file that is first read when \fInamed\fP starts up.
+This tells the server what type of server it is,
+which
+zones it has authority over and where to get its initial data.
+The default location for this file is \fI/etc\|/named.boot\fP\|.
+However this can be changed
+by setting the \fIBOOTFILE\fP variable when you compile \fInamed\fP
+or by specifying
+the location on the command line when \fInamed\fP is started up.
+.sh 3 "Domain"
+.pp
+A default domain may be specified for the name server
+using a line such as
+.(b l
+.ta 0.5i +\w`secondary `u +\w`berkeley.edu `u +.5i +.5i
+\fIdomain Berkeley\fP\fB\|.\|\fP\fIEdu\fP
+.)b
+.re
+Older name servers use this information when they receive a query for a name
+without a ``\fB.\fP'' that is not known. Newer designs assume that the
+resolver library will append its own idea of a ``default domain'' to any
+unqualified names. Though the name server can still be compiled with
+support for the \fIdomain\fP directive in the boot file, the default is to
+leave it out and we strenuously recommend against its use. If you use this
+feature, clients outside your local domain which send you requests about
+unqualified names will have the implicit qualification of your domain rather
+than theirs. The proper place for this function is on the client, in their
+\fB/etc/resolv.conf\fP (or equivalent) file. Use of the \fIdomain\fP
+directive in your boot file is strongly discouraged.
+.sh 3 "Directory"
+.pp
+The \fIdirectory\fP directive specifies the directory in which the name server
+should run, allowing the other file names in the boot file to use relative path
+names. There can be only one \fIdirectory\fP directive and it should be given
+before any other directives that specify file names.
+.(b l
+.ta 0.5i +\w`secondary `u +\w`berkeley.edu `u +.5i +.5i
+\fIdirectory /var/named\fP
+.)b
+.re
+If you have more than a couple of named files to be maintained, you may wish
+to place the named files in a directory such as /var/named and adjust the
+directory command properly. The main purposes of this command are to make
+sure named is in the proper directory when trying to include files by
+relative path names with $INCLUDE and to allow named to run in a location
+that is reasonable to dump core if it feels the urge.
+.sh 3 "Primary Service"
+.pp
+The line in the boot file that designates the server as a primary master server
+for a zone looks as follows:
+.(b l
+.ta 0.5i +\w`secondary `u +\w`berkeley.edu `u +.5i +.5i
+\fIprimary Berkeley\fP\fB\|.\|\fP\fIEdu ucbhosts\fP
+.)b
+.re
+The first field specifies that the server is a primary one for the zone
+stated in the second field.
+The third field is the name of the file from which the data is read.
+.pp
+The above assumes that the zone you are specifying is a class \fIIN\fP
+zone. If you wish to designate a different class you can append
+\fI/class\fP to the first field, where \fIclass\fP is either the
+integer value or the standard mnemonic for the class. For example the line
+for a primary server for a hesiod class zone looks as follows:
+.(b l
+.ta 0.5i +\w`secondary `u +\w`berkeley.edu `u +.5i +.5i
+\fIprimary/HS Berkeley\fP\fB\|.\|\fP\fIEdu hesiod.data\fP
+.)b
+.re
+Note that this support for specifying other than class \fIIN\fP zones is a
+compile-time option which your vendor may not have enabled when they built
+your operating system.
+.sh 3 "Secondary Service"
+.pp
+The line for a secondary server is similar to the primary except
+that it lists addresses of other servers (usually primary servers)
+from which the zone data will be obtained.
+.(b l
+.ta 0.5i +\w`secondary `u +\w`berkeley.edu `u +\w`128.32.0.10 `u +\w`128.32.0.10 `u +.5i +.5i
+\fIsecondary Berkeley\fP\fB\|.\|\fP\fIEdu 128\fP\fB.\fP\fI32\fP\fB.\fP\fI0\fP\fB.\fP\fI10 \fP\fI128\fP\fB.\fP\fI32\fP\fB.\fP\fI0\fP\fB.\fP\fI4\fP \fIucbhosts.bak\fP
+.)b
+.re
+The first field specifies that the server is a secondary server for
+the zone stated in the second field.
+The two network addresses specify the name servers which have data for the
+zone. Note that at least one of these will be a \fIprimary\fP, and, unless
+you are using some protocol other than \s-1IP/DNS\s+1 for your zone transfer
+mechanism, the others will all be other \fIsecondary\fP servers. Having your
+secondary server pull data from other secondary servers is usually unwise,
+since you can add delay to the propagation of zone updates if your network's
+connectivity varies in pathological but common ways. The intended use for
+multiple addresses on a \fIsecondary\fP declaration is when the \fIprimary\fP
+server has multiple network interfaces and therefore multiple host addresses.
+The secondary server gets its data across the network from one of the listed
+servers. The server addresses are tried in the order listed.
+If a filename is present after the list of primary servers, data for the zone
+will be dumped into that file as a backup.
+When the server is first started, the data is loaded from the backup file
+if possible, and a primary server is then consulted to check that the zone
+is still up-to-date. Note that listing your server as a \fIsecondary\fP
+server does not necessarily make it one \(em the parent zone must
+\fIdelegate\fP authority to your server as well as the primary and the
+other secondaries, or you will be transferring a zone over for no reason;
+no other server will have a reason to query you for that zone unless the
+parent zone lists you as a server for the zone.
+.pp
+As with primary you may specify a secondary server for a class other than
+\fIIN\fP by appending \fI/class\fP to the \fIsecondary\fP keyword, e.g.,
+\fIsecondary/HS\fP.
+.sh 3 "Stub Service"
+.pp
+The line for a stub server is similar to a secondary.
+(This feature is experimental as of 4.9.3.)
+.(b l
+.ta 0.5i +\w`stub `u +\w`berkeley.edu `u +\w`128.32.0.10 `u +\w`128.32.0.10 `u +.5i +.5i
+\fIstub Berkeley\fP\fB\|.\|\fP\fIEdu 128\fP\fB.\fP\fI32\fP\fB.\fP\fI0\fP\fB.\fP\fI10 \fP\fI128\fP\fB.\fP\fI32\fP\fB.\fP\fI0\fP\fB.\fP\fI4\fP \fIucbhosts.bak\fP
+.)b
+.re
+The first field specifies that the server is a stub server for the zone stated
+in the second field.
+.pp
+Stub zones are intended to ensure that a primary for a zone always has the
+correct \fINS\fP records for children of that zone. If the primary is not
+a secondary for a child zone it should be configured with stub zones for
+all its children. Stub zones provide a mechanism to allow \fINS\fP records
+for a zone to be specified in only one place.
+.(b l
+.ta 0.5i +\w`primary `u +\w`dms.csiro.au `u +\w`130.155.98.1 `u +.5i +.5i
+\fIprimary CSIRO\fP\fB\|.\|\fP\fIAU \fIcsiro.dat\fP
+\fIstub dms.CSIRO\fP\fB\|.\|\fP\fIAU 130\fP\fB.\fP\fI155\fP\fB.\fP\fI16\fP\fB.\fP\fI1 \fIdms.stub\fP
+\fIstub dap.CSIRO\fP\fB\|.\|\fP\fIAU 130\fP\fB.\fP\fI155\fP\fB.\fP\fI98\fP\fB.\fP\fI1 \fIdap.stub\fP
+.)b
+.re
+.sh 3 "Cache Initialization"
+.pp
+All servers, including ``caching only'' servers, should have a line as
+follows in the boot file to prime the name servers cache:
+.(b l
+\fIcache \fP\fB.\fP\fI root\fP\fB.\fP\fIcache\fP
+.)b
+Do not put anything into your \fIcache\fP files other than root server
+information.
+.pp
+All cache files listed will be read in at named boot time and any values
+still valid will be reinstated in the cache.
+The root name server
+information in the cache files will be used until a root query is
+actually answered by one of the name servers in the cache file, after
+which that answer will be used instead of the cache file until the answer
+times out.
+.pp
+As with \fIprimary\fP and \fIsecondary\fP, you may specify a secondary
+server for a class other than \fIIN\fP by appending \fI/class\fP to the
+\fIcache\fP keyword, e.g., \fIclass/HS\fP.
+.sh 3 "Forwarders"
+.pp
+Any server can make use of \fIforwarders\fP. A \fIforwarder\fP is another
+server capable of processing recursive queries that is willing to try
+resolving queries on behalf of other systems. The \fIforwarders\fP
+command specifies forwarders by internet address as follows:
+.(b l
+\fIforwarders \fI128\fP\fB.\fP\fI32\fP\fB.\fP\fI0\fP\fB.\fP\fI10 \fP\fI128\fP\fB.\fP\fI32\fP\fB.\fP\fI0\fP\fB.\fP\fI4\fP
+.)b
+.re
+There are two main reasons for wanting to do so. First, some systems may
+not have full network access and may be prevented from sending any IP
+packets into the rest of the Internet and therefore must rely on a forwarder
+which does have access to the full net. The second reason is that the
+forwarder sees a union of all queries as they pass through its server and
+therefore it builds up a very rich cache of data compared to the cache in a
+typical workstation name server. In effect, the \fIforwarder\fP becomes a
+meta-cache that all hosts can benefit from, thereby reducing the total
+number of queries from that site to the rest of the net.
+.pp
+The effect of ``forwarders'' is to prepend some fixed addresses to the list
+of name servers to be tried for every query. Normally that list is made up
+only of higher-authority servers discovered via \fINS\fP record lookups for
+the relevant domain. If the forwarders do not answer, then unless the
+\fIslave\fP directive was given, the appropriate servers for the domains
+will be queried directly.
+
+.sh 3 "Slave Servers"
+.pp
+Slave mode is used if the use of forwarders is the only possible way
+to resolve queries due to lack of full net access or if you wish to prevent
+the name server from using other than the listed forwarders.
+Slave mode is activated by placing the simple command
+.(b l
+\fIoptions forward-only\fP
+.)b
+in the bootfile. If this option is used, then you must specify forwarders.
+When in slave mode, the server will forward each query to each of the the
+forwarders until an answer is found or the list of forwarders is exhausted.
+The server will not try to contact any remote name server other than those
+named in the \fIforwarders\fP list.
+.pp
+So while \fIforwarders\fP prepends addresses to the ``server list'' for each
+query, \fIoptions forward-only\fP causes the ``server list'' to contain
+\fIonly\fP those addresses listed in the \fIforwarders\fP declarations.
+Careless use of the \fIoptions forward-only\fP directive can cause really
+horrible forwarding loops, since
+you could end up forwarding queries only to some set of hosts which are also
+slaves, and one or several of them could be forwarding queries back to you.
+.pp
+Use of the \fIoptions forward-only\fP directive should be considered very
+carefully. Note that this same behaviour can be achieved using the deprecated
+directive, \fIslave\fP.
+
+.sh 3 "Nonrecursive Servers"
+.pp
+\s-1BIND\s+1's separation of authoritative (zone) and nonauthoritiative (cache)
+data has always been somewhat weak, and pollution of the former via the latter
+has been known to occur. One way to prevent this, as well as to save memory on
+servers carrying a lot of authoritative data (e.g., root servers) is to make
+such servers ``nonrecursive.'' This can be achieved via the directive
+.(b l
+\fIoptions no-recursion\fP
+.)b
+in the bootfile. A server with this option enabled will not attempt to fetch
+data to help answer queries \(em if you ask it for data it does not have, it
+will send you a referral to a more authoritative server or, if it is itself
+authoritative for the zone of the query, it will send you an negative answer.
+.pp
+A nonrecursive server can be named in an \s-1NS\ RR\s+1 but it cannot be listed
+in the \fIresolv.conf\fP file.
+
+.sh 3 "Query Logging"
+.pp
+If the file system containing your \fIsyslog\fP file has quite a bit of space,
+you can consider using the
+.(b l
+\fIoptions query-log\fP
+.)b
+directive in your bootfile. This will cause your name server to log every
+query it receives, which when combined with a Perl or \s-1AWK\s+1 script to
+postprocess the logs, can be a useful management tool.
+
+.sh 3 "Inverse Query Pseudosupport"
+.pp
+\s-1BIND\s+1 by default does not support inverse queries, and this has been
+known to cause problems for certain microcomputer operating systems and for
+older versions of \s-1BIND\s+1's \fInslookup\fP tool. You may decide that
+rather than answering with ``operation not implemented,'' \fInamed\fP should
+detect the most common inverse queries and answer them with bogus information.
+It is better to upgrade your clients to stop depending on inverse queries, but
+if that is not possible, you should use the
+.(b l
+\fIoptions fake-iquery\fP
+.)b
+directive in your bootfile. \fINOTE:\fP the responses are in fact bogus, in
+that they contain \s-1ISO\s+18859 square brackets (\fB[\fP and \fB]\fP), so
+your clients will not be able to do anything useful with these responses. It
+has been observed that no client ever did anything useful with real inverse
+query responses, either.
+
+.sh 3 "Setting Name Server Limits"
+.pp
+Some name server operations can be quite resource intensive, and in order to
+tune your system properly it is sometimes necessary to change \s-1BIND\s+1's
+internal quotas. This is accomplished via
+.(b l
+\fIlimit <name> <value>\fP
+.)b
+directives in the bootfile. Limits, and their default values, are as follows:
+.(b I
+\fIlimit transfers-in 10\fP
+.)b
+This is the number of simultaneous \fInamed-xfer\fP processes \s-1BIND\s+1 is
+willing to start. Higher numbers yield faster convergence to primary servers
+if your secondary server has hundreds or thousands of zones to maintain, but
+setting this number too high can cause thrashing due to starvation of resources
+such as network bandwidth or swap space. \fINOTE:\fP this limit can also be
+expressed via the deprecated directive \fImax-fetch NN\fP.
+.(b I
+\fIlimit transfers-per-ns 2\fP
+.)b
+This is the number of simultaneous \fInamed-xfer\fP processes \s-1BIND\s+1 is
+willing to initiate \fIto any given name server\fP. In most cases, you should
+not need to change it. If your secondary server is pulling hundreds or
+thousands of zones from a single primary server, increasing
+\fItransfers-per-ns\fP may speed convergence. It should be kept as
+small as possible, to avoid causing thrashing and resource starvation
+on the primary server.
+.(b I
+\fIlimit datasize <system-dependent>\fP
+.)b
+Most systems have a quota that limits the size of the so-called ``data
+segment,'' which is where \s-1BIND\s+1 keeps all of its authority and cache
+data. \s-1BIND\s+1 will behave suboptimally (perhaps even exiting) if it runs
+up against this quota. If your system supports a system call to change this
+quota for a given process, you can ask \s-1BIND\s+1 to use that system call
+via the \fIlimit datasize NN\fP directive. The value given here may be scaled
+by postfixing \fIk\fP for 1024X, \fIm\fP for (1024^2)X, and \fIg\fP for
+(1024^3)X. In 1995, the root servers all use \fIlimit datasize 64m\fP.
+
+.sh 3 "Zone Transfer Restrictions"
+.pp
+It may be the case that your organization does not wish to give complete
+lists of your hosts to anyone on the Internet who can reach your name servers.
+While it is still possible for people to ``iterate'' through your address
+range, looking for \fIPTR\fP records, and build a list of your hosts the
+``slow'' way, it is still considered reasonable to restrict your export of
+zones via the zone transfer protocol. To limit the list of neighbors who
+can transfer zones from your server, use the \fIxfrnets\fP directive.
+.pp
+This directive has the same syntax as \fIforwarders\fP except that you can
+list network numbers in addition to host addresses. For example, you could
+add the directive
+.(b l
+\fIxfrnets 16.0.0.0\fP
+.)b
+.re
+if you wanted to permit only hosts on Class A network number 16 to transfer
+zones from your server. This is not nearly granular enough, and a future
+version of \s-1BIND\s+1 will permit such access-control to be specified on a
+per-host basis rather than the current per-net basis. Note that while
+addresses without explicit masks are assumed by this directive to be networks,
+you can specify a mask which is as granular as you wish, perhaps including
+all bits of the address such that only a single host is given transfer
+permission. For example, consider
+.(b l
+\fIxfrnets 16.1.0.2&255.255.255.255\fP
+.)b
+which would permit only host \fI16.1.0.2\fP to transfer zones from you. Note
+that no spaces are allowed surrounding the ``\fI&\fP'' character that
+introduces a netmask.
+.pp
+The \fIxfrnets\fP directive may also be given as \fItcplist\fP for
+compatibility with interim releases of \s-1BIND\s+1 4.9.
+
+.sh 3 "Sorting Addresses"
+.pp
+If there are multiple addresses available for a name server which \s-1BIND\s+1
+wants to contact, \s-1BIND\s+1 will try the ones it believes are ``closest''
+first. ``Closeness'' is defined in terms of similarity-of-address; that is,
+if one address is on the same \fIsubnet\fP as some interface of the local host,
+then that address will be tried first. Failing that, an address which is on
+the same \fInetwork\fP will be tried first. Failing that, they will be tried
+in a more-or-less random order unless the \fIsortlist\fP directive was given
+in the \fInamed.boot\fP file. \fIsortlist\fP has a syntax similar to
+\fIforwarders\fP, \fIxfrnets\fP, and \fIbogusns\fP \(em you give it a list
+of dotted-quad networks and it uses these to ``prefer'' some remote name server
+addresses over others. If no explicit mask is provided with each element of
+a \fIsortlist\fP, one will be inferred based on the high order address bits.
+.pp
+If you are on a Class C net which has a Class B net between you and the rest
+of the Internet, you could try to improve the name server's luck in getting
+answers by listing the Class B network's number in a \fIsortlist\fP
+directive. This should have the effect of trying ``closer'' servers before
+the more ``distant'' ones. Note that this behaviour is new as of \s-1BIND
+4.9\s+1.
+.pp
+The other and older effect of the \fIsortlist\fP directive is to cause
+\s-1BIND\s+1 to sort the \fIA\fP records in any response it generates, so as
+to put those which appear on the \fIsortlist\fP earlier than those which do
+not. This is not as helpful as you might think, since many clients will
+reorder the \fIA\fP records either at random or using \s-1LIFO\s+1; also,
+consider the fact that the server won't be able to guess the client's network
+topology, and so will not be able to accurately order for ``closeness'' to
+all possible clients. Doing the ordering in the resolver is clearly superior.
+.pp
+In actual practice, this directive is used only rarely since it hardwires
+information which changes rapidly; a network which is ``close'' today may
+be ``distant'' next month. Since \s-1BIND\s+1 builds up a cache of the
+remote name servers' response times, it will quickly converge on
+``reasonable'' behaviour, which isn't the same as ``optimal'' but it's
+close enough. Future directions for \s-1BIND\s+1 include choosing
+addresses based on local interface metrics (on hosts that have more than
+one) and perhaps on routing table information. We do not intend to solve
+the generalized ``multihomed host'' problem, but we should be able to do a
+little better than we're doing now. Likewise, we hope to see a higher
+level resolver library that sorts responses using topology information that
+only exists on the client's host.
+
+.sh 3 "Bogus Name Servers"
+.pp
+It happens occasionally that some remote name server goes ``bad''. You can
+tell your name server to refuse to listen to or ask questions of certain
+other name servers by listing them in a \fIbogusns\fP directive in your
+\fInamed.boot\fP file. Its syntax is the same as \fIforwarders\fP,
+\fIxfrnets\fP, and \fIsortlist\fP \(em you just give it a list of dotted-quad
+Internet addresses. Note that zones delegated to such servers will not be
+reachable from clients of your servers; thus you should use this directive
+sparingly or not at all.
+
+.sh 3 "Segmented Boot Files"
+.pp
+If you are secondary for a lot of zones, you may find it convenient to split
+your \fInamed.boot\fP file into a static portion which hardly ever changes
+(directives such as \fIdirectory\fP, \fIsortlist\fP, \fIxfrnets\fP and
+\fIcache\fP could go here), and dynamic portions that change frequently
+(all of your \fIprimary\fP directives might go in one file, and all of your
+\fIsecondary\fP directives might go in another file \(em and either or both
+of these might be fetched automatically from some neighbor so that they can
+change your list of secondary zones without requiring your active
+intervention). You can accomplish this via the \fIinclude\fP directive,
+which takes just a single file name as its argument. No quotes are needed
+around the file name. The file name will be evaluated after the name server
+has changed its working directory to that specified in the \fIdirectory\fP
+directive, so you can use relative pathnames if your system supports them.
+
+.sh 2 "Resolver Configuration"
+.pp
+The configuration file's name is \fI/etc/resolv.conf\fP.
+This file designates the name servers on the network that should
+be sent queries.
+The resolver will try to contact a name server on the localhost if it cannot
+find its configuration file. You should install the configuration file
+on every host anyway, since this is the only recommended way to specify a
+system-level default domain, and you can still list the local host's address
+if it runs a name server.
+It is considered reasonable to create this file even if you run a local
+server, since its contents will be cached by each client of the resolver
+library when the client makes its first call to a resolver routine.
+.pp
+The \fIresolv.conf\fP file contains directives, one per line, of the
+following forms:
+.(l I
+; comment
+# another comment
+domain \fIlocal-domain\fP
+search \fIsearch-list\fP
+nameserver \fIserver-address\fP
+sortlist \fIsort-list\fP
+options \fIoption-list\fP
+.)l
+Exactly one of the \fIdomain\fP or \fIsearch\fP directives should be given,
+exactly once.
+If the \fIsearch\fP directive is given, the first item in the given
+\fIsearch-list\fP will override any previously-specified \fIlocal-domain\fP.
+The \fInameserver\fP directive may be given up to three times; additional
+\fInameserver\fP directives will be ignored. Comments may be given by
+starting a line with a ``\fB\|;\|\fP'' or ``\fB\|#\|\fP''; note that
+comments were not permitted in versions of the resolver earlier than the one
+included with \s-1BIND 4.9\s+1 \(em so if your vendor's resolver supports
+comments, you know they are really on the ball.
+.pp
+The \fIlocal-domain\fP will be appended to any query-name that does not
+contain a ``\fB\|.\|\fP''. \fIlocal-domain\fP can be overridden on a
+per-process basis by setting the \s-1LOCALDOMAIN\s+1 environment variable.
+Note that \fIlocal-domain\fP processing can be disabled by setting an
+option in the resolver.
+.pp
+The \fIsearch-list\fP is a list of domains which are tried, in order,
+as qualifying domains for query-names which do not contain a ``\fB\|.\|\fP''.
+Note that \fIsearch-list\fP processing can be disabled by setting an
+option in the resolver. Also note that the environment variable
+``\s-1LOCALDOMAIN\s+1'' can override this \fIsearch-list\fP on a per-process
+basis.
+.pp
+The \fIserver-address\fP\|'s are aggregated and then used as the default
+destination of queries generated through the resolver. In other words,
+this is the way you tell the resolver which name servers it should use. It
+is possible for a given client application to override this list, and this
+is often done inside the name server (which is itself a \fIresolver\fP
+client) and in test programs such as \fInslookup\fP.
+Note that if you wish to list the
+local host in your resolver configuration file, you should probably use its
+primary Internet address rather than a local-host alias such as 127.0.0.1 or
+0.0.0.0. This is due to a bug in the handling of connected \s-1SOCK_DGRAM\s+1
+sockets in some versions of the \s+1BSD\s-1 networking code. If you must use
+an address-alias, you should prefer 0.0.0.0 (or simply ``0'') over 127.0.0.1,
+though be warned that depending on the vintage of your \s-1BSD\s+1-derived
+networking code, both of them are capable of failing in their own ways.
+If your host's IP
+implementation does not create a short-circuit route between the default
+interface and the loopback interface, then you might also want to add a
+static route (eg. in \fB/etc/rc.local\fP) to do so:
+.(b l
+\fIroute add myhost.domain.name localhost 1\fP
+.)b
+.pp
+The \fIsort-list\fP is a list of IP address, netmask pairs. Addresses
+returned by gethostbyname are sorted to the order specified by this list.
+Any addresses that do not match the address netmask pair will be returned
+after those that do. The netmask is optional and the natural netmask will be
+used if not specified.
+.pp
+The \fIoption-list\fP is a list of options which each override some internal
+resolver variable. Supported options at this time are:
+.ip \fBdebug\fP
+sets the \s-1RES_DEBUG\s+1 bit in \fB_res.options\fP.
+.ip \fBndots:\fP\fIn\fP
+sets the lower threshold (measured in ``number of dots'') on names given to
+\fIres_query\fP() such that names with more than this number of dots will be
+tried as absolute names before any \fIlocal-domain\fP or \fIsearch-list\fP
+processing is done. The default for this internal variable is ``1''.
+.\" .pp
+.\" Finally, if the environment variable \s-1HOSTALIASES\s+1 is set, it is
+.\" taken to contain the name of a file which in turn contains resolver-level
+.\" aliases. These aliases are applied only to names which do not contain any
+.\" ``\fB\|.\|\fP'' characters, and they are applied to query-names before the
+.\" query is generated. Note that the resolver options governing the operation
+.\" of \fIlocal-domain\fP and \fIsearch-list\fP do not apply to
+.\" \s-1HOSTALIASES\s+1.
+
+.sh 2 "Cache Initialization File"
+.sh 3 root.cache
+.pp
+The name server needs to know the servers that are the authoritative name
+servers for the root domain of the network. To do this we have to prime the
+name server's cache with the addresses of these higher authorities. The
+location of this file is specified in the boot file. This file uses the
+Standard Resource Record Format (aka. Masterfile Format) covered further on
+in this paper.
+
+.sh 2 "Domain Data Files"
+.pp
+There are two standard files for specifying the data for a
+domain. These are \fIhosts\fP and \fIhost.rev\fP.
+These files use the Standard Resource Record Format covered later
+in this paper. Note that the file names are arbitrary; many network
+administrators prefer to name their zone files after the domains they
+contain, especially in the average case which is where a given server
+is primary and/or secondary for many different zones.
+.sh 3 hosts
+.pp
+This file contains all the data about the machines in this zone.
+The location of this file is specified in the boot file.
+.sh 3 hosts.rev
+.pp
+This file specifies the IN-ADDR\|.\|ARPA domain.
+This is a special domain for allowing address to name mapping.
+As internet host addresses do not fall within domain boundaries,
+this special domain was formed to allow inverse mapping.
+The IN-ADDR\|.\|ARPA domain has four
+labels preceding it. These labels correspond to the 4 octets of
+an Internet address.
+All four octets must be specified even if an octet contains zero.
+The Internet address 128.32.0.4 is located in the domain
+4\|.\|0\|.\|32\|.\|128\|.\|IN-ADDR\|.\|ARPA.
+This reversal of the address is awkward to read but allows
+for the natural grouping of hosts in a network.
+.sh 3 named.local
+.pp
+This file specifies the \fIPTR\fP record for the local loopback interface,
+better known as \fIlocalhost\fP, whose network address is 127.0.0.1. The
+location of this file is specified in the boot file. It is vitally
+important to the proper operation of every name server that the 127.0.0.1
+address have a \fIPTR\fP record pointing back to the name
+``\fBlocalhost.\fP''. The name of this \fIPTR\fP record is always
+``\fB1.0.0.127.\s-1IN-ADDR.ARPA\s+1\fP''. This is necessary if you want
+your users to be able to use hostname-authentication (\fIhosts.equiv\fP or
+\fI~/.rhosts\fP) on the name ``\fBlocalhost\fP''. As implied by this
+\fIPTR\fP record, there should be a ``\fBlocalhost.\fP\fImy.dom.ain\fP''
+\fIA\fP record (with address 127.0.0.1) in every domain that contains hosts.
+``\fBlocalhost.\fP'' will lose its trailing dot when
+\fB1.0.0.127.in-addr.arpa\fP is queried for; then, the DEFNAMES and/or
+DNSRCH resolver options will cause ``\fBlocalhost\fP'' to be evaluated as a
+host name in the local domain, and that means the top domains (or ideally,
+every domain) in your resolver's search path had better have something by
+that name.
+.sh 2 "Standard Resource Record Format"
+.pp
+The records in the name server data files are called resource records.
+The Standard Resource Record Format (RR) is specified in RFC1035.
+The following is a general description of these records:
+.TS
+l l l l l.
+\fI{name} {ttl} addr-class Record Type Record Specific data\fP
+.TE
+Resource records have a standard format shown above.
+The first field is always the name of the domain record
+and it must always start in column 1.
+For all RR's other than the first in a file, the name may be left blank;
+in that case it takes on the name of the previous RR.
+The second field is an optional time to live field.
+This specifies how long this data will be stored in the data base.
+By leaving this field blank the default time to live is specified
+in the \fIStart Of Authority\fP resource record (see below).
+The third field is the address class; currently, only one class is supported:
+\fIIN\fP for internet addresses and other internet information. Limited
+support is included for the \fIHS\fP class, which is for MIT/Athena ``Hesiod''
+information.
+The fourth field states the type of the resource record.
+The fields after that are dependent on the type of the RR.
+Case is preserved in names and data fields when loaded into the name server.
+All comparisons and lookups in the name server data base are case insensitive.
+.bl
+.b
+The following characters have special meanings:
+.ip ``\fB.\fP''
+A free standing dot in the name field refers to the root domain.
+.ip ``@''
+A free standing @ in the name field denotes the current origin.
+.ip "``\eX''"
+Where X is any character other than a digit (0-9),
+quotes that character so that its special meaning does not apply.
+For example, ``\e.'' can be used to place a dot character in a label.
+.ip "``\eDDD''"
+Where each D is a digit, is the octet corresponding to the
+decimal number described by DDD.
+The resulting octet is assumed to be text and
+is not checked for special meaning.
+.ip "``( )''"
+Parentheses are used to group data that crosses a line.
+In effect, line terminations are not recognized within parentheses.
+(At present, this notation only works for SOA RR's and is not optional.)
+.ip "``;''"
+Semicolon starts a comment; the remainder of the line is ignored. Note
+that a completely blank line is also considered a comment, and ignored.
+.ip "``*''"
+An asterisk signifies wildcarding. Note that this is just another data
+character whose special meaning comes about only during internal name
+server search operations. Wildcarding is only meaningful for some RR
+types (notably \fIMX\fP), and then only in the name field \(em not in
+the data fields.
+.pp
+Anywhere a name appears \(em either in the name field or in some data field
+defined to contain names \(em the current origin will be appended if the
+name does not end in a ``\fB\|.\|\fP''.
+This is useful for appending the current domain name to the data,
+such as machine names, but may cause problems where you do not want
+this to happen.
+A good rule of thumb is that, if the name is not in the domain for which
+you are creating the data file, end the name with a ``\fB.\fP''.
+.sh 3 $INCLUDE
+.pp
+An include line begins with $INCLUDE, starting in column 1,
+and is followed by a file name, and, optionally, by a new
+temporary $ORIGIN to be used while reading this file.
+This feature is
+particularly useful for separating different types of data into multiple files.
+An example would be:
+.(b l
+$INCLUDE /usr/local/adm/named/data/mail-exchanges
+.)b
+The line would be interpreted as a request to load the file
+\fI/usr/local/adm/named/data/mail-exchanges\fP. The $INCLUDE command does not cause
+data to be loaded into a different zone or tree. This is simply a way to
+allow data for a given primary zone to be organized in separate files.
+Not even the ``temporary $ORIGIN'' feature described above is sufficient
+to cause your data to branch out into some other zone \(em zone boundaries
+can only be introduced in the boot file.
+.pp
+A $INCLUDE file must have a name on its first RR. That is, the first
+character of the first non-comment line must not be a space. The current
+default name in the parent file \fIdoes not\fP carry into the $INCLUDE
+file.
+.sh 3 $ORIGIN
+.pp
+The origin is a way of changing the origin in a data file. The line starts
+in column 1, and is followed by a domain origin. This seems like it could
+be useful for putting more then one zone into a data file, but that's not
+how it works. The name server fundamentally requires a given zone to map
+entirely to some specific file. You should therefore be very careful to use
+$ORIGIN only once at the top of a file, or, within a file, to change to a
+``lower'' domain in the zone \(em never to some other zone altogether.
+.sh 3 "SOA - Start Of Authority"
+.(b L
+.TS
+l l l l l l.
+\fIname {ttl} addr-class SOA Origin Person in charge\fP
+@ IN SOA ucbvax\fB.\fPBerkeley\fB.\fPEdu\fB.\fP kjd\fB.\fPucbvax\fB.\fPBerkeley\fB.\fPEdu\fB.\fP (
+ 1995122103 ; Serial
+ 10800 ; Refresh
+ 1800 ; Retry
+ 3600000 ; Expire
+ 259200 ) ; Minimum
+.TE
+.)b
+The \fIStart of Authority, SOA,\fP record designates the start of a zone.
+The name is the name of the zone and is often given as ``@'' since this
+is always the current $ORIGIN and the SOA RR is usually the first record
+of the primary zone file.
+Origin is the name of the host on which this data file resides (in other
+words, the \fIprimary master\fP server for this zone.)
+Person in charge is the e-mail address for the person responsible
+for the name server, with ``@'' changed to a ``.''.
+The serial number is the version number of this data file and must be a
+positive integer.
+This number must be incremented whenever a change is made to the data.
+Older servers permitted the use of a phantom ``.'' in this and other
+numbers in a zone file; the meaning of n.m was ``n000m'' rather than the
+more intuitive ``n*1000+m'' (such that 1.234 translated to 1000234 rather
+than to 1234). This feature has been deprecated due to its
+obscurity, unpredictability, and lack of necessity.
+Note that using a ``YYYYMMDDNN'' notation you can still make 100 changes
+per day until the year 4294. You should choose a notation that works for
+you. If you're a clever \fIperl\fP programmer you could even use \fIRCS\fP
+version numbers to help generate your zone serial numbers.
+The refresh indicates how often, in seconds, the secondary name servers
+are to check with the primary name server to see if an update is needed.
+The retry indicates how long, in seconds, a secondary server should wait
+before retrying a failed zone transfer.
+Expire is the upper limit, in seconds, that a secondary name server
+is to use the data before it expires for lack of getting a refresh.
+Minimum is the default number of seconds to be used for the Time To Live
+field on resource records which do not specify one in the zone file.
+It is also an enforced minimum on Time To Live if it is specified on
+some resource record (RR) in the zone.
+There must be exactly one \fISOA\fP record per zone.
+.sh 3 "NS - Name Server"
+.TS
+l l l l l.
+\fI{name} {ttl} addr-class NS Name servers name\fP
+ IN NS ucbarpa\fB\|.\|\fPBerkeley\fB\|.\|\fPEdu\fB.\fP
+.TE
+The \fIName Server\fP record, \fINS\fP, lists a name server responsible
+for a given domain, creating a \fIdelegation point\fP and a \fIsubzone\fP.
+The first name field specifies the zone that is serviced by
+the name server specified by the second name.
+Every zone needs at least two name servers.
+.bp \" ----PLACEMENT HACK----
+.sh 3 "A - Address"
+.TS
+l l l l l.
+\fI{name} {ttl} addr-class A address\fP
+ucbarpa IN A 128\fB.\fP32\fB.\fP0\fB.\fP4
+ IN A 10\fB.\fP0\fB.\fP0\fB.\fP78
+.TE
+The \fIAddress\fP record, \fIA\fP, lists the address for a given machine.
+The name field is the machine name and the address is the network address.
+There should be one \fIA\fP record for each address of the machine.
+.sh 3 "HINFO - Host Information"
+.TS
+l l l l l l.
+\fI{name} {ttl} addr-class HINFO Hardware OS\fP
+ IN HINFO VAX-11/780 UNIX
+.TE
+\fIHost Information\fP resource record, \fIHINFO\fP, is for host specific
+data. This lists the hardware and operating system that are running at the
+listed host. If you want to include a space in the machine name you must
+quote the name (using ``"'' characters.) There could be one \fIHINFO\fP
+record for each host, though for security reasons most domains don't have
+any \fIHINFO\fP records at all. No application depends on them.
+.(b L
+.sh 3 "WKS - Well Known Services"
+.TS
+l l l l l l l.
+\fI{name} {ttl} addr-class WKS address protocol list of services\fP
+ IN WKS 128\fB.\fP32\fB.\fP0\fB.\fP10 UDP who route timed domain
+ IN WKS 128\fB.\fP32\fB.\fP0\fB.\fP10 TCP ( echo telnet
+ discard sunrpc sftp
+ uucp-path systat daytime
+ netstat qotd nntp
+ link chargen ftp
+ auth time whois mtp
+ pop rje finger smtp
+ supdup hostnames
+ domain
+ nameserver )
+.TE
+The \fIWell Known Services\fP record, \fIWKS\fP, describes the well known
+services supported by a particular protocol at a specified address. The
+list of services and port numbers come from the list of services specified
+in \fI/etc/services.\fP There should be only one \fIWKS\fP record per
+protocol per address. Note that RFC1123 says of \fIWKS\fP records:
+.)b
+.(l L
+ 2.2 Using Domain Name Service
+ ...
+ An application SHOULD NOT rely on the ability to locate a WKS
+ record containing an accurate listing of all services at a
+ particular host address, since the WKS RR type is not often used
+ by Internet sites. To confirm that a service is present, simply
+ attempt to use it.
+ ...
+ 5.2.12 WKS Use in MX Processing: RFC-974, p. 5
+
+ RFC-974 [SMTP:3] recommended that the domain system be queried
+ for WKS ("Well-Known Service") records, to verify that each
+ proposed mail target does support SMTP. Later experience has
+ shown that WKS is not widely supported, so the WKS step in MX
+ processing SHOULD NOT be used.
+ ...
+ 6.1.3.6 Status of RR Types
+ ...
+ The TXT and WKS RR types have not been widely used by
+ Internet sites; as a result, an application cannot rely
+ on the the existence of a TXT or WKS RR in most
+ domains.
+.)l
+.sh 3 "CNAME - Canonical Name"
+.TS
+l l l l l.
+\fIalias {ttl} addr-class CNAME Canonical name\fP
+ucbmonet IN CNAME monet
+.TE
+The \fICanonical Name\fP resource record, \fICNAME\fP, specifies an
+alias or nickname for the official, or canonical, host name.
+This record must be the only one associated with the alias name.
+All other resource records must be
+associated with the canonical name, not with the nickname.
+Any resource records that include a domain name as their value
+(e.g., NS or MX) \fImust\fP list the canonical name, not the nickname.
+Similarly, a CNAME will be followed when searching for A RRs, but not
+for MX RRs or NS RRs or most other types of RRs. CNAMEs are allowed
+to point to other CNAMEs, but this is considered sloppy.
+.pp
+Nicknames are useful when a well known host changes its name. In that
+case, it is usually a good idea to have a \fICNAME\fP record so that
+people still using the old name will get to the right place.
+.sh 3 "PTR - Domain Name Pointer"
+.TS
+l l l l l.
+\fIname {ttl} addr-class PTR real name\fP
+7.0 IN PTR monet\fB\|.\|\fPBerkeley\fB\|.\|\fPEdu\fB\|.\fP
+.TE
+A \fIDomain Name Pointer\fP record, \fIPTR\fP, allows special names to point
+to some other location in the domain. The above example of a \fIPTR\fP
+record is used in setting up reverse pointers for the special
+\fIIN-ADDR\fP\fB\|.\|\fP\fIARPA\fP domain. This line is from the example
+\fIhosts.rev\fP file. \fIPTR\fP records are needed by the
+\fIgethostbyaddr\fP function. Note the trailing ``\fB\|.\|\fP'' which
+prevents \s-1BIND\s+1 from appending the current \s-1$ORIGIN\s+1 to that
+domain name.
+.sh 3 "MX - Mail Exchange"
+.TS
+l l l l l l.
+\fIname {ttl} addr-class MX preference value mail exchange\fP
+Munnari\fB\|.\|\fPOZ\fB\|.\|\fPAU\fB\|.\fP IN MX 0 Seismo\fB\|.\|\fPCSS\fB\|.\|\fPGOV\fB\|.\fP
+*\fB\|.\|\fPIL\fB\|.\fP IN MX 0 RELAY\fB\|.\|\fPCS\fB\|.\|\fPNET\fB\|.\fP
+.TE
+\fIMail eXchange\fP records, \fIMX\fP, are used to specify a list of hosts
+which are configured to receive mail sent to this domain name. Every name
+which receives mail should have an \fIMX\fP since if one is not found at the
+time mail is being delivered, an \fIMX\fP will be ``imputed'' with a cost
+of 0 and a destination of the host itself. If you want a host to receive
+its own mail, you should create an \fIMX\fP for your host's name, pointing
+at your host's name. It is better to have this be explicit than to let it
+be imputed by remote mailers.
+In the first example, above,
+Seismo\fB\|.\|\fPCSS\fB\|.\|\fPGOV\fB\|.\fP is a mail gateway that knows how
+to deliver mail to Munnari\fB\|.\|\fPOZ\fB\|.\|\fPAU\fB\|.\fP. These two
+machines may have a private connection or use a different transport medium.
+The preference value is the order that a mailer should follow when there is
+more than one way to deliver mail to a single machine. Note that lower
+numbers indicate higher precedence, and that mailers are supposed to randomize
+same-valued \fIMX\fP hosts so as to distribute the load evenly if the costs
+are equal. See RFC974 for more detailed information.
+.pp
+Wildcard names containing the character ``*'' may be used for mail routing
+with \fIMX\fP records. There are likely to be servers on the network that
+simply state that any mail to a domain is to be routed through a relay.
+Second example, above, all mail to hosts in the domain IL is routed through
+RELAY.CS.NET. This is done by creating a wildcard resource record, which
+states that *.IL has an \fIMX\fP of RELAY.CS.NET. Wildcard \fIMX\fP records
+are not very useful in practice, though, since once a mail message gets to
+the gateway for a given domain it still has to be routed \fIwithin\fP that
+domain and it is not currently possible to have an apparently-different set
+of \fIMX\fP records inside and outside of a domain. If you won't be needing
+any Mail Exchanges inside your domain, go ahead and use a wildcard. If you
+want to use both wildcard ``top-level'' and specific ``interior'' \fIMX\fP
+records, note that each specific record will have to ``end with'' a complete
+recitation of the same data that is carried in the top-level record. This
+is because the specific \fIMX\fP records will take precedence over the
+top-level wildcard records, and must be able to perform the top-level's
+if a given interior domain is to be able to receive mail from outside the
+gateway. Wildcard \fIMX\fP records are very subtle and you should be careful
+with them.
+.sh 3 "TXT - Text"
+.TS
+l l l l l l.
+\fIname {ttl} addr-class TXT string\fP
+Munnari\fB\|.\|\fPOZ\fB\|.\|\fPAU\fB\|.\fP IN TXT "foo"
+.TE
+A \fITXT\fP record contains free-form textual data. The syntax of the text
+depends on the domain where it is found; many systems use \fITXT\fP records
+to encode local data in a stylized format. MIT Hesiod is one such system.
+.sh 3 "RP - Responsible Person"
+.TS
+l l l l l l.
+\fIowner {ttl} addr-class RP mbox-domain-name TXT-domain-name\fP
+franklin IN RP ben.franklin.berkeley.edu. sysadmins.berkeley.edu.
+.TE
+.pp
+The Responsible Person record, \fIRP\fP, identifies the name or group name of
+the responsible person for a host. Often it is desirable to be able to
+identify the responsible entity for a particular host. When that host
+is down or malfunctioning, you would want to contact those parties
+who might be able to repair the host.
+.pp
+The first field, \fImbox-domain-name\fP, is a domain name that specifies the
+mailbox for the responsible person. Its format in a zone file uses
+the \s-1DNS\s+1 convention for mailbox encoding, identical to that used for
+the \fIPerson-in-charge\fP mailbox field in the SOA record.
+In the example above, the \fImbox-domain-name\fP shows the encoding for
+``\fB<ben@franklin.berkeley.edu>\fP''.
+The root domain name (just ``\fB\|.\|\fP'') may be specified
+to indicate that no mailbox is available.
+.pp
+The second field, \fITXT-domain-name\fP, is a domain name for which
+\fITXT\fP records exist. A subsequent query can be performed to retrieve
+the associated \fITXT\fP resource records at \fITXT-domain-name\fP. This
+provides a level of indirection so that the entity can be referred to from
+multiple places in the \s-1DNS\s+1. The root domain name (just
+``\fB\|.\|\fP'') may be specified for \fITXT-domain-name\fI to indicate
+that no associated \fITXT\fP RR exists. In the example above,
+``\fBsysadmins.berkeley.edu.\fP'' is the name of a TXT record that might
+contain some text with names and phone numbers.
+.pp
+The format of the \fIRP\fP record is class-insensitive.
+Multiple \fIRP\fP records at a single name may be present in the database,
+though they should have identical TTLs.
+.pp
+The \fIRP\fP record is still experimental; not all name servers implement
+or recognize it.
+.sh 3 "AFSDB - DCE or AFS Server"
+.TS
+l l l l l l.
+\fIname {ttl} addr-class AFSDB subtype server host name\fP
+toaster.com. IN AFSDB 1 jack.toaster.com.
+toaster.com. IN AFSDB 1 jill.toaster.com.
+toaster.com. IN AFSDB 2 tracker.toaster.com.
+.TE
+\fIAFSDB\fP records are used to specify the hosts that provide a style of
+distributed service advertised under this domain name. A subtype value
+(analogous to the ``preference'' value in the \fIMX\fP record) indicates
+which style of distributed service is provided with the given name.
+Subtype 1 indicates that the named host is an AFS (R) database server for
+the AFS cell of the given domain name. Subtype 2 indicates that the
+named host provides intra-cell name service for the DCE (R) cell named by
+the given domain name.
+In the example above, jack\fB\|.\|\fPtoaster\fB\|.\|\fPcom and
+jill\fB\|.\|\fPtoaster\fB\|.\|\fPcom are declared to be AFS database
+servers for the toaster\fB\|.\|\fPcom AFS cell, so that AFS clients
+wishing service from toaster\fB\|.\|\fPcom are directed to those two hosts
+for further information. The third record declares that
+tracker\fB\|.\|\fPtoaster\fB\|.\|\fPcom houses a directory server for the
+root of the DCE cell toaster\fB\|.\|\fPcom, so that DCE clients that wish
+to refer to DCE services should consult with the host
+tracker\fB\|.\|\fPtoaster\fB\|.\|\fPcom for further information. The
+DCE sub-type of record is usually accompanied by a \fITXT\fP record for
+other information specifying other details to be used in accessing the
+DCE cell. RFC1183 contains more detailed information on the use of
+this record type.
+.pp
+The \fIAFSDB\fP record is still experimental; not all name servers implement
+or recognize it.
+
+.sh 3 "PX - Pointer to X.400/RFC822 mapping information"
+.TS
+l l l l l l l.
+\fIname {ttl} addr-class PX prefer 822-dom X.400-dom\fP
+*.ADMD-garr.X42D.it. IN PX 50 it. ADMD-garr.C-it.
+*.infn.it. IN PX 50 infn.it. O.PRMD-infn.ADMD-garr.C-it.
+*.it. IN PX 50 it. O-gate.PRMD-garr.ADMD-garr.C-it.
+.TE
+.pp
+The \fIPX\fP records (\fIPointer to X.400/RFC822 mapping information\fP)
+are used to specify address mapping rules between X.400 O/R addresses and
+RFC822 style (domain-style) mail addresses. For a detailed description of the
+mapping process please refer to RFC1327.
+.pp
+Mapping rules are of 3 different types:
+.pp
+1) mapping from X.400 to RFC822 (defined as "table 1 rules" in RFC1327)
+.pp
+2) mapping from RFC822 to X.400 (defined as "table 2 rules" in RFC1327)
+.pp
+3) encoding RFC822 into X.400 (defined as "gate table" in RFC1327)
+.pp
+All three types of mapping rules are specified using \fIPX\fP Resource
+Records in DNS, although the \fIname\fP value is different: for case 1, the
+\fIname\fP value is an X.400 domain in DNS syntax, whereas for cases 2 and
+3 the \fIname\fP value is an RFC822 domain. Refer to RFC-1664 for details
+on specifying an X.400 domain in DNS syntax and for the use of the
+\fIX42D\fP keyword in it. Tools are available to convert from RFC1327
+tables format into DNS files syntax. \fIPreference\fP is analogous to the
+\fIMX\fP RR Preference parameter: it is currently advised to use a fixed
+value of 50 for it. \fI822-dom\fP gives the RFC822 part of the mapping
+rules, and \fIX.400-dom\fP gives the X.400 part of the mapping rule (in DNS
+syntax). It is currently advised always to use wildcarded \fIname\fP
+values, as the RFC1327 tables specifications permit wildcard
+specifications only. This is to keep compatibility with existing services
+using static RFC1327 tables instead of DNS \fIPX\fP information.
+.pp
+Specifications of mapping rules from X.400 to RFC822 syntax requires the
+creation of an appropriate X.400 domain tree into DNS, including thus specific
+\fISOA\fP and \fINS\fP records for the domain itself. Specification of mapping
+rules from RFC822 into X.400 can be embedded directly into the normal direct
+\fIname\fP tree.
+Again, refer to RFC1664 for details about organization of this structure.
+.pp
+Tools and library routines, based on the standard resolver ones, are available
+to retrieve from DNS the appropriate mapping rules in RFC1327 or DNS syntax.
+.pp
+Once again, refer to RFC1664 to use the \fIPX\fP resource record, and be careful
+in coordinating the mapping information you can specify in DNS with the same
+information specified into the RFC1327 static tables.
+.pp
+The \fIPX\fP record is still experimental; not all servers implement or
+recognize it.
+
+.sh 2 "Discussion about the TTL"
+.pp
+The Time To Live assigned to the records and to the zone via the
+Minimum field in the SOA record is very important. High values will
+lead to lower BIND network traffic and faster response time. Lower
+values will tend to generate lots of requests but will allow faster
+propagation of changes.
+.pp
+Only changes and deletions from the zone are affected by the TTLs.
+Additions propagate according to the Refresh value in the SOA.
+.pp
+Experience has shown that sites use default TTLs for their zones varying
+from around 0.5 day to around 7 days. You may wish to consider boosting
+the default TTL shown in former versions of this guide from one day
+(86400 seconds) to three days (259200 seconds). This will drastically
+reduce the number of requests made to your name servers.
+.pp
+If you need fast propagation of changes and deletions, it might be wise
+to reduce the Minimum field a few days before the change, then do the
+modification itself and augment the TTL to its former value.
+.pp
+If you know that your zone is pretty stable (you mainly add new records
+without deleting or changing old ones) then you may even wish to consider
+a TTL higher than three days.
+.pp
+Note that in any case, it makes no sense to have records with a TTL
+below the SOA Refresh delay, as Delay is the time required for secondaries
+to get a copy of the newly modified zone.
+
+.sh 2 "About ``secure zones''
+.pp
+Secure zones implement named security on a zone by zone basis. It is
+designed to use a permission list of networks or hosts which may obtain
+particular information from the zone.
+.pp
+In order to use zone security, \fInamed\fP must be compiled with SECURE_ZONES
+defined and you must have at least one secure_zone TXT RR. Unless a
+\fIsecure_zone\fP record exists for a given zone, no restrictions will be
+applied to the data in that zone. The format of the secure_zone TXT RR is:
+.lp
+secure_zone\h'0.5i'addr-class\h'0.5i'TXT\h'0.5i'string
+.pp
+The addr-class may be either \fIHS\fP or \fIIN\fP. The syntax for the TXT
+string is either ``network address:netmask'' or ``host IP address:H''.
+.pp
+``network address:netmask'' allows queries from an entire network. If the
+netmask is omitted, named will use the default netmask for the network
+address specified.
+.pp
+``host IP address:H'' allows queries from a host. The ``H'' after the ``:''
+is required to differentiate the host address from a network address.
+Multiple secure_zone TXT RRs are allowed in the same zone file.
+.pp
+For example, you can set up a zone to only answer Hesiod requests from the
+masked class B network 130.215.0.0 and from host 128.23.10.56 by adding the
+following two TXT RR's:
+.lp
+secure_zone\h'0.5i'HS\h'0.5i'TXT\h'0.5i'``130.215.0.0:255.255.0.0''
+secure_zone\h'0.5i'HS\h'0.5i'TXT\h'0.5i'``128.23.10.56:H''
+.pp
+This feature can be used to restrict access to a Hesiod password map or to
+separate internal and external internet address resolution on a firewall
+machine without needing to run a separate named for internal and external
+address resolution.
+.pp
+Note that you will need to include your loopback interface (127.0.0.1) in
+your secure_zone record, or your local clients won't be able to resolve
+names.
+
+.sh 2 "About Hesiod, and HS-class Resource Records
+.pp
+Hesiod, developed by \s-1MIT\s+1 Project Athena, is an information service
+built upon \s-1BIND\s+1. Its intent is similar to that of Sun's
+\s-1NIS\s+1: to furnish information about users, groups, network-accessible
+file systems, printcaps, and mail service throughout an installation. Aside
+from its use of \s-1BIND\s+1 rather than separate server code another
+important difference between Hesiod and \s-1NIS\s+1 is that Hesiod is not
+intended to deal with passwords and authentication, but only with data that
+are not security sensitive. Hesiod servers can be implemented by adding
+resource records to \s-1BIND\s+1 servers; or they can be implemented as
+separate servers separately administered.
+.pp
+To learn about and obtain Hesiod make an anonymous \s-1FTP\s+1 connection to
+host \s-1ATHENA-DIST.MIT.EDU\s+1 and retrieve the compressed tar file
+\fB/pub/ATHENA/hesiod.tar.Z\fP. You will not need the named and resolver
+library portions of the distribution because their functionality has already
+been integrated into \s-1BIND as of 4.9\s+1. To learn how Hesiod functions
+as part of the Athena computing environment obtain the paper
+\fB/pub/ATHENA/usenix/athena-changes.PS\fP from the above \s-1FTP\s+1 server
+host. There is also a tar file of sample Hesiod resource files.
+.pp
+Whether one should use Hesiod class is open to question, since the same
+services can probably be provided with class IN, type TXT and type
+CNAME records. In either case, the code and documents for Hesiod will
+suggest how to set up and use the service.
+.pp
+Note that while \s-1BIND\s+1 includes support for \fIHS\fP-class queries,
+the zone transfer logic for non-\fIIN\fP-class zones is still experimental.
+
+.sh 2 "Sample Files"
+.pp
+The following section contains sample files for the name server.
+This covers example boot files for the different types of servers
+and example domain data base files.
diff --git a/contrib/bind/doc/bog/intro.me b/contrib/bind/doc/bog/intro.me
new file mode 100644
index 0000000..597fa44
--- /dev/null
+++ b/contrib/bind/doc/bog/intro.me
@@ -0,0 +1,75 @@
+.\" ++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--
+.\"
+.\" @(#)intro.me 6.2 (Berkeley) 2/28/88
+.\"
+.sh 1 Introduction
+.pp
+The Berkeley Internet Name Domain (\s-1BIND\s+1) implements an Internet name
+server for \s-2BSD\s+2-derived operating systems. The \s-1BIND\s+1 consists
+of a server (or ``daemon'') called \fInamed\fP and a \fIresolver\fP library.
+A name server is a network service that enables clients to name resources or
+objects and share this information with other objects in the network. This
+in effect is a distributed data base system for objects in a computer
+network. The \s-1BIND\s+1 server runs in the background, servicing queries
+on a well known network port. The standard port for UDP and TCP is specified
+in \fI/etc/services\fP. The \fIresolver\fP is a set of routines residing
+in a system library that provides the interface that programs can use to
+access the domain name services.
+.pp
+BIND is fully integrated into BSD (4.3 and later releases)
+network programs for use in storing and retrieving host names and address.
+The system administrator can configure the system to use BIND as a
+replacement to the older host table lookup of information in the network
+hosts file \fI/etc/hosts\fP. The default configuration for BSD uses
+BIND.
diff --git a/contrib/bind/doc/bog/manage.me b/contrib/bind/doc/bog/manage.me
new file mode 100644
index 0000000..6f17b80
--- /dev/null
+++ b/contrib/bind/doc/bog/manage.me
@@ -0,0 +1,156 @@
+.\" ++Copyright++ 1986, 1988, 1995
+.\" -
+.\" Copyright (c) 1986, 1988, 1995
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\" -
+.\" Portions Copyright (c) 1993 by Digital Equipment Corporation.
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies, and that
+.\" the name of Digital Equipment Corporation not be used in advertising or
+.\" publicity pertaining to distribution of the document or software without
+.\" specific, written prior permission.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
+.\" WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
+.\" OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
+.\" CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+.\" DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+.\" PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+.\" ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+.\" SOFTWARE.
+.\" -
+.\" --Copyright--
+.\"
+.\" @(#)manage.me 6.6 (Berkeley) 9/19/89
+.\" $Id: manage.me,v 8.4 1995/12/22 10:20:24 vixie Exp $
+.\"
+.sh 1 "Domain Management"
+.pp
+This section contains information for starting, controlling and debugging
+\fInamed\fP.
+.sh 2 /etc/rc.local
+.pp
+The hostname should be set to the full domain style name in
+\fI/etc/rc.local\fP using \fIhostname\|(1)\fP. The following entry should
+be added to \fI/etc/rc.local\fP to start up \fInamed\fP at system boot time:
+.(b l
+\fIif [ -f /usr/sbin/named ]; then
+ /usr/sbin/named\fP [options] \fI& echo -n ' named' >/dev/console\fP
+\fIfi\fP
+.)b
+This usually directly follows the lines that start \fIsyslogd\fP.
+\fBDo Not\fP attempt to run \fInamed\fP from \fIinetd\fP.
+This will
+continuously restart the name server and defeat the purpose of the cache.
+.sh 2 /var/run/named.pid
+.pp
+When \fInamed\fP is successfully started up it writes its process id into
+the file \fI/var/run/named.pid\fP. This is useful to programs that want to
+send signals to \fInamed\fP. The name of this file may be changed by defining
+\fIPIDFILE\fP to the new name when compiling \fInamed\fP.
+.sh 2 /etc/hosts
+.pp
+The \fIgethostbyname\|()\fP library call can detect if \fInamed\fP is running.
+If it is determined that \fInamed\fP is not running it will look in
+\fI/etc/hosts\fP to resolve an address.
+This option was added to allow \fIifconfig\|(8C)\fP to configure the machines
+local interfaces and to enable a system manager to access the network
+while the system is in single user mode.
+It is advisable to put the local machines interface addresses and a couple of
+machine names and address in
+\fI/etc/hosts\fP so the system manager can rcp files from another machine
+when the system is in single user mode.
+The format of \fI/etc/hosts\fP has not changed. See \fIhosts\|(5)\fP
+for more information.
+Since the process of reading \fI/etc/hosts\fP is slow,
+it is not advisable to use this option when the system is in multi user mode.
+
+.sh 2 Signals
+.pp
+There are several signals that can be sent to the \fInamed\fP process
+to have it do tasks without restarting the process.
+.sh 3 Reload
+.pp
+SIGHUP -
+Causes \fInamed\fP to read \fInamed.boot\fP and reload the database.
+This is useful when you have made a change to a ``primary'' data file
+and you want \fInamed\fP\|'s internal database to reflect the change.
+If you build \s-1BIND\s+1 with the \s-1FORCED_RELOAD\s+1 option, then
+\s-1SIGHUP\s+1 also has the effect of scheduling all ``secondary'' zones
+for serial-number checks, which could lead to zone transfers ahead of
+the usual schedule. Normally serial-number compares are done only at
+the intervals specified in the zone's \s-1SOA\s+1 record.
+.sh 3 Debugging
+.pp
+When \fInamed\fP is running incorrectly, look first in
+\fI/var/log/messages\fP and check for any messages logged by \fIsyslog\fP.
+Next send it a signal to see what is happening. Unless you run it with the
+``-d'' option, \fInamed\fP has very little to say on its standard output or
+standard error. Everything \fInamed\fP has to say, it says to \fIsyslog\fP.
+.pp
+SIGINT -
+Dumps the current data base and cache to
+\fI/var/tmp/named_dump.db\fP
+This should give you an indication to whether the data base was loaded
+correctly.
+The name of the dump file may be changed
+by defining \fIDUMPFILE\fP to the new name when compiling \fInamed\fP.
+
+\fINote:\fP the following two signals only work when \fInamed\fP is built with
+\fIDEBUG\fP defined.
+.pp
+SIGUSR1 -
+Turns on debugging. Each following SIGUSR1 increments the debug level.
+The output goes to \fI/var/tmp/named.run\fP
+The name of this debug file may be changed
+by defining \fIDEBUGFILE\fP to the new name before compiling \fInamed\fP.
+.pp
+SIGUSR2 -
+Turns off debugging completely.
+
+For more detailed debugging, define DEBUG when compiling the resolver
+routines into \fI/lib/libc.a\fP.
+.pp
+SIGWINCH -
+Toggles tracing of all incoming queries if \fInamed\fP has been
+compiled with \fIQRYLOG\fP defined. The trace is sent to syslog, and
+is huge, but it is very useful for tracking down problems.
+
+To run with tracing of all queries specify the \fI-q\fP flag on the
+command line. If you routinely log queries you will probably want to
+analyze the results using the dnsstats stats script in the
+contrib directory.
+.pp
+SIGIOT -
+Dumps statistics data into \fI/var/tmp/named.stats\fP if the server
+is built with \fISTATS\fP defined. Statistics are appended to the file.
diff --git a/contrib/bind/doc/bog/named.boot.cache b/contrib/bind/doc/bog/named.boot.cache
new file mode 100644
index 0000000..5e0e3d3
--- /dev/null
+++ b/contrib/bind/doc/bog/named.boot.cache
@@ -0,0 +1,77 @@
+.\" ++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--
+.\"
+.\" @(#)named.boot.cache 6.4 (Berkeley) 9/19/89
+.\"
+.ne 13v
+.sh 4 "Caching Only Server"
+.(b L
+.TS
+l.
+;
+; Boot file for Caching Only Name Server
+;
+.TE
+.TS
+l l l
+l
+l l l.
+; type domain source file or host
+;
+directory /usr/local/adm/named
+cache \fB.\fP root\fB.\fPcache
+primary 0\fB.\fP0\fB.\fP127\fB.\fPin-addr\fB.\fParpa named\fB.\fPlocal
+.TE
+.)b
+
+
diff --git a/contrib/bind/doc/bog/named.boot.primary b/contrib/bind/doc/bog/named.boot.primary
new file mode 100644
index 0000000..0f3c3ca
--- /dev/null
+++ b/contrib/bind/doc/bog/named.boot.primary
@@ -0,0 +1,78 @@
+.\" ++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--
+.\"
+.\" @(#)named.boot.primary 6.4 (Berkeley) 9/19/89
+.\"
+.ne 15v
+.sh 3 "Boot Files"
+.sh 4 "Primary Server"
+.(b L
+.TS
+l.
+;
+; Boot file for Primary Name Server
+;
+.TE
+.TS
+l l l
+l
+l l l.
+; type domain source file or host
+;
+directory /usr/local/adm/named
+primary Berkeley\fB.\fPEdu ucbhosts
+primary 32\fB.\fP128\fB.\fPin-addr\fB.\fParpa ucbhosts\fB.\fPrev
+primary 0\fB.\fP0\fB.\fP127\fB.\fPin-addr\fB.\fParpa named\fB.\fPlocal
+cache \fB.\fP root\fB.\fPcache
+.TE
+.)b
diff --git a/contrib/bind/doc/bog/named.boot.secondary b/contrib/bind/doc/bog/named.boot.secondary
new file mode 100644
index 0000000..64a607d
--- /dev/null
+++ b/contrib/bind/doc/bog/named.boot.secondary
@@ -0,0 +1,77 @@
+.\" ++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--
+.\"
+.\" @(#)named.boot.secondary 6.4 (Berkeley) 9/19/89
+.\"
+.ne 12v
+.sh 4 "Secondary Server"
+.(b L
+.TS
+l.
+;
+; Boot file for Secondary Name Server
+;
+.TE
+.TS
+l l l
+l
+l l l.
+; type domain source file or host
+;
+directory /usr/local/adm/named
+secondary Berkeley\fB.\fPEdu 128\fB.\fP32\fB.\fP0\fB.\fP4 128\fB.\fP32\fB.\fP0\fB.\fP10 ucbhosts.bak
+secondary 32\fB.\fP128\fB.\fPin-addr\fB.\fParpa 128\fB.\fP32\fB.\fP0\fB.\fP4 128\fB.\fP32\fB.\fP0\fB.\fP10 ucbhosts.rev.bak
+primary 0\fB.\fP0\fB.\fP127\fB.\fPin-addr\fB.\fParpa named\fB.\fPlocal
+cache \fB.\fP root\fB.\fPcache
+.TE
+.)b
diff --git a/contrib/bind/doc/bog/named.local b/contrib/bind/doc/bog/named.local
new file mode 100644
index 0000000..209c5be
--- /dev/null
+++ b/contrib/bind/doc/bog/named.local
@@ -0,0 +1,75 @@
+.\" ++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--
+.\"
+.\" @(#)named.local 6.3 (Berkeley) 5/24/89
+.\"
+.ne 13v
+.sh 3 "named.local"
+.(b L
+
+.TS
+l l l l l s.
+@ IN SOA ucbvax\fB.\fPBerkeley\fB.\fPEdu. kjd\fB.\fPucbvax\fB.\fPBerkeley\fB.\fPEdu\fB.\fP (
+.T&
+l l l l l.
+ 1994072100 ; Serial
+ 10800 ; Refresh
+ 1800 ; Retry
+ 3600000 ; Expire
+ 259200 ) ; Minimum
+.T&
+l l l l l s.
+ IN NS ucbvax\fB.\fPBerkeley\fB.\fPEdu\fB.\fP ; pedantic
+1 IN PTR localhost\fB.\fP
+.TE
+.)b
diff --git a/contrib/bind/doc/bog/ns.me b/contrib/bind/doc/bog/ns.me
new file mode 100644
index 0000000..ec3ca3c
--- /dev/null
+++ b/contrib/bind/doc/bog/ns.me
@@ -0,0 +1,96 @@
+.\" ++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--
+.\"
+.\" @(#)ns.me 6.3 (Berkeley) 9/19/89
+.\"
+.sh 1 "The Name Service"
+.pp
+The basic function of the name server is to provide information about network
+objects by answering queries. The specifications for this name server are
+defined in RFC1034, RFC1035 and RFC974. These documents can be found in
+\fI/usr/src/etc/named/doc\fP in 4.3BSD or \fIftp\fPed from
+\fBftp.rs.internic.net\fP.
+It is also recommended that you read the related manual pages,
+\fInamed\fP\|(8),
+\fIresolver\fP\|(3),
+and \fIresolver\fP\|(5).
+.pp
+The advantage of using a name server over the host table lookup for host
+name resolution is to avoid the need for a single centralized clearinghouse
+for all names. The authority for this information can be delegated to the
+different organizations on the network responsible for it.
+.pp
+The host table lookup routines require that the master file for the entire
+network be maintained at a central location by a few people. This works
+fine for small networks where there are only a few machines and the
+different organizations responsible for them cooperate. But this does not
+work well for large networks where machines cross organizational boundaries.
+.pp
+With the name server, the network can be broken into a hierarchy of domains.
+The name space is organized as a tree according to organizational or
+administrative boundaries.
+Each node, called a \fIdomain\fP, is given a label, and the name of the
+domain is the concatenation of all the labels of the domains from
+the root to the current domain, listed from right to left separated by dots.
+A label need only be unique within its domain.
+The whole space is partitioned into several areas called \fIzones\fP,
+each starting at a domain and extending down to the leaf domains or to
+domains where other zones start.
+Zones usually represent administrative boundaries.
+An example of a host address for a host at the University of California,
+Berkeley would look as follows:
+.(b
+\fImonet\fP\|\fB.\fP\|\fIBerkeley\fP\|\fB.\fP\|\fIEDU\fP
+.)b
+The top level domain for educational organizations is EDU;
+Berkeley is a subdomain of EDU and monet is the name of the host.
diff --git a/contrib/bind/doc/bog/resolv.conf b/contrib/bind/doc/bog/resolv.conf
new file mode 100644
index 0000000..1f15991
--- /dev/null
+++ b/contrib/bind/doc/bog/resolv.conf
@@ -0,0 +1,67 @@
+.\" ++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--
+.\"
+.\" @(#)resolv.conf 6.2 (Berkeley) 2/29/88
+.\"
+.ne 6v
+.\" .bp
+.sh 3 "Remote Server / DNS Client"
+.sh 4 "/etc/resolv.conf"
+.(b L
+
+domain Berkeley\fB.\fPEdu
+nameserver 128\fB.\fP32\fB.\fP0\fB.\fP4
+nameserver 128\fB.\fP32\fB.\fP0\fB.\fP10
+sortlist 130.155.160.0/255.255.240.0 130.155.0.0
+
+.)b
diff --git a/contrib/bind/doc/bog/root.cache b/contrib/bind/doc/bog/root.cache
new file mode 100644
index 0000000..3bf5727
--- /dev/null
+++ b/contrib/bind/doc/bog/root.cache
@@ -0,0 +1,102 @@
+.\" ++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--
+.\"
+.\" @(#)root.cache 6.4 (Berkeley) 4/29/90
+.\"
+.ne 38v
+.sh 3 "root.cache"
+.(b L
+
+;
+; This file holds the information on root name servers needed to
+; initialize cache of Internet domain name servers
+; (e.g. reference this file in the "cache . <file>"
+; configuration file of BIND domain name servers).
+;
+; This file is made available by InterNIC registration services
+; under anonymous FTP as
+; file /domain/named.root
+; on server FTP.RS.INTERNIC.NET
+; -OR- under Gopher at RS.INTERNIC.NET
+; under menu InterNIC Registration Services (NSI)
+; submenu InterNIC Registration Archives
+; file named.root
+;
+; last update: Oct 5, 1994
+; related version of root zone: 1994100500
+;
+.TS
+l l l l l.
+\fB.\fP 604800 IN NS NS\fB.\fPINTERNIC\fB.\fPNET\fB.\fP
+NS\fB.\fPINTERNIC\fB.\fPNET\fB.\fP 604800 IN A 198\fB.\fP41\fB.\fP0\fB.\fP4
+\fB.\fP 604800 IN NS NS1\fB.\fPISI\fB.\fPEDU\fB.\fP
+NS1\fB.\fPISI\fB.\fPEDU\fB.\fP 604800 IN A 128\fB.\fP9\fB.\fP0\fB.\fP107
+\fB.\fP 604800 IN NS C\fB.\fPPSI\fB.\fPNET\fB.\fP
+C\fB.\fPPSI\fB.\fPNET\fB.\fP 604800 IN A 192\fB.\fP33\fB.\fP4\fB.\fP12
+\fB.\fP 604800 IN NS TERP\fB.\fPUMD\fB.\fPEDU\fB.\fP
+TERP\fB.\fPUMD\fB.\fPEDU\fB.\fP 604800 IN A 128\fB.\fP8\fB.\fP10\fB.\fP90
+\fB.\fP 604800 IN NS NS\fB.\fPNASA\fB.\fPGOV\fB.\fP
+NS\fB.\fPNASA\fB.\fPGOV\fB.\fP 604800 IN A 128\fB.\fP102\fB.\fP16\fB.\fP10
+ 604800 IN A 192\fB.\fP52\fB.\fP195\fB.\fP10
+\fB.\fP 604800 IN NS NS\fB.\fPISC\fB.\fPORG\fB.\fP
+NS\fB.\fPISC\fB.\fPORG\fB.\fP 604800 IN A 192\fB.\fP5\fB.\fP5\fB.\fP241
+\fB.\fP 604800 IN NS NS\fB.\fPNIC\fB.\fPDDN\fB.\fPMIL\fB.\fP
+NS\fB.\fPNIC\fB.\fPDDN\fB.\fPMIL\fB.\fP 604800 IN A 192\fB.\fP112\fB.\fP36\fB.\fP4
+\fB.\fP 604800 IN NS AOS\fB.\fPARL\fB.\fPARMY\fB.\fPMIL\fB.\fP
+AOS\fB.\fPARL\fB.\fPARMY\fB.\fPMIL\fB.\fP 604800 IN A 128\fB.\fP63\fB.\fP4\fB.\fP82
+ 604800 IN A 192\fB.\fP5\fB.\fP25\fB.\fP82
+\fB.\fP 604800 IN NS NIC\fB.\fPNORDU\fB.\fPNET\fB.\fP
+NIC\fB.\fPNORDU\fB.\fPNET\fB.\fP 604800 IN A 192\fB.\fP36\fB.\fP148\fB.\fP17
+.TE
+; End of File
+.)b
diff --git a/contrib/bind/doc/bog/setup.me b/contrib/bind/doc/bog/setup.me
new file mode 100644
index 0000000..fff7657
--- /dev/null
+++ b/contrib/bind/doc/bog/setup.me
@@ -0,0 +1,88 @@
+.\" ++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--
+.\"
+.\" @(#)setup.me 6.4 (Berkeley) 9/19/89
+.\"
+.sh 1 "Setting up Your Own Domain"
+.pp
+When setting up a domain that is going to be on a public network the site
+administrator should contact the organization in charge of the network and
+request the appropriate domain registration form. An organization that
+belongs to multiple networks (such as the \fIInternet\fP and
+\fIBITNET\fP) should register with only one network.
+.sh 2 "Internet"
+.pp
+Sites on the Internet who need information on setting up a domain should
+contact the registrar for their network, which is one of the following:
+.TS
+l l.
+MILnet \s-1HOSTMASTER\s+1@\s-1NIC\s+1\fB\|.\|\fP\s-1DDN\s+1\fB\|.\|\fP\s-1MIL\s+1
+other \s-1HOSTMASTER\s+1@\s-1INTERNIC\s+1\fB\|.\|\fP\s-1NET\s+1
+.TE
+You may also want to be placed on the \s-1BIND\s+1 mailing list, which is a
+mail group for people on the Internet who run \s-1BIND\s+1. The group
+discusses future design decisions, operational problems, and other related
+topic. The address to request being placed on this mailing list is:
+.(b l
+\fIbind-request\|@\|uunet\fP\fB\|.\|\fP\fIuu\fP\fB\|.\|\fP\fInet\fP
+.)b
+.sh 2 "Subdomains of Existing Domains"
+.pp
+If you want a subdomain of some existing domain, you should find the contact
+point for the parent domain rather than asking one of the above top-level
+registrars. There should be a convention that \fBregistrar\fP@\fIdomain\fP
+or \fBhostmaster\fP@\fIdomain\fP for any given domain will always be an alias
+for that domain's registrar (somewhat analogous to \fBpostmaster\fP), but
+there is no such convention. Try it as a last resort, but first you should
+examine the \fISOA\fP record for the domain and send mail to the ``responsible
+person'' shown therein. You can also try \fIwhois\fP.
diff --git a/contrib/bind/doc/bog/types.me b/contrib/bind/doc/bog/types.me
new file mode 100644
index 0000000..9d14111
--- /dev/null
+++ b/contrib/bind/doc/bog/types.me
@@ -0,0 +1,163 @@
+.\" ++Copyright++ 1986, 1988, 1995
+.\" -
+.\" Copyright (c) 1986, 1988, 1995
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\" -
+.\" Portions Copyright (c) 1993 by Digital Equipment Corporation.
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies, and that
+.\" the name of Digital Equipment Corporation not be used in advertising or
+.\" publicity pertaining to distribution of the document or software without
+.\" specific, written prior permission.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
+.\" WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
+.\" OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
+.\" CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+.\" DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+.\" PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+.\" ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+.\" SOFTWARE.
+.\" -
+.\" --Copyright--
+.\"
+.\" @(#)types.me 6.3 (Berkeley) 9/19/89
+.\"
+.sh 1 "Types of Zones"
+.pp
+A ``zone'' is a point of delegation in the DNS tree. It contains all names
+from a certain point ``downward'' except those which are delegated to other
+zones. A ``delegation point'' has one or more \fINS\fP records in the
+``parent zone'', which should be matched by equivalent \fINS\fP records at
+the root of the ``delegated zone'' (i.e., the ``@'' name in the zone file).
+.pp
+Understanding the difference between a ``zone'' and a ``domain'' is crucial
+to the proper operation of a name server. As an example, consider the
+\s-1DEC.COM\s+1 \fIdomain\fP, which includes names such as
+\s-1POBOX1.PA.DEC.COM\s+1 and \s-1QUABBIN.CRL.DEC.COM\s+1 even though
+the \s-1DEC.COM\s+1 \fIzone\fP includes only \fIdelegations\fP for the
+\s-1PA.DEC.COM\s+1 and \s-1CRL.DEC.COM\s+1 zones. A zone can map exactly
+to a single domain, but could also include only part of a domain (the rest
+of which could be delegated to other name servers). Technically speaking,
+every name in the DNS tree is a ``domain'', even if it is ``terminal'', that
+is, has no ``subdomains''. Technically speaking, every subdomain is a domain
+and every domain except the root is also a subdomain. The terminology is not
+intuitive and you would do well to read RFC's 1033, 1034, and 1035 to gain a
+complete understanding of this difficult and subtle topic.
+.pp
+Though \s-1BIND\s+1 is a \fIDomain\fP Name Server, it deals primarily in terms
+of \fIzones\fP. The \fIprimary\fP and \fIsecondary\fP declarations in the
+\fInamed.boot\fP file specify \fIzones\fP, not \fIdomains\fP. When you ask
+someone if they are willing to be a secondary server for your ``domain'', you
+are actually asking for secondary service for some collection of \fIzones\fP.
+.pp
+Each zone will have one ``primary'' server, which loads the zone contents
+from some local file which is edited by humans or perhaps generated
+mechanically from some other local file which is edited by humans. Then
+there will be some number of ``secondary'' servers, which load the zone
+contents using the \s-1IP/DNS\s+1 protocol (that is, the secondary servers will
+contact the primary and fetch the zone using \s-1IP/TCP\s+1). This set of
+servers (the primary and all of the secondaries) should be listed in the
+\fINS\fP records in the parent zone, which will constitute a ``delegation''.
+This set of servers must also be listed in the zone file itself, usually
+under the ``@'' name which is a magic cookie that means the ``top level''
+or ``root'' of current zone. You can list servers in the zone's
+top-level ``@'' \fINS\fP records that are not in the parent's \fINS\fP
+delegation, but you cannot list servers in the parent's delegation that are
+not present in the zone's ``@''. Any servers listed in the \fINS\fP records
+must be configured as authoritative (either primary or secondary) for the
+zone. If a server listed in a \fINS\fP record is not authoritative, it
+will respond with a ``lame delegation'' when queried.
+.sh 1 "Types of Servers"
+.pp
+Servers do not really have ``types''. A server can be a primary for some
+zones and a secondary for others, or it can be only a primary, or only a
+secondary, or it can serve no zones and just answer queries via its ``cache''.
+Previous versions of this document referred to servers as ``master'' and
+``slave'' but we now feel that those distinctions \(em and the assignment of
+a ``type'' to a name server \(em are not useful.
+.sh 2 "Caching Only Server"
+.pp
+All servers are caching servers. This means that the server caches the
+information that it receives for use until the data expires. A \fICaching
+Only Server\fP is a server that is not authoritative for any zone. This
+server services queries and asks other servers, who have the authority, for
+the information needed. All servers keep data in their cache until the data
+expires, based on a \fITTL\fP (``Time To Live'') field which is maintained
+for all resource records.
+.sh 2 "Remote Server"
+.pp
+A Remote Server is an option given to people who would like to use
+a name server from their workstation or on a machine that has a limited
+amount of memory and CPU cycles.
+With this option you can run all of the networking programs that use
+the name server without the name server running on the local machine.
+All of the queries are serviced by a name server that is running on another
+machine on the network.
+A host which has an
+\fI/etc/resolv.conf\fP file listing only remote hosts, and which does not
+run a name server of its own, is sometimes called a Remote Server (because
+the actual server is remote?) but more
+often it is called simply a DNS Client.
+This kind of host is technically not a ``server'',
+since it has no cache and does not answer queries.
+.sh 2 "Slave Server"
+.pp
+A Slave Server is a server that always forwards queries it cannot
+satisfy from its cache, to a fixed list of \fIforwarding\fP servers
+instead of interacting
+with the name servers for the root and other domains.
+The queries to the \fIforwarding servers\fP are recursive queries.
+There may be one or more forwarding servers, and they are tried in turn
+until the list is exhausted.
+A Slave and forwarder configuration is typically used when you do not
+wish all the servers at a given site to interact with the rest
+of the Internet servers. A typical scenario would involve a number of
+workstations and a departmental timesharing machine with Internet
+access. The workstations might be
+administratively prohibited from having Internet access.
+To give the workstations the appearance of access to the Internet
+domain system, the workstations could be Slave servers to the timesharing
+machine which would forward the queries and interact with other
+name servers to resolve the query before returning the answer.
+An added benefit of using the forwarding feature is that the central
+machine develops a much more complete cache of information that
+all the workstations can take advantage of. The use of Slave mode
+and forwarding is discussed further under the description of
+the \fInamed\fP bootfile commands.
+.pp
+There is no prohibition against declaring a server to be a \fIslave\fP
+even though it has \fIprimary\fP and/or \fIsecondary\fP zones as well;
+the effect will still be that anything in the local server's cache or
+zones will be answered, and anything else will be forwarded using the
+\fIforwarders\fP list.
diff --git a/contrib/bind/doc/bog/ucbhosts b/contrib/bind/doc/bog/ucbhosts
new file mode 100644
index 0000000..2cb2635
--- /dev/null
+++ b/contrib/bind/doc/bog/ucbhosts
@@ -0,0 +1,118 @@
+.\" ++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--
+.\"
+.\" @(#)ucbhosts 6.3 (Berkeley) 2/8/89
+.\"
+.\" .ne 48v
+.\" .bp
+.sh 3 "Hosts"
+.(b L
+;
+; @(#)ucb-hosts 1.2 (berkeley) 88/02/05
+;
+.TS
+l l l l l s.
+@ IN SOA ucbvax\fB.\fPBerkeley\fB.\fPEdu\fB.\fP kjd\fB.\fPmonet\fB.\fPBerkeley\fB.\fPEdu\fB.\fP (
+.T&
+l l l l l.
+ 1988020501 ; Serial
+ 10800 ; Refresh
+ 1800 ; Retry
+ 3600000 ; Expire
+ 259200 ) ; Minimum
+.T&
+l l l l s.
+ IN NS ucbarpa\fB.\fPBerkeley\fB.\fPEdu\fB.\fP
+ IN NS ucbvax\fB.\fPBerkeley\fB.\fPEdu\fB.\fP
+localhost IN A 127\fB.\fP1
+ ; note that 127.1 is the same as 127.0.0.1; see inet(3n)
+ucbarpa IN A 128\fB.\fP32\fB.\fP4
+ IN A 10\fB.\fP0\fB.\fP0\fB.\fP78
+ IN HINFO VAX-11/780 UNIX
+arpa IN CNAME ucbarpa
+ernie IN A 128\fB.\fP32\fB.\fP6
+ IN HINFO VAX-11/780 UNIX
+ucbernie IN CNAME ernie
+monet IN A 128\fB.\fP32\fB.\fP7
+ IN A 128\fB.\fP32\fB.\fP130\fB.\fP6
+ IN HINFO VAX-11/750 UNIX
+ucbmonet IN CNAME monet
+ucbvax IN A 10\fB.\fP2\fB.\fP0\fB.\fP78
+ ; 128.32.10 means 128.32.0.10; see inet(3n)
+ IN A 128\fB.\fP32\fB.\fP10
+ ; HINFO and WKS are widely unused,
+ ; but we'll show them as examples.
+ IN HINFO VAX-11/750 UNIX
+ IN WKS 128.32.0.10 TCP ( echo telnet
+ discard sunrpc sftp
+ uucp-path systat daytime
+ netstat qotd nntp
+ link chargen ftp
+ auth time whhois mtp
+ pop rje finger smtp
+ supdup hostnames
+ domain
+ nameserver )
+vax IN CNAME ucbvax
+toybox IN A 128\fB.\fP32\fB.\fP131\fB.\fP119
+ IN HINFO Pro350 RT11
+toybox IN MX 0 monet.Berkeley.Edu.
+csrg IN MX 0 Ralph.CS
+ IN MX 0 Zhou.CS
+ IN MX 0 Painter.CS
+ IN MX 0 Riggle.CS
+ IN MX 0 Terry.CS
+ IN MX 0 Kevin.CS
+.TE
+.)b
+.\" .bp
diff --git a/contrib/bind/doc/bog/ucbhosts.rev b/contrib/bind/doc/bog/ucbhosts.rev
new file mode 100644
index 0000000..16207af
--- /dev/null
+++ b/contrib/bind/doc/bog/ucbhosts.rev
@@ -0,0 +1,86 @@
+.\" ++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--
+.\"
+.\" @(#)ucbhosts.rev 6.3 (Berkeley) 9/19/89
+.\"
+.ne 22v
+.sh 3 "host.rev"
+.(b L
+
+;
+; @(#)ucb-hosts.rev 1.1 (Berkeley) 86/02/05
+;
+.TS
+l l l l l s.
+@ IN SOA ucbvax\fB.\fPBerkeley\fB.\fPEdu\fB.\fP kjd\fB.\fPmonet\fB.\fPBerkeley\fB.\fPEdu\fB.\fP (
+.T&
+l l l l l.
+ 1986020501 ; Serial
+ 10800 ; Refresh
+ 1800 ; Retry
+ 3600000 ; Expire
+ 259200 ) ; Minimum
+.T&
+l l l l s.
+ IN NS ucbarpa\fB.\fPBerkeley\fB.\fPEdu\fB.\fP
+ IN NS ucbvax\fB.\fPBerkeley\fB.\fPEdu\fB.\fP
+0\fB.\fP0 IN PTR Berkeley-net\fB.\fPBerkeley\fB.\fPEDU\fB.\fP
+ IN A 255\fB.\fP255\fB.\fP255\fB.\fP0
+0\fB.\fP130 IN PTR csdiv-net\fB.\fPBerkeley\fB.\fPEDU\fB.\fP
+4\fB.\fP0 IN PTR ucbarpa\fB.\fPBerkeley\fB.\fPEdu\fB.\fP
+6\fB.\fP0 IN PTR ernie\fB.\fPBerkeley\fB.\fPEdu\fB.\fP
+7\fB.\fP0 IN PTR monet\fB.\fPBerkeley\fB.\fPEdu\fB.\fP
+10\fB.\fP0 IN PTR ucbvax\fB.\fPBerkeley\fB.\fPEdu\fB.\fP
+6\fB.\fP130 IN PTR monet\fB.\fPBerkeley\fB.\fPEdu\fB.\fP
+.TE
+.)b
diff --git a/contrib/bind/doc/misc/FAQ.1of2 b/contrib/bind/doc/misc/FAQ.1of2
new file mode 100644
index 0000000..ab55bea
--- /dev/null
+++ b/contrib/bind/doc/misc/FAQ.1of2
@@ -0,0 +1,1339 @@
+Newsgroups: comp.protocols.tcp-ip.domains,comp.answers,news.answers
+Path: vixie!news1.digital.com!uunet!in1.uu.net!usc!rutgers!njitgw.njit.edu!hertz.njit.edu!cdp2582
+From: cdp@njit.edu (Chris Peckham)
+Subject: comp.protocols.tcp-ip.domains Frequently Asked Questions (FAQ) (Part 1 of 2)
+Message-ID: <cptd-faq-1-810621452@njit.edu>
+Followup-To: comp.protocols.tcp-ip.domains
+Originator: cdp2582@hertz.njit.edu
+Keywords: BIND,DOMAIN,DNS
+Sender: news@njit.edu
+Supersedes: <cptd-faq-1-807632375@njit.edu>
+Nntp-Posting-Host: hertz.njit.edu
+X-Posting-Frequency: posted on the 1st of each month
+Reply-To: domain-faq@njit.edu (comp.protocols.tcp-ip.domains FAQ comments)
+Organization: NJIT.EDU - New Jersey Institute of Technology, Newark, NJ, USA
+Date: Sat, 9 Sep 1995 04:37:47 GMT
+Approved: news-answers-request@MIT.EDU
+Expires: Sat 14 Oct 95 00:37:32 EDT
+Lines: 1319
+Xref: vixie comp.protocols.tcp-ip.domains:6018 comp.answers:13881 news.answers:49918
+
+Posted-By: auto-faq 3.1.1.2
+Archive-name: internet/tcp-ip/domains-faq/part1
+Revision: 1.6 1995/05/12 18:49:48
+
+
+This FAQ is edited and maintained by Chris Peckham, <cdp@njit.edu>.
+The latest version may always be found for anonymous ftp from
+
+ ftp://rtfm.mit.edu/pub/usenet/news.answers/internet/tcp-ip/domains-faq
+ ftp://ftp.njit.edu/pub/dns/Comp.protocols.tcp-ip.domains.FAQ
+
+If you can contribute any answers for items in the TODO section, please do
+so by sending e-mail to domain-faq@njit.edu ! If you know of any items that
+are not included and you feel that they should be, send the relevant
+information to domain-faq@njit.edu.
+
+
+------------------------------
+
+Date: Fri May 12 14:41:47 EDT 1995
+Subject: Table of Contents
+
+Table of Contents
+=================
+Part 1
+------
+ 0. TO DO
+ 1. INTRODUCTION / MISCELLANEOUS
+ 1.1 What is this newsgroup ?
+ 1.2 More information
+ 1.3 What is BIND and where is the latest version of BIND ?
+ 1.4 How can I find the route between systems ?
+ 1.5 Finding the hostname if you have the tcp-ip address
+ 1.6 How to register a domain name
+ 1.7 Change of Domain name
+ 1.8 How memory and CPU does DNS use ?
+ 1.9 Other things to consider when planning your servers
+ 1.10 Proper way to get NS and reverse IP records into DNS
+ 1.11 How to get my address assign from NIC?
+ 1.12 Is there a block of private IP addresses I can use?
+ 1.13 Cache failed lookups
+ 1.14 What does an NS record really do ?
+ 1.15 DNS ports
+ 1.16 Obtaining the latest cache file
+ 2. UTILITIES
+ 2.1 Utilities to administer DNS zone files
+ 2.2 DIG - Domain Internet Groper
+ 2.3 DNS packet analyzer
+ 2.4 host
+ 2.5 Programming with DNS
+ 2.6 A source of information relating to DNS
+ 3. DEFINITIONS
+ 3.1 TCP/IP Host Naming Conventions
+ 3.2 Slaves and servers with forwarders
+ 3.3 When is a server authoritative?
+ 3.4 Underscore in host-/domain names
+ 3.5 Lame delegation
+ 3.6 What does opt-class field do?
+ 3.7 Top level domains
+ 3.8 Classes of networks
+ 3.9 What is CIDR ?
+ 3.10 What is the rule for glue ?
+
+Part 2
+------
+ 4. CONFIGURATION
+ 4.1 Changing a Secondary server to a Primary
+ 4.2 How do I subnet a Class B Address ?
+ 4.3 Subnetted domain name service
+ 4.4 Recommended format/style of DNS files
+ 4.5 DNS on a system not connected to the Internet
+ 4.6 Multiple Domain configuration
+ 4.7 wildcard MX records
+ 4.8 How to identify a wildcard MX record
+ 4.9 Why are fully qualified domain names recommended ?
+ 4.10 Distributing load using named
+ 4.11 Order of returned records
+ 4.12 resolv.conf
+ 4.13 Delegating authority
+ 4.14 DNS instead of NIS on a Sun OS 4.1.x system
+ 5. PROBLEMS
+ 5.1 No address for root server
+ 5.2 Error - No Root Nameservers for Class XX
+ 5.3 Bind 4.9.x and MX querying?
+ 5.4 Some root nameservers don't know localhost
+ 5.5 MX records and CNAMES and separate A records for MX targets
+ 5.6 NS is a CNAME
+ 5.7 Nameserver forgets own A record
+ 5.8 General problems (core dumps !)
+ 5.9 malloc and DECstations
+ 6. ACKNOWLEDGEMENTS
+
+------------------------------
+
+Date: Wed May 3 12:55:13 EDT 1995
+Subject: Q0 - TO DO list
+
+
+* How to do an initial installation
+* How to change service providers (what happens)
+* Explain the difference between BIND (an implementation) and DNS (spec)
+* Expand the slave/forward section of Q 3.2
+* Add a definition of a "private domain" in discussion (or cut it out)
+* mention mail-to-news gateways for newsgroup, mailing lists, anonymous
+ ftp, etc in what is newsgroup section
+* The evils of wildcard MX records
+
+
+
+-------------------------------
+
+Date: Thu Dec 1 11:08:28 EST 1994
+Subject: Q1.1 - What is this newsgroup ?
+
+comp.protocols.tcp-ip.domains is the usenet newsgroup for discussion
+on issues relating to the Domain Name System (DNS).
+
+This newsgroup is not for issues directly relating to IP routing and
+addressing. Issues of that nature should be directed towards
+comp.protocols.tcp-ip.
+
+
+-------------------------------
+
+
+Date: Fri May 12 13:54:01 EDT 1995
+Subject: Q1.2 - More information
+
+ You can find more information concerning DNS in the following places:
+
+ * The BOG (BIND Operations Guide) - in the BIND distribution
+ * The FAQ included with bind4.9.3 doc/misc/FAQ
+ * DNS and BIND by Albitz and Liu (an O'Reilly & Associates Nutshell
+ handbook)
+ * A number of RFCs (920, 974, 1032, 1034, 1101, 1123, 1178, 1183, 1348,
+ 1535, 1536, 1537, 1591, 1706, 1712, 1713)
+ * The DNS Resource Directory (DNSRD)
+ http://www.dns.net/dnsrd
+ * If you are having troubles relating to sendmail and DNS, you may wish to
+ refer to the USEnet newsgroup comp.mail.sendmail and/or the FAQ for that
+ newsgroup
+ ftp://rtfm.mit.edu/pub/usenet/news.answers/mail/sendmail-faq
+ * Information concerning some frequently asked questions relating to
+ the Internet (i.e., what is the InterNIC, what is an RFC, what is the
+ IETF, etc) may be found for anonymous ftp from
+ ftp://ds.internic.net/fyi/fyi4.txt
+ A version may also be obtained with the URL
+ gopher://ds.internic.net/00/fyi/fyi4.txt
+
+
+-------------------------------
+
+Date: Fri Aug 4 10:18:58 EDT 1995
+Subject: Q1.3 - What is BIND and where is the latest version of BIND ?
+
+Q: What is BIND ?
+
+A: From the BOG Introduction -
+
+ The Berkeley Internet Name Domain (BIND) implements
+ an Internet name server for the BSD operating system.
+ The BIND consists of a server (or ``daemon'') and a
+ resolver library. A name server is a network service
+ that enables clients to name resources or objects and
+ share this information with other objects in the network.
+ This in effect is a distributed data base system for
+ objects in a computer network. BIND is fully integrated
+ into BSD (4.3 and later releases) network programs for
+ use in storing and retrieving host names and address.
+ The system administrator can configure the system to use
+ BIND as a replacement to the older host table lookup of
+ information in the network hosts file /etc/hosts. The
+ default configuration for BSD uses BIND.
+
+Q: Where is the latest non-beta version of BIND ?
+
+A: The latest non-beta version of BIND is version 4.9.2. This can be
+ found for anonymous ftp from
+
+ ftp://gatekeeper.dec.com/pub/misc/vixie/4.9.2-940221.tar.gz
+
+Q: Where is the latest version of 4.9.3 located ?
+
+A: You can reference this URL:
+
+ http://www.isc.org/isc/
+
+ At this time, the latest version of 4.9.3 may be found for anonymous ftp
+ from
+
+ ftp://ftp.vix.com/pub/bind/testing/bind-4.9.3-BETA24.tar.gz
+
+ You will need GNU zip, Larry Wall's patch program (if there are any
+ patch files), and a C compiler to get BIND running from the above
+ mentioned source.
+
+ GNU zip is available for anonymous ftp from
+
+ ftp://prep.ai.mit.edu/pub/gnu/gzip-1.2.4.tar
+
+ patch is available for anonymous ftp from
+
+ ftp://prep.ai.mit.edu/pub/gnu/patch-2.1.tar.gz
+
+------------------------------
+
+Date: Mon Jan 2 13:27:27 EST 1995
+Subject: Q1.4 - How can I find the route between systems
+
+Q: How can I find the path taken by packets between two systems/domains ?
+
+A: Get the source of the 'traceroute' command, compile it and install
+ it on your system.
+
+ One version of this program with additional functionality may be found
+ for anonymous ftp from
+
+ ftp://ftp.nikhef.nl/pub/network/traceroute.tar.Z
+
+ This package is mirrored at
+
+ ftp://ftp.njit.edu/pub/dns/nikhef/traceroute.tar.Z
+
+ Another version may be found for anonymous ftp from
+
+ ftp://ftp.psc.edu/pub/net_tools/traceroute.tar
+
+
+------------------------------
+
+Date: Thu Dec 1 09:55:24 EST 1994
+Subject: Q1.5 - Finding the hostname if you have the tcp-ip address
+
+Q: Can someone tell me how can I find the name of the domain if I know the
+ tcp-ip address of the domain? Is there some kind of service for this?
+
+A: For an address a.b.c.d you can always do:
+
+% nslookup
+> set q=ptr
+> d.c.b.a.in-addr.arpa.
+
+ Most newer version of nslookup (since 4.8.3) will recognize an address,
+ so you can just say:
+
+% nslookup a.b.c.d
+
+ DiG will work like this also:
+
+$ dig -x a.b.c.d
+
+ Host from the contrib/host from the bind distribution may also be used.
+
+-------------------------------
+
+Date: Fri Apr 28 13:16:32 EDT 1995
+Subject: Q1.6 - How to register a domain name
+
+Q: I would like to register a domain. How do I do this ? Can a name be
+ reserved, or must we already have an IP address and be hooked up to the
+ Internet before obtaining a domain name?
+
+A: You can talk to your Internet Service Provider (ISP). They can submit
+ the registration for you. If you are not going to be directly
+ connected, they should be able to offer MX records for your domain
+ for mail delivery (so that mail sent to the new domain will be sent
+ to your "standard" account). In the case where the registration is
+ done by the organization itself, it still makes the whole process
+ much easier if the ISP is approached for secondary servers _before_
+ the InterNIC is approached for registration.
+
+ For information about making the registration yourself, look to the
+ InterNIC !
+
+ ftp://internic.net/templates/
+ gopher://rs.internic.net/
+ http://www.internic.net/infoguide.html
+ http://www.ripe.net
+
+ You will need at least two domain name servers when you register your
+ domain. Many ISP's are willing to provide primary and/or secondary name
+ service for their customers.
+
+ Many times, registration of a domain name can be initiated by sending
+ e-mail to the zone contact. You can obtain the contact in the
+ SOA record for the country, or in a whois server:
+
+ $ nslookup -type=SOA fr.
+ origin = ns1.nic.fr
+ mail addr = nic.nic.fr
+ ...
+
+ The mail address to contact in this case is 'nic@nic.fr' (you must
+ substitute an '@' for the first dot in the mail addr field).
+
+ An alternate method to obtain the e-mail address of the national NIC
+ is the 'whois' server at InterNIC.
+
+ You may be requested to make your request to another email address or
+ using a certain information template/application.
+
+
+-------------------------------
+
+Date: Sun Nov 27 23:32:41 EST 1994
+Subject: Q1.7 - Change of Domain name
+
+Q: We are preparing for a change of our domain name:
+ abc.foobar.com -> foobar.net
+
+ What are the tricks and caveats we should be aware of ?
+
+A: The forward zones are easy and there are a number of ways to do it.
+ One way is the following:
+
+ Have a single db file for the 2 domains, and have a single machine
+ be the primary server for both abc.foobar.com and foobar.net.
+
+ To resolve the host foo in both domains, use a single zone file which
+ merely uses this for the host:
+
+foo IN A 1.2.3.4
+
+ Use a "@" wherever the domain would be used ie for the SOA:
+
+@ IN SOA (...
+
+ Then use this pair of lines in your named.boot:
+
+primary abc.foobar.com db.foobar
+primary foobar.net db.foobar
+
+ The reverse zones should either contain PTRs to both names,
+ or to whichever name you believe to be canonical currently.
+
+-------------------------------
+
+Date: Fri Apr 28 13:52:20 EDT 1995
+Subject: Q1.8 - How memory and CPU does DNS use ?
+
+Q: How much memory and CPU does DNS use ?
+
+A: It can use quite a bit ! The main thing that BIND needs is memory.
+ It uses very little CPU or network bandwidth. The main
+ considerations to keep in mind when planning are:
+
+ 1) How many zones do you have and how large are they ?
+ 2) How many clients do you expect to serve and how active are they ?
+
+ As an example, here is a snapshot of memory usage from CSIRO Division
+ of Mathematics and Statistics, Australia
+
+ Named takes several days to stabalize its memory usage.
+
+ Our main server stabalises at ~10Mb. It takes about 3 days to
+ reach this size from 6 M at startup. This is under Sun OS 4.1.3U1.
+
+ As another example, here is the configuration of ns.uu.net (from late
+ 1994):
+
+ ns.uu.net only does nameservice. It is running a version of BIND
+ 4.9.3 on a Sun Classic with 96 MB of RAM, 220 MB of swap (remember
+ that Sun OS will reserve swap for each fork, even if it is not needed)
+ running Sun OS 4.1.3_U1.
+
+ Joseph Malcolm, of Alternet, states that named generally hovers at
+ 5-10% of the CPU, except after a reload, when it eats it all. He
+ also states that if you are interested in the network connectivity
+ around the system (ns.uu.net is located off of Falls-Church4), a
+ PostScript map is available for anonymous ftp from
+
+ ftp://ftp.uu.net/uunet-info/alternet.map.ps
+
+
+-------------------------------
+
+Date: Mon Jan 2 14:24:51 EST 1995
+Subject: Q1.9 - Other things to consider when planning your servers
+
+ When making the plans to set up your servers, you may want to also
+ consider the following issues:
+
+ A) Server O/S limitations/capacities (which tend to be widely
+ divergent from vendor to vendor)
+ B) Client resolver behavior (even more widely divergent)
+ C) Expected query response time
+ D) Redundancy
+ E) Desired speed of change propagation
+ F) Network bandwidth availability
+ G) Number of zones/subdomain-levels desired
+ H) Richness of data stored (redundant MX records? HINFO records?)
+ I) Ease of administration desired
+ J) Network topology (impacts reverse-zone volume)
+
+ Assuming a best-possible case for the factors above, particularly (A), (B),
+ (C), (F), (G) & (H), it would be possible to run a 1000-node domain
+ using a single lowly 25 or 40 MHz 386 PC with a fairly modest amount of RAM
+ by today's standards, e.g. 4 or 8 Meg. However, this configuration would
+ be slow, unreliable, and would provide no functionality beyond your basic
+ address-to-name and name-to-address mappings.
+
+ Beyond that baseline case, depending on what factors listed above,
+ you may want look at other strategies, such splitting up the DNS
+ traffic among several machines strategically located, possibly larger ones,
+ and/or subdividing your domain itself. There are many options, tradeoffs,
+ and DNS architectural paradigms from which to choose.
+
+
+------------------------------
+
+Date: Mon Jan 2 13:03:53 EST 1995
+Subject: Q1.10 - Proper way to get NS and reverse IP records into DNS
+
+
+Q: Reverse domain registration is separate from forward domain registration.
+ How do I get it updated ?
+
+A: Blocks of network addresses have been delegated by the InterNIC. Check
+ if your network a.b.c.0 is in such a block by using nslookup:
+
+ nslookup -type=soa c.b.a.in-addr.arpa.
+ nslookup -type=soa b.a.in-addr.arpa.
+ nslookup -type=soa a.in-addr.arpa.
+
+ One of the above should give you the information you are looking for
+ (the others will return with an error something like `*** No start of
+ authority (SOA) records available for ...')
+ This will give you the email address of the person to whom you should
+ address your change request.
+
+ If none of these works, your network probably has not been delegated
+ by the InterNIC and you need to contact them directly.
+
+ CIDR has meant that the registration is delegated, but registration
+ of in-addr.arpa has always been separate from forward zones - and
+ for good reason - in that the forward and reverse zones may have
+ different policies, contents etc, may be served by a different set
+ of nameservers, and exist at different times (usually only at point
+ of creation). There isn't a one-to-one mapping between the two, so
+ merging the registration would probably cause more problems than
+ people forgetting/not-knowing that they had to register in-addr.arpa
+ zones separately. For example, there are organizations that have
+ hundreds of networks and two or more domains, with a sprinkling of
+ machines from each network in each of the domains.
+
+
+-------------------------------
+
+Date: Mon Jan 2 13:08:38 EST 1995
+Subject: Q1.11 - How to get my address assign from NIC ?
+
+
+Q: Can anyone tell me how can I get the address from NIC? How many subnets
+ will NIC give to me?
+
+A: You should probably ask your Internet provider to give you an address.
+ These days, addresses are being distributed through the providers,
+ so that they can assign adjacent blocks of addresses to sites that
+ go through the same provider, to permit more efficient routing on
+ the backbones.
+
+ Unless you have thousands of hosts, you probably won't be able to get a
+ class B these days. Instead, you can get a series of class C networks.
+ Large requests will be queried, so be ready to provide a network plan if
+ you ask for more than 16 class C networks.
+
+ If you can't do this through your Internet provider, you can look for a
+ subnet registration form on rs.internic.net. See the answer in this FAQ
+ to the question "How to register a domain name" for a URL to these
+ forms.
+
+-------------------------------
+
+Date: Mon Jan 2 13:12:01 EST 1995
+Subject: Q1.12 -Is there a block of private IP addresses I can use?
+
+
+Q: Is there a block of private IP addresses I can use?
+
+A: This answer may be found in the FAQ for the newsgroup comp.dcom.sys.cisco
+ available for anonymous ftp from
+
+ ftp://rtfm.mit.edu/pub/usenet/comp.dcom.sys.cisco
+
+ There is a block of private IP addresses that you can use. However
+ whether you wish to do so is an issue of some debate.
+
+ There are two RFCs which discuss this issue, and present opposing
+ views:
+
+1597 Address Allocation for Private Internets. Y. Rekhter, B.
+ Moskowitz, D. Karrenberg & G. de Groot. March 1994. (Format:
+ TXT=17430 bytes)
+
+1627 Network 10 Considered Harmful (Some Practices Shouldn't be
+ Codified). E. Lear, E. Fair, D. Crocker & T. Kessler. June 1994.
+ (Format: TXT=18823 bytes)
+
+ Neither one of these RFCs is anything more than a set of informational
+ guidelines; they are *not* words to live by (remember that RFC stands
+ for Request For Comments). If you're seriously considering using
+ private IP addresses, please read them both.
+
+ In any event, RFC 1597 documents the allocation of the following
+ addresses for use by ``private internets'':
+
+ 10.0.0.0 - 10.255.255.255
+ 172.16.0.0 - 172.31.255.255
+ 192.168.0.0 - 192.168.255.255
+
+ Most importantly, it is vital that nothing using these addresses
+ should ever connect to the global Internet, or have plans to do so.
+ Please read the above RFCs before considering implementing such
+ a policy.
+
+
+-------------------------------
+
+Date: Mon Jan 2 13:55:50 EST 1995
+Subject: Q1.13 - Cache failed lookups
+
+Q: Does BIND cache negative answers (failed DNS lookups) ?
+
+A: Yes, BIND 4.9.3 will cache negative answers.
+
+
+-------------------------------
+
+Date: Fri Feb 10 15:35:07 EST 1995
+Subject: Q1.14 - What does an NS record really do ?
+
+Q: What does a NS record really do ?
+
+A: The NS records in your zone data file pointing to the zone's name
+ servers (as opposed to the servers of delegated subdomains) don't do
+ much. They're essentially unused, though they are returned in the
+ authority section of reply packets from your name servers.
+
+-------------------------------
+
+Date: Fri Feb 10 15:40:10 EST 1995
+Subject: Q1.15 - DNS ports
+
+Q: Does anyone out there have any information/experience on exactly which
+ TCP/UDP ports DNS uses to send and receive queries ?
+
+A: Use the following chart:
+
+ Prot Src Dst Use
+ udp 53 53 Queries between servers (eg, recursive queries)
+ Replies to above
+ tcp 53 53 Queries with long replies between servers, zone
+ transfers Replies to above
+ udp >1023 53 Client queries (sendmail, nslookup, etc ...)
+ udp 53 >1023 Replies to above
+ tcp >1023 53 Client queries with long replies
+ tcp 53 >1023 Replies to above
+
+ Note: >1023 is for non-priv ports on Un*x clients. On other client
+ types, the limit may be more or less.
+
+ Another point to keep in mind when designing filters for DNS is that a
+ DNS server uses port 53 both as the source and destination for it's
+ queries. So, a client queries an initial server from an unreserved
+ port number to UDP port 53. If the server needs to query another
+ server to get the required info, it sends a UDP query to that server
+ with both source and destination ports set to 53. The response is then
+ sent with the same src=53 dest=53 to the first server which then
+ responds to the original client from port 53 to the original source
+ port number.
+
+ The point of all this is that putting in filters to only allow UDP
+ between a high port and port 53 will not work correctly, you must also
+ allow the port 53 to port 53 UDP to get through.
+
+ Also, ALL versions of BIND use TCP for queries in some cases. The
+ original query is tried using UDP. If the response is longer than
+ the allocated buffer, the resolver will retry the query using a TCP
+ connection. If you block access to TCP port 53 as suggested above,
+ you may find that some things don't work.
+
+ Newer version of BIND allow you to configure a list of IP addresses
+ from which to allow zone transfers. This mechanism can be used to
+ prevent people from outside downloading your entire namespace.
+
+
+-------------------------------
+
+
+Date: Fri Apr 28 14:19:10 EDT 1995
+Subject: Q1.16 - Obtaining the latest cache file
+
+Q: What is the cache file and where can I obtain the latest version ?
+
+A: From the "Name Server Operations Guide"
+
+ 6.3. Cache Initialization
+
+ 6.3.1. root.cache
+
+ The name server needs to know the servers that
+ are the authoritative name servers for the root
+ domain of the network. To do this we have to prime
+ the name server's cache with the addresses of these
+ higher authorities. The location of this file is
+ specified in the boot file. ...
+
+ A copy of the comments in the file available from the InterNIC follow:
+
+ ; This file holds the information on root name servers needed to
+ ; initialize cache of Internet domain name servers
+ ; (e.g. reference this file in the "cache . <file>"
+ ; configuration file of BIND domain name servers).
+ ;
+ ; This file is made available by InterNIC registration services
+ ; under anonymous FTP as
+ ; file /domain/named.root
+ ; on server FTP.RS.INTERNIC.NET
+ ; -OR- under Gopher at RS.INTERNIC.NET
+ ; under menu InterNIC Registration Services (NSI)
+ ; submenu InterNIC Registration Archives
+ ; file named.root
+ ;
+ ; last update: Oct 5, 1994
+ ; related version of root zone: 1994100500
+ ;
+
+ If you have a version of dig running, you may obtain the information with
+ the command
+
+ dig @ns.internic.net . ns
+
+
+-------------------------------
+
+
+Date: Mon Jan 2 13:13:49 EST 1995
+Subject: Q2.1 - Utilities to administer DNS zone files
+
+Q: I am wondering if there are utilities available to ease the
+ administration of the zone files in the DNS.
+
+A: There are a few. Two common ones are h2n and makezones. Both are perl
+ scripts. h2n is used to convert host tables into zone data files. It
+ is available for anonymous ftp from
+
+ ftp://ftp.uu.net/published/oreilly/nutshell/dnsbind/dns.tar.Z.
+
+ makezones works from a single file that looks like a forward zone file,
+ with some additional syntax for special cases. It is included in the
+ current BIND distribution. The newest version is always available for
+ anonymous ftp from
+
+ ftp://ftp.cus.cam.ac.uk/pub/software/programs/DNS/makezones
+
+ This package is mirrored at
+
+ ftp://ftp.njit.edu/pub/dns/cus.cam.ac/makezones
+
+ More information may be found using the DNS Resource Directory
+
+ http://www.dns.net/dnsrd
+
+
+-------------------------------
+
+Date: Thu Dec 1 11:09:11 EST 1994
+Subject: Q2.2 - DIG - Domain Internet Groper
+
+Q: Where can I find the latest version of DIG ?
+
+A: The latest and greatest, official, accept-no-substitutes version of DiG
+ is the one that comes with BIND. Get the latest kit.
+
+-------------------------------
+
+Date: Mon May 15 12:57:42 EDT 1995
+Subject: Q2.3 -DNS packet analyser
+
+Q: I'm looking for a Ethernet packet analyser of public domain or standard
+ (like tcpdump, snoop, packetman) that is able to determine DNS data
+ field protocol
+
+A: There is a free ethernet analyser called Ethload available for PC's
+ running DOS. The latest filename is ETHLD104.ZIP. It understands lots
+ of protocols including TCP/UDP. It'll look inside there and display
+ DNS/BOOTP/ICMP packets etc. (Ed. note: something nice for someone to
+ add to tcpdump ;^) ). Depending on the ethernet controller it's given
+ it'll perform slightly differently. It handles NDIS/Novell/Packet
+ drivers. It works best with Novell's promiscuous mode drivers.
+ A A SimTel mirror site should have the program available for anonymous
+ ftp. As an example,
+
+ ftp://oak.oakland.edu/SimTel/msdos/lan/ethld104.zip
+
+
+-------------------------------
+
+Date: Sun Dec 4 21:15:38 EST 1994
+Subject: Q2.4 - host
+
+A section from the host man page:
+
+ host looks for information about Internet hosts and domain
+ names. It gets this information from a set of intercon-
+ nected servers that are spread across the world. The infor-
+ mation is stored in the form of "resource records" belonging
+ to hierarchically organized "zones".
+
+ By default, the program simply converts between host names
+ and Internet addresses. However, with the -t, -a and -v
+ options, it can be used to find all of the information about
+ domain names that is maintained by the domain nameserver
+ system. The information printed consists of various fields
+ of the associated resource records that were retrieved.
+
+ The arguments can be either host names (domain names) or
+ numeric Internet addresses.
+
+'host' is compatible with both BIND 4.9 and BIND 4.8
+
+'host' may be found in contrib/host in the BIND distribution. The latest
+version always available for anonymous ftp from
+
+ ftp://ftp.nikhef.nl/pub/network/host.tar.Z
+
+It may also be found for anonymous ftp from
+
+ ftp://ftp.uu.net/networking/ip/dns/host.tar.Z
+
+-------------------------------
+
+Date: Fri Feb 10 15:25:11 EST 1995
+Subject: Q2.5 - Programming with DNS
+
+Q: How can I use DNS information in my program?
+
+A: It depends on precisely what you want to do:
+
+ a) Consider whether you need to write a program at all. It may well
+ be easier to write a shell program (e.g. using awk or perl) to parse
+ the output of dig, host or nslookup.
+
+ b) If all you need is names and addresses, there will probably be
+ system routines 'gethostbyname' and 'gethostbyaddr' to provide this
+ information.
+
+ c) If you need more details, then there are system routines (res_query
+ and res_search) to assist with making and sending DNS queries.
+ However, these do not include a routine to parse the resulting answer
+ (although routines to assist in this task are provided). There is a
+ separate library available that will take a DNS response and unpick
+ it into its constituent parts, returning a C structure that can be
+ used by the program. The source for this library is available for
+ anonymous ftp from
+
+ ftp://hpux.csc.liv.ac.uk/hpux/Networking/Admin/resparse-*
+
+
+-------------------------------
+
+
+Date: Wed May 3 12:46:50 EDT 1995
+Subject: Q2.6 - A source of information relating to DNS
+
+Q: Where can I find utilities and tools to help me manage my zone files ?
+
+A: There are several tools available. Please refer to the "tools" section
+ of the DNS resources directory:
+
+ http://www.dns.net/dnsrd/tools.html
+
+
+-------------------------------
+
+
+Date: Fri May 12 14:33:40 EDT 1995
+Subject: Q3.1 - TCP/IP Host Naming Conventions
+
+Q: Is a guide available relating to naming systems ?
+
+A: One guide/resource is RFC 1178, "Choosing a Name for Your Computer",
+ which is available via anonymous FTP from
+
+ ftp://ftp.internic.netrfc/rfc1178.txt
+
+ RFCs (Request For Comments) are specifications and guidelines for how
+ many aspects of TCP/IP and the Internet (should) work. Most RFCs are
+ fairly technical documents, and some have semantics that are hotly
+ contested in the newsgroups. But a few, like RFC 1178, are actually
+ good to read for someone who's just starting along a TCP/IP path.
+
+
+-------------------------------
+
+Date: Thu Dec 1 10:32:43 EST 1994
+Subject: Q3.2 - What are slaves and forwarders ?
+
+Q: What are slaves and forwarders ?
+
+A: "forwarders" is a list of NS records that are _prepended_ to a list
+ of NS records to query if the data is not available locally. This
+ allows a rich cache of records to be built up at a centralized
+ location. This is good for sites that have sporadic or very slow
+ connections to the Internet. (demand dial-up, for example) It's
+ also just a good idea for very large distributed sites to increase
+ the chance that you don't have to go off to the Internet to get an
+ IP address. (sometimes for addresses across the street!)
+
+ "slave" modifies this to say to replace the list of NS records
+ with the forwarders entry, instead of prepending to it. This is
+ for firewalled environments, where the nameserver can't directly
+ get out to the Internet at all.
+
+ "slave" is meaningless (and invalid, in late-model BINDs) without
+ "forwarders". "forwarders" is an entry in named.boot, and therefore
+ applies only to the nameserver (not to resolvers).
+
+-------------------------------
+
+Date: Mon Jan 2 13:15:13 EST 1995
+Subject: Q3.3 - When is a server authoritative?
+
+
+Q: What criteria does a server use to determine if it is authoritative
+ for a domain?
+
+A: In the case of BIND:
+ 1) The server contains current data in files for the zone in
+ question (Data must be current for secondaries, as defined
+ in the SOA)
+ 2) The server is told that it is authoritative for the zone, by
+ a 'primary' or 'secondary' keyword in /etc/named.boot.
+ 3) The server does an error-free load of the zone.
+
+Q: I have set up a DNS where there is an SOA record for
+ the domain, but the server still does not consider itself
+ authoritative. (I used nslookup and set server=the correct machine.)
+ It seems to me that something is not matching up somewhere. I suspect
+ that this is because the service provider has not given us control
+ over the IP numbers in our own domain, and so while the machine listed
+ has an A record for an address, there is no corresponding PTR record.
+
+A: That's possible too, but is unrelated to the first question.
+ You need to be delegated a zone before outside people will start
+ talking to your server. However, a server can still be authoritative
+ for a zone even though it hasn't been delegated authority (it's just
+ that only the people who use that as their server will see the data).
+
+ A server may consider itself non-authoritative even though it's a
+ primary if there is a syntax error in the zone (see point 3 above).
+
+Q: I always believe that it was the NS record that defined authoritative
+ servers.
+
+A: Nope, delegation is a separate issue from authoritativeness.
+ You can still be authoritative, but not delegated. (you can also be
+ delegated, but not authoritative -- that's a "lame delegation")
+
+Q: We have had problems in the past from servers that were
+ authoritative (primary or secondary) but no NS, so other thought they
+ were not. Some resolvers get very confused when they get non-
+ authoritative data from the primary server.
+
+A: Yes, that's a lame delegation. That's not caused by what you said,
+ but rather by a server which is _not_ authoritative for a zone, yet
+ someone else (the parent) is saying that a server is authoritative
+ (via the NS records).
+
+ The set of NS records in the parent zone must be a subset of the
+ authoritative servers to avoid lame delegations.
+
+
+-------------------------------
+
+Date: Fri Apr 28 13:26:37 EDT 1995
+Subject: Q3.4 - underscore in host-/domainnames
+
+
+Q: I had a quick look on whether underscores are allowed in host- or
+ domainnames.
+
+ RFC 1033 allows them.
+ RFC 1035 doesn't.
+ RFC 1123 doesn't.
+ dnswalk complains about them.
+
+ Which RFC is the final authority these days?
+
+A: Actually RFC 1035 deals with names of machines or names of
+ mail domains. i.e "_" is not permitted in a hostname or on the
+ RHS of the "@" in local@domain.
+
+ Underscore is permitted where ever the domain is NOT one of
+ these types of addresses.
+
+ In general the DNS mostly contains hostnames and mail domainnames.
+ This will change as new resource record types for authenticating DNS
+ queries start to appear.
+
+ The latest version of 'host' checks for illegal characters in A/MX
+ record names and the NS/MX target names.
+
+ After saying all of that, remember that RFC 1123 is a Required Internet
+ Standard (per RFC 1720), and RFC 1033 isn't. Even 1035 isn't a required
+ standard. Therefore, RFC 1123 wins, no contest.
+
+
+-------------------------------
+
+Date: Fri Dec 2 15:03:56 EST 1994
+Subject: Q3.5 - Lame delegation
+
+Q: What is lame delegation ?
+
+A: Two things are required for a lame delegation:
+ 1) A nameserver X is delegated as authoritative for a zone.
+ 2) Nameserver X is not performing nameservice for that zone.
+
+ Try to think of a lame delegation as a long-term condition, brought
+ about by a misconfiguration somewhere. Bryan Beecher's 1992 LISA
+ paper on lame delegations is good to read on this. The problem
+ really lies in misconfigured nameservers, not "lameness" brought
+ about by transient outages. The latter is common on the Internet
+ and hard to avoid, while the former is correctable.
+
+ In order to be performing nameservice for a zone, it must have
+ (presumed correct) data for that zone, and it must be answering
+ authoritatively to resolver queries for that zone. (The AA bit is
+ set in the flags section)
+
+ The "classic" lame delegation case is when nameserver X is delegated
+ as authoritative for domain Y, yet when you ask Y about X, it
+ returns non-authoritative data.
+
+ Here's an example that shows what happens most often (using dig,
+ dnswalk, and doc to find).
+
+ Let's say the domain bogus.com gets registered at the NIC and they
+ have listed 2 primary name servers, both from their *upstream*
+ provider:
+
+ bogus.com IN NS ns.bogus.com
+ bogus.com IN NS upstream.com
+ bogus.com IN NS upstream1.com
+
+ So the root servers have this info. But when the admins at
+ bogus.com actually set up their zone files they put something like:
+
+ bogus.com IN NS upstream.com
+ bogus.com IN NS upstream1.com
+
+ So your name server may have the nameserver info cached (which it
+ may have gotten from the root). The root says "go ask ns.bogus.com"
+ since they are authoritative
+
+ This is usually from stuff being registered at the NIC (either
+ nic.ddn.mil or rs.internic.net), and then updated later, but the
+ folks who make the updates later never let the folks at the NIC know
+ about it.
+
+Q: How can I see if the server is "lame" ?
+
+A: Go to the authoritative servers one level up, and ask them who
+ they think is authoritative, and then go ask each one of those
+ delegees if they think that they themselves are authoritative. If any
+ responds "no", then you know who the lame delegation is, and who is
+ delegating lamely to them. You can then send off a message to the
+ administrators of the level above.
+
+ The 'lamers' script from Byran Beecher really takes care of all this
+ for you. It parses the lame delegation notices from BIND's syslog
+ and summarizes them for you. It may be found in the contrib section
+ of the latest BIND distribution. The latest version is available
+ for anonymous ftp from
+
+ ftp://terminator.cc.umich.edu/dns/lame-delegations/
+
+ If you want to actively check for lame delegations, you can use 'doc'
+ and 'dnswalk'. You can check things manually with 'dig'.
+
+-------------------------------
+
+Date: Thu Dec 1 11:10:39 EST 1994
+Subject: Q3.6 - What does opt-class field do?
+
+Q: Just something I was wondering about: What does the opt-class
+ field in an name database do (the one that always says IN)?
+ What would happen if I put something else there instead?
+
+A: This field is the address class. From the BOG -
+
+ ...is the address class; currently, only one class
+ is supported: IN for internet addresses and other
+ internet information. Limited support is included for
+ the HS class, which is for MIT/Athena ``Hesiod''
+ information.
+
+-------------------------------
+
+Date: Fri Feb 10 14:49:54 EST 1995
+Subject: Q3.7 - Top level domains
+
+
+A section from RFC 1591:
+
+ 2. The Top Level Structure of the Domain Names
+
+ In the Domain Name System (DNS) naming of computers there is a
+ hierarchy of names. The root of system is unnamed. There are a set
+ of what are called "top-level domain names" (TLDs). These are the
+ generic TLDs (EDU, COM, NET, ORG, GOV, MIL, and INT), and the two
+ letter country codes from ISO-3166. It is extremely unlikely that
+ any other TLDs will be created.
+
+[ Ed note: the ISO-3166 country codes may be found for anonymous ftp from:
+
+ ftp://ftp.isi.edu/in-notes/iana/assignments/country-codes
+ ftp://ftp.ripe.net/iso3166-codes
+]
+
+ Under each TLD may be created a hierarchy of names. Generally, under
+ the generic TLDs the structure is very flat. That is, many
+ organizations are registered directly under the TLD, and any further
+ structure is up to the individual organizations.
+
+ In the country TLDs, there is a wide variation in the structure, in
+ some countries the structure is very flat, in others there is
+ substantial structural organization. In some country domains the
+ second levels are generic categories (such as, AC, CO, GO, and RE),
+ in others they are based on political geography, and in still others,
+ organization names are listed directly under the country code. The
+ organization for the US country domain is described in RFC 1480.
+
+ Each of the generic TLDs was created for a general category of
+ organizations. The country code domains (for example, FR, NL, KR,
+ US) are each organized by an administrator for that country. These
+ administrators may further delegate the management of portions of the
+ naming tree. These administrators are performing a public service on
+ behalf of the Internet community. Descriptions of the generic
+ domains and the US country domain follow.
+
+ Of these generic domains, five are international in nature, and two
+ are restricted to use by entities in the United States.
+
+ World Wide Generic Domains:
+
+ COM - This domain is intended for commercial entities, that is
+ companies. This domain has grown very large and there is
+ concern about the administrative load and system performance if
+ the current growth pattern is continued. Consideration is
+ being taken to subdivide the COM domain and only allow future
+ commercial registrations in the subdomains.
+
+ EDU - This domain was originally intended for all educational
+ institutions. Many Universities, colleges, schools,
+ educational service organizations, and educational consortia
+ have registered here. More recently a decision has been taken
+ to limit further registrations to 4 year colleges and
+ universities. Schools and 2-year colleges will be registered
+ in the country domains (see US Domain, especially K12 and CC,
+ below).
+
+ NET - This domain is intended to hold only the computers of network
+ providers, that is the NIC and NOC computers, the
+ administrative computers, and the network node computers. The
+ customers of the network provider would have domain names of
+ their own (not in the NET TLD).
+
+ ORG - This domain is intended as the miscellaneous TLD for
+ organizations that didn't fit anywhere else. Some non-
+ government organizations may fit here.
+
+ INT - This domain is for organizations established by international
+ treaties, or international databases.
+
+ United States Only Generic Domains:
+
+ GOV - This domain was originally intended for any kind of government
+ office or agency. More recently a decision was taken to
+ register only agencies of the US Federal government in this
+ domain. State and local agencies are registered in the country
+ domains (see US Domain, below).
+
+ MIL - This domain is used by the US military.
+
+ Example country code Domain:
+
+ US - As an example of a country domain, the US domain provides for
+ the registration of all kinds of entities in the United States
+ on the basis of political geography, that is, a hierarchy of
+ <entity-name>.<locality>.<state-code>.US. For example,
+ "IBM.Armonk.NY.US". In addition, branches of the US domain are
+ provided within each state for schools (K12), community
+ colleges (CC), technical schools (TEC), state government
+ agencies (STATE), councils of governments (COG),libraries
+ (LIB), museums (MUS), and several other generic types of
+ entities (see RFC 1480 for details).
+
+
+A section from RFC 1480:
+
+ 2. NAMING STRUCTURE
+
+ The US Domain hierarchy is based on political geography. The
+ basic name space under US is the state name space, then the
+ "locality" name space, (like a city, or county) then
+ organization or computer name and so on.
+
+ For example:
+
+ BERKELEY.CA.US
+ PORTLAND.WA.US
+
+ There is of course no problem with running out of names.
+
+ The things that are named are individual computers.
+
+ If you register now in one city and then move, the database can
+ be updated with a new name in your new city, and a pointer can
+ be set up from your old name to your new name. This type of
+ pointer is called a CNAME record.
+
+ The use of unregistered names is not effective and causes problems
+ for other users. Inventing your own name and using it without
+ registering is not a good idea.
+
+ In addition to strictly geographically names, some special names
+ are used, such as FED, STATE, AGENCY, DISTRICT, K12, LIB, CC,
+ CITY, and COUNTY. Several new name spaces have been created,
+ DNI, GEN, and TEC, and a minor change under the "locality" name
+ space was made to the existing CITY and COUNTY subdomains by
+ abbreviating them to CI and CO. A detailed description
+ follows.
+
+ Below US, Parallel to States:
+ -----------------------------
+
+ "FED" - This branch may be used for agencies of the federal
+ government. For example: <org-name>.<city>.FED.US
+
+ "DNI" - DISTRIBUTED NATIONAL INSTITUTES - The "DNI" branch was
+ created directly under the top-level US. This branch is to be used
+ for distributed national institutes; organizations that span state,
+ regional, and other organizational boundaries; that are national in
+ scope, and have distributed facilities. For example:
+ <org-name>.DNI.US.
+
+ Name Space Within States:
+ ------------------------
+
+ "locality" - cities, counties, parishes, and townships. Subdomains
+ under the "locality" would be like CI.<city>.<state>.US,
+ CO.<county>.<state>.US, or businesses. For example:
+ Petville.Marvista.CA.US.
+
+ "CI" - This branch is used for city government agencies and is a
+ subdomain under the "locality" name (like Los Angeles). For example:
+ Fire-Dept.CI.Los-Angeles.CA.US.
+
+ "CO" - This branch is used for county government agencies and is a
+ subdomain under the "locality" name (like Los Angeles). For example:
+ Fire-Dept.CO.San-Diego.CA.US.
+
+ "K12" - This branch may be used for public school districts. A
+ special name "PVT" can be used in the place of a school district name
+ for private schools. For example: <school-name>.K12.<state>.US and
+ <school-name>.PVT.K12.<state>.US.
+
+ "CC" - COMMUNITY COLLEGES - This branch was established for all state
+ wide community colleges. For example: <school-name>.CC.<state>.US.
+
+ "TEC" - TECHNICAL AND VOCATIONAL SCHOOLS - The branch "TEC" was
+ established for technical and vocational schools and colleges. For
+ example: <school-name>.TEC.<state>.US.
+
+ "LIB" - LIBRARIES (STATE, REGIONAL, CITY, COUNTY) - This branch may
+ be used for libraries only. For example: <lib-name>.LIB.<state>.US.
+
+ "STATE" - This branch may be used for state government agencies. For
+ example: <org-name>.STATE.<state>.US.
+
+ "GEN" - GENERAL INDEPENDENT ENTITY - This branch is for the things
+ that don't fit easily into any other structure listed -- things that
+ might fit in to something like ORG at the top-level. It is best not
+ to use the same keywords (ORG, EDU, COM, etc.) that are used at the
+ top-level to avoid confusion. GEN would be used for such things as,
+ state-wide organizations, clubs, or domain parks. For example:
+ <org-name>.GEN.<state-code>.US.
+
+ The application form for the US domain may be found for anonymous ftp
+ from:
+
+ ftp://internic.net/templates/us-domain-template.txt
+
+ The application form for the EDU, COM, NET, ORG, and GOV domains may be
+ found for anonymous ftp from:
+
+ ftp://internic.net/templates/domain-template.txt
+
+
+-------------------------------
+
+Date: Sun Nov 27 23:32:41 EST 1994
+Subject: Q3.8 - Classes of networks
+
+Q: I am just kind of curious to what exactly the differences in classes
+ of networks are (class A, B, C).
+
+A: An Internet Protocol (IP) address is 32 bit in length, divided into
+ two or three parts (the network address, the subnet address (if present),
+ and the host address. The subnet addresses are only present if the
+ network has been divided into subnetworks. The length of the network,
+ subnet, and host field are all variable.
+
+ There are five different network classes. The leftmost bits indicate
+ the class of the network.
+
+ # bits in # bits in
+ network host
+Class field field Internet Protocol address in binary Ranges
+============================================================================
+ A 7 24 0NNNNNNN.HHHHHHHH.HHHHHHHH.HHHHHHHH 1-127.x.x.x
+ B 14 16 10NNNNNN.NNNNNNNN.HHHHHHHH.HHHHHHHH 128-191.x.x.x
+ C 22 8 110NNNNN.NNNNNNNN.NNNNNNNN.HHHHHHHH 192-223.x.x.x
+ D NOTE 1 1110xxxx.xxxxxxxx.xxxxxxxx.xxxxxxxx 224-239.x.x.x
+ E NOTE 2 11110xxx.xxxxxxxx.xxxxxxxx.xxxxxxxx 240-247.x.x.x
+
+ where N represents part of the network address and H represents part of
+ the host address. When the subnet address is defined, the needed bits
+ are assigned from the host address space.
+
+ NOTE 1: Reserved for multicast groups - RFC 1112
+ NOTE 2: Reserved for future use
+
+ 127.0.0.1 is reserved for local loopback.
+
+ Under the current arrangements, many class A IP numbers will not be
+ assigned whereas class C usage will be at a premium.
+
+-------------------------------
+
+
+Date: Fri Apr 28 13:31:24 EDT 1995
+Subject: Q3.9 - What is CIDR ?
+
+Q: What is CIDR ?
+
+A: CIDR is "Classless Inter-Domain Routing (CIDR). From RFC1517:
+
+ ...Classless Inter-Domain Routing (CIDR) attempts to deal with
+ these problems by defining a mechanism to slow the growth of
+ routing tables and reduce the need to allocate new IP network
+ numbers.
+
+ Much more information may be obtained in RFCs 1467, 1517, 1518, 1520;
+ with primary reference 1519
+
+
+-------------------------------
+
+
+Date: Fri Apr 28 13:31:24 EDT 1995
+Subject: Q3.10 - What is the rule for glue ?
+
+Q: What is the rule for glue ?
+
+A: A glue record is an A record for a name that appears on the right-hand
+ side of a NS record. So, if you have this:
+
+ sub.foobar.com. IN NS dns.sub.foobar.com.
+ dns.sub.foobar.com. IN A 1.2.3.4
+
+ then the second record is a glue record (for the NS record above it).
+
+ You need glue records when -- and only when -- you are delegating
+ authority to a nameserver that "lives" in the domain you are delegating
+ *and* you aren't a secondary server for that domain.
+
+ In other words, in the example above, you need to add an A record
+ for dns.sub.foobar.com since it "lives" in the domain it serves.
+ This boot strapping information is necessary: How are you supposed
+ to find out the IP address of the nameserver for domain FOO if the
+ nameserver for FOO "lives" in FOO?
+
+ If you have this NS record:
+
+ sub.foobar.com. IN NS dns.xyz123.com.
+
+ you do NOT need a glue record, and, in fact, adding one is a very
+ bad idea. If you add one, and then the folks at xyz123.com change
+ the address, then you will be passing out incorrect data.
+
+ Also, unless you actually have a machine called something.IN-ADDR.ARPA,
+ you will never have any glue records present in any of your "reverse"
+ files.
+
+ There is also a sort of implicit glue record that can be useful (or
+ confusing :^) ). If the parent server (abc.foobar.com domain in example
+ above) is a secondary server for the child, then the A record will be
+ fetched from the child server when the zone transfer is done. The glue
+ is still there but it's a little different, it's in the ip address in
+ the named.boot line instead of explicitly in the data. In this case
+ you can leave out the explicit glue A record and leave the manually
+ configured "glue" in just the one place in the named.boot file.
+
+ RFC 1537 says it quite nicely:
+
+ 2. Glue records
+
+ Quite often, people put unnecessary glue (A) records in their
+ zone files. Even worse is that I've even seen *wrong* glue records
+ for an external host in a primary zone file! Glue records need only
+ be in a zone file if the server host is within the zone and there
+ is no A record for that host elsewhere in the zone file.
+
+ Old BIND versions ("native" 4.8.3 and older versions) showed the
+ problem that wrong glue records could enter secondary servers in
+ a zone transfer.
diff --git a/contrib/bind/doc/misc/FAQ.2of2 b/contrib/bind/doc/misc/FAQ.2of2
new file mode 100644
index 0000000..ae453c9
--- /dev/null
+++ b/contrib/bind/doc/misc/FAQ.2of2
@@ -0,0 +1,1131 @@
+Newsgroups: comp.protocols.tcp-ip.domains,comp.answers,news.answers
+Path: vixie!news1.digital.com!uunet!in1.uu.net!usc!rutgers!njitgw.njit.edu!hertz.njit.edu!cdp2582
+From: cdp@njit.edu (Chris Peckham)
+Subject: comp.protocols.tcp-ip.domains Frequently Asked Questions (FAQ) (Part 2 of 2)
+Message-ID: <cptd-faq-2-810621452@njit.edu>
+Followup-To: comp.protocols.tcp-ip.domains
+Originator: cdp2582@hertz.njit.edu
+Keywords: BIND,DOMAIN,DNS
+Sender: news@njit.edu
+Supersedes: <cptd-faq-2-807632375@njit.edu>
+Nntp-Posting-Host: hertz.njit.edu
+X-Posting-Frequency: posted on the 1st of each month
+Reply-To: domain-faq@njit.edu (comp.protocols.tcp-ip.domains FAQ comments)
+Organization: NJIT.EDU - New Jersey Institute of Technology, Newark, NJ, USA
+References: <cptd-faq-1-810621452@njit.edu>
+Date: Sat, 9 Sep 1995 04:38:21 GMT
+Approved: news-answers-request@MIT.EDU
+Expires: Sat 14 Oct 95 00:37:32 EDT
+Lines: 1110
+Xref: vixie comp.protocols.tcp-ip.domains:6019 comp.answers:13882 news.answers:49919
+
+Posted-By: auto-faq 3.1.1.2
+Archive-name: internet/tcp-ip/domains-faq/part2
+Revision: 1.5 1995/05/12 18:50:41
+
+
+This FAQ is edited and maintained by Chris Peckham, <cdp@njit.edu>.
+The latest version may always be found for anonymous ftp from
+
+ ftp://rtfm.mit.edu/pub/usenet/news.answers/internet/tcp-ip/domains-faq
+ ftp://ftp.njit.edu/pub/dns/Comp.protocols.tcp-ip.domains.FAQ
+
+If you can contribute any answers for items in the TODO section, please do
+so by sending e-mail to domain-faq@njit.edu ! If you know of any items that
+are not included and you feel that they should be, send the relevant
+information to domain-faq@njit.edu.
+
+
+------------------------------
+
+Date: Fri May 12 14:41:47 EDT 1995
+Subject: Table of Contents
+
+Table of Contents
+=================
+Part 1
+------
+ 0. TO DO
+ 1. INTRODUCTION / MISCELLANEOUS
+ 1.1 What is this newsgroup ?
+ 1.2 More information
+ 1.3 What is BIND and where is the latest version of BIND ?
+ 1.4 How can I find the route between systems ?
+ 1.5 Finding the hostname if you have the tcp-ip address
+ 1.6 How to register a domain name
+ 1.7 Change of Domain name
+ 1.8 How memory and CPU does DNS use ?
+ 1.9 Other things to consider when planning your servers
+ 1.10 Proper way to get NS and reverse IP records into DNS
+ 1.11 How to get my address assign from NIC?
+ 1.12 Is there a block of private IP addresses I can use?
+ 1.13 Cache failed lookups
+ 1.14 What does an NS record really do ?
+ 1.15 DNS ports
+ 1.16 Obtaining the latest cache file
+ 2. UTILITIES
+ 2.1 Utilities to administer DNS zone files
+ 2.2 DIG - Domain Internet Groper
+ 2.3 DNS packet analyzer
+ 2.4 host
+ 2.5 Programming with DNS
+ 2.6 A source of information relating to DNS
+ 3. DEFINITIONS
+ 3.1 TCP/IP Host Naming Conventions
+ 3.2 Slaves and servers with forwarders
+ 3.3 When is a server authoritative?
+ 3.4 Underscore in host-/domain names
+ 3.5 Lame delegation
+ 3.6 What does opt-class field do?
+ 3.7 Top level domains
+ 3.8 Classes of networks
+ 3.9 What is CIDR ?
+ 3.10 What is the rule for glue ?
+
+Part 2
+------
+ 4. CONFIGURATION
+ 4.1 Changing a Secondary server to a Primary
+ 4.2 How do I subnet a Class B Address ?
+ 4.3 Subnetted domain name service
+ 4.4 Recommended format/style of DNS files
+ 4.5 DNS on a system not connected to the Internet
+ 4.6 Multiple Domain configuration
+ 4.7 wildcard MX records
+ 4.8 How to identify a wildcard MX record
+ 4.9 Why are fully qualified domain names recommended ?
+ 4.10 Distributing load using named
+ 4.11 Order of returned records
+ 4.12 resolv.conf
+ 4.13 Delegating authority
+ 4.14 DNS instead of NIS on a Sun OS 4.1.x system
+ 5. PROBLEMS
+ 5.1 No address for root server
+ 5.2 Error - No Root Nameservers for Class XX
+ 5.3 Bind 4.9.x and MX querying?
+ 5.4 Some root nameservers don't know localhost
+ 5.5 MX records and CNAMES and separate A records for MX targets
+ 5.6 NS is a CNAME
+ 5.7 Nameserver forgets own A record
+ 5.8 General problems (core dumps !)
+ 5.9 malloc and DECstations
+ 6. ACKNOWLEDGEMENTS
+
+------------------------------
+
+Date: Fri Dec 2 15:31:06 EST 1994
+Subject: Q4.1 - Changing a Secondary server to a Primary
+
+Q: Do I need to do anything special when I change a server from a secondary
+ to a primary ?
+
+A: For 4.8.3, it's prudent to kill and restart following any changes to
+ named.boot.
+
+ In BIND 4.9.3, you only have to kill and restart named if you change
+ a primary zone to a secondary or v-v, or if you delete a zone and
+ remain authoritative for its parent. Every other case should be
+ taken care of by a HUP. (Ed. note: 4.9.3b9 may still require you to
+ kill and restart the server due to some bugs in the HUP code).
+
+ You will also need to update the server information on the root servers.
+ You can do this by filing a new domain registration form to inform
+ InterNIC of the change. They will then update the root server's SOA
+ records. This process usually takes 10-12 business days after they
+ receive the request.
+
+-------------------------------
+
+Date: Fri Apr 28 13:34:52 EDT 1995
+Subject: Q4.2 - How do I subnet a Class B Address ?
+
+Q: I just received a Class B internet address and I am wondering where to
+ get an RFC or other information on how to properly to the TCP/IP
+ sub-netting.
+
+A: That you need to subnet at all is something of a misconception. You
+ can also think of a class B network as giving you 65,534 individual
+ hosts, and such a network will work. You can also configure your
+ class B as 16,384 networks of 2 hosts each. That's obviously not
+ very practical, but it needs to be made clear that you are not
+ constrained by the size of an octet (remember that many older
+ devices would not work in a network configured in this manner).
+
+ So, the question is: why do you need to subnet? One reason is that
+ it is easier to manage a subnetted network, and in fact, you can
+ delegate the responsibility for address space management to local
+ administrators on the various subnets. Also, IP based problems will
+ end up localized rather than affecting your entire network.
+
+ If your network is a large backbone with numerous segments
+ individually branching off the backbone, that too suggests
+ subnetting.
+
+ Subnetting can also be used to improve routing conditions.
+
+ You may wish to partition your network to disallow certain protocols
+ on certain segments of your net. You can, for example, restrict IP or
+ IPX to certain segments only by adding a router routing high level
+ protocols, and across the router you may have to subnet.
+
+ Finally, as far as how many subnets you need depends on the answer to
+ the above question. As far as subnet masks are concerned, the mask
+ can be anything from 255.0.0.0 to 255.255.255.252. You'll probably be
+ looking at 9 or 10 bits for the subnet (last octet 128 or 192
+ respectively). RFC1219 discusses the issue of subnetting very well
+ and leaves the network administrator with a large amount of flexibility
+ for future growth.
+
+
+------------------------------
+
+Date: Sun Nov 27 23:32:41 EST 1994
+Subject: Q4.3 -Subnetted domain name service
+
+Q: After doing some reading (DNS and BIND, Albitz&Liu), I don't really
+ find any examples of handling subnetted class C networks as separate
+ DNS domains.
+
+A: This is possible, just messy. You need to delegate down to the
+ fourth octet, so you will have one domain per IP address ! Here is
+ how you can subdelegate a in-addr.arpa address for non-byte aligned
+ subnet masks:
+
+ Take as an example the net 192.1.1.x, and example subnet mask
+ 255.255.255.240.
+
+ We first define the domain for the class C net,
+
+$origin 1.1.192.in-addr.arpa
+@ SOA (usual stuff)
+@ ns some.nameserver
+ ns some.other.nameserver
+; delegate a subdomain
+one ns one.nameserver
+ ns some.nameserver
+; delegate another
+two ns two.nameserver
+ ns some.nameserver
+; CNAME pointers to subdomain one
+0 CNAME 0.one
+1 CNAME 1.one
+; through
+15 CNAME 15.one
+; CNAME pointers to subdomain two
+16 CNAME 16.two
+17 CNAME 17.two
+31 CNAME 31.two
+; CNAME as many as required.
+
+
+ Now, in the delegated nameserver, one.nameserver
+
+$origin one.1.1.192.in-addr.arpa
+@ SOA (usual stuff)
+ NS one.nameserver
+ NS some.nameserver ; secondary for us
+0 PTR onenet.one.domain
+1 PTR onehost.one.domain
+; through
+15 PTR lasthost.one.domain
+
+ And similar for the two.1.1.192.in-addr.arpa delegated domain.
+
+
+------------------------------
+
+Date: Sun Nov 27 23:32:41 EST 1994
+Subject: Q4.4 - Recommended format/style of DNS files
+
+Q: Are there any suggestions for how to layout DNS configuration files
+ (both forward and reverse)?
+
+A: This answer is quoted from an article posted by Paul Vixie:
+
+ I've gone back and forth on the question of whether the BOG should
+ include a section on this topic. I know what I myself prefer, but
+ I'm wary of ramming my own stylistic preferences down the throat of
+ every BOG reader. But since you ask :-)...
+
+ Create /var/named. If your system is too old to have a /var, either
+ create one or use /usr/local/adm/named instead. Put your named.boot
+ in it, and make /etc/named.boot a symlink to it. If your system
+ doesn't have symlinks, you're S-O-L (but you knew that). In
+ named.boot, put a "directory" directive that specifies your actual
+ BIND working directory:
+
+ directory /var/named
+
+ All relative pathnames used in "primary", "secondary", and "cache"
+ directives will be evaluated relative to this directory. Create two
+ subdirectories, /var/named/pri and /var/named/sec. Whenever you add
+ a "primary" directive to your named.boot, use "pri/WHATEVER" as the
+ path name. And then put the primary zone file into "pri/WHATEVER".
+ Likewise when you add "secondary" directives, use "sec/WHATEVER" and
+ BIND (really named-xfer) will create the files in that
+ subdirectory.
+
+ (Variations: (1) make a midlevel directory "zones" and put "pri" and
+ "sec" into it; (2) if you tend to pick up a lot of secondaries from
+ a few hosts, group them together in their own subdirectories --
+ something like /var/named/zones/uucp if you're a UUCP Project name
+ server.)
+
+ For your forward files, name them after the zone. dec.com becomes
+ "/var/named/zones/pri/dec.com". For your reverse files, name them
+ after the network number. 0.1.16.in-addr.arpa becomes
+ "/var/named/zones/pri/16.1.0".
+
+ When creating or maintaining primary zone files, try to use the same
+ SOA values everywhere, except for the serial number which varies per
+ zone. Put a $ORIGIN directive at the top of the primary zone file,
+ not because its needed (it's not since the default origin is the
+ zone named in the "primary" directive) but because it make it easier
+ to remember what you're working on when you have a lot of primary
+ zones. Put some comments up there indicating contact information
+ for the real owner if you're proxying. Use RCS and put the "Id"
+ in a ";" comment near the top of the zone file.
+
+ The SOA and other top level information should all be listed
+ together. But don't put IN on every line, it defaults nicely. For
+ example:
+
+==============
+@ IN SOA gw.home.vix.com. postmaster.vix.com. (
+ 1994082501 ; serial
+ 3600 ; refresh (1 hour)
+ 1800 ; retry (30 mins)
+ 604800 ; expire (7 days)
+ 3600 ) ; minimum (1 hour)
+
+ NS gw.home.vix.com.
+ NS ns.uu.net.
+ NS uucp-gw-1.pa.dec.com.
+ NS uucp-gw-2.pa.dec.com.
+
+ MX 10 gw.home.vix.com.
+ MX 20 uucp-gw-1.pa.dec.com.
+ MX 20 uucp-gw-1.pa.dec.com.
+==============
+
+ I don't necessarily recommend those SOA values. Not every zone is
+ as volatile as the example shown. I do recommend that serial number
+ format; it's in date format with a 2-digit per-day revision number.
+ This format will last us until 2147 A.D. at which point I expect a
+ better solution will have been found :-). (Note that it would last
+ until 4294 A.D. except that there are some old BINDs out there that
+ use a signed quantity for representing serial number interally; I
+ suppose that as long as none of these are still running after 2047
+ A.D., that we can use the above serial number format until 4294
+ A.D., at which point a better solution will HAVE to be found.)
+
+ You'll note that I use a tab stop for "IN" even though I never again
+ specify it. This leaves room for names longer than 7 bytes without
+ messing up the columns. You might also note that I've put the MX
+ priority and destination in the same tab stop; this is because both
+ are part of the RRdata and both are very different from MX which is
+ an RRtype. Some folks seem to prefer to group "MX" and the priority
+ together in one tab stop. While this looks neat it's very confusing
+ to newcomers and for them it violates the law of least
+ astonishment.
+
+ If you have a multi-level zone (one which contains names that have
+ dots in them), you can use additional $ORIGIN statements but I
+ recommend against it since there is no "back" operator. That is,
+ given the above example you can add:
+
+=============
+$ORIGIN home
+gw A 192.5.5.1
+=============
+
+ The problem with this is that subsequent RR's had better be
+ somewhere under the "home.vix.com" name or else the $ORIGIN that
+ introduces them will have to use a fully qualified name. FQDN
+ $ORIGIN's aren't bad and I won't be mad if you use them.
+ Unqualified ones as shown above are real trouble. I usually stay
+ away from them and just put the whole name in:
+
+=============
+gw.home A 192.5.5.1
+=============
+
+ In your reverse zones, you're usually in some good luck because the
+ owner name is usually a single short token or sometimes two.
+
+=============
+$ORIGIN 5.5.192.in-addr.arpa.
+@ IN SOA ...
+ NS ...
+1 PTR gw.home.vix.com.
+=========================================
+$ORIGIN 1.16.in-addr.arpa.
+@ IN SOA ...
+ NS ...
+2.0 PTR gatekeeper.dec.com.
+=============
+
+ It is usually pretty hard to keep your forward and reverse zones in
+ synch. You can avoid that whole problem by just using "h2n" (see
+ the ORA book, DNS and BIND, and its sample toolkit, included in the
+ BIND distribution or on ftp.uu.net (use the QUOTE SITE EXEC INDEX
+ command there to find this -- I never can remember where it's at).
+ "h2n" and many tools like it can just read your old /etc/hosts file
+ and churn it into DNS zone files. (May I recommend
+ contrib/decwrl/mkdb.pl from the BIND distribution?) However, if you
+ (like me) prefer to edit these things by hand, you need to follow
+ the simple convention of making all of your holes consistent. If
+ you use 192.5.5.1 and 192.5.5.3 but not (yet) 192.5.5.2, then in
+ your forward file you will have something like
+
+=============
+...
+gw.home A 192.5.5.1
+;avail A 192.5.5.2
+pc.home A 192.5.5.3
+=============
+
+ and in your reverse file you will have something like
+
+=============
+...
+1 PTR gw.home.vix.com.
+;2 PTR avail
+3 PTR pc.home.vix.com.
+=============
+
+ This convention will allow you to keep your sanity and make fewer
+ errors. Any kind of automation (h2n, mkdb, or your own
+ perl/tcl/awk/python tools) will help you maintain a consistent
+ universe even if it's also a complex one. Editing by hand doesn't
+ have to be deadly but you MUST take care.
+
+------------------------------
+
+Date: Sun Nov 27 23:32:41 EST 1994
+Subject: Q4.5 - DNS on a system not connected to the Internet
+
+
+Q: How do I use DNS on a system that is not connected to the Internet or
+ set BIND up with an internal root server ?
+
+A: You need to create your own root domain name server until you connect
+ to the internet. Your roots need to delegate to mydomain.com and any
+ in-addr.arpa subdomains you might have, and that's about it. As
+ soon as you're connected, rip out the fake roots and use the real
+ ones.
+
+ It does not actually have to be another server pretending to be the root.
+ You can set up the name server so that it is primary for each domain
+ above you and leave them empty (i.e. you are foo.bar.com - claim to be
+ primary for bar.com and com)
+
+Q: What if you connect intermittently and want DNS to work when you are
+ connected, and "fail" when you are not ?
+
+A: You can point the resolver at the name server at the remote site and
+ if the connection (SLIP/PPP) isn't up, the resolver doesn't have a
+ route to the remote server and since there's only one name server in
+ resolv.conf, the resolver quickly backs off the using /etc/hosts.
+ No problem. You could do the same with multiple name server and a
+ resolver that did configurable /etc/hosts fallback.
+
+------------------------------
+
+Date: Fri Dec 2 15:40:49 EST 1994
+Subject: Q4.6 -Multiple Domain configuration
+
+
+Q: I have seen sites that seem to have multiple domain names pointing to the
+ same destination. I would like to implement this and have found no
+ information explaining how to do it. What I would like to do is:
+
+ ftp ftp.biff.com connects user to -> ftp.biff.com
+ ftp ftp.fred.com connects user to -> ftp.biff.com
+ ftp ftp.bowser.com connects user to -> ftp.biff.com
+
+A: This is done through CNAME records:
+
+ ftp.bowser.com. IN CNAME ftp.biff.com.
+
+ You can also do the same thing with multiple A records.
+
+
+------------------------------
+
+Date: Sun Nov 27 23:32:41 EST 1994
+Subject: Q4.7 - wildcard MX records
+
+Q: Does BIND not understand wildcard MX records such as the following?
+
+ *.foo.com MX 0 mail.foo.com.
+
+A: Explicit RR's at one level of specificity will, by design, "block" a
+ wildcard at a lesser level of specificity. I suspect that you have
+ an RR (an A RR, perhaps?) for "bar.foo.com" which is blocking the
+ application of your "*.foo.com" wildcard. The initial MX query is
+ thus failing (NOERROR but an answer count of 0), and the backup
+ query finds the A RR for "bar.foo.com" and uses it to deliver the
+ mail directly (which is what you DIDN'T want it to do). Adding an
+ explicit MX RR for the host is therefore the right way to handle
+ this situation.
+
+ See RFC 1034, Section 4.3.3 ("Wildcards") for more information on
+ this "blocking" behavior, along with an illustrative example. See
+ also RFC 974 for an explanation of standard mailer behavior in the
+ face of an "empty" response to one's MX query.
+
+ Basically, what it boils down to is, there is no point in trying to
+ use a wildcard MX for a host which is otherwise listed in the DNS.
+ It just doesn't work.
+
+------------------------------
+
+Date: Thu Dec 1 11:10:39 EST 1994
+Subject: Q4.8 - How to identify a wildcard MX record
+
+
+Q: How do you identify a wildcard MX record ?
+
+A: You don't really need to "identify" a wildcard MX RR. The precedence
+ for u@dom is:
+
+ exact match MX
+ exact match A
+ wildcard MX
+
+ One way to implement this is to query for ("dom",IN,MX) and if the
+ answer name that comes back is "*." something, you know it's a
+ wildcard, therefore you know there is no exact match MX, and you
+ therefore query for ("dom",IN,A) and if you get something, use it.
+ if you don't, use the previous wildcard response.
+
+ RFC 974 explains this pretty well.
+
+------------------------------
+
+Date: Sun Nov 27 23:32:41 EST 1994
+Subject: Q4.9 - Why are fully qualified domain names recommended ?
+
+
+Q: Why are fully qualified domain names recommended ?
+
+A: The documentation for BIND 4.9.2 says that the hostname should be set
+ to the full domain style name (i.e host.our.domain rather than
+ host). What advantages are there in this, and are there any adverse
+ consequences if we don't?
+
+A: Paul Vixie likes to do it :-) He lists a few reasons -
+
+ * Sendmail can be configured to just use Dj$w rather than
+ Dj$w.mumble where "mumble" is something you have to edit in by
+ hand. Granted, most people use "mumble" elsewhere in their config
+ files ("tack on local domain", etc) but why should it be a
+ requirement ?
+
+ * The real reason is that not doing it violates a very useful invariant:
+
+ gethostbyname(gethostname) == gethostbyaddr(primary_interface_address)
+
+ If you take an address and go "backwards" through the PTR's with
+ it, you'll get a FQDN, and if you push that back through the A
+ RR's, you get the same address. Or you should. Many multi-homed
+ hosts violate this uncaringly.
+
+ If you take a non-FQDN hostname and push it "forwards" through the
+ A RR's, you get an address which, if you push it through the
+ PTR's, comes back as a FQDN which is not the same as the hostname
+ you started with. Consider the fact that, absent NIS/YP, there is
+ no "domainname" command analogous to the "hostname" command.
+ (NIS/YP's doesn't count, of course, since it's
+ sometimes-but-only-rarely the same as the Internet domain or
+ subdomain above a given host's name.) The "domain" keyword in
+ resolv.conf doesn't specify the parent domain of the current host;
+ it specifies the default domain of queries initiated on the
+ current host, which can be a very different thing. (As of RFC
+ 1535 and BIND 4.9.2's compliance with it, most people use "search"
+ in resolv.conf, which overrides "domain", anyway.)
+
+ What this means is that there is NO authoritative way to
+ programmatically discover your host's FQDN unless it is set in the
+ hostname, or unless every application is willing to grovel the
+ "netstat -in" tables, find what it hopes is the primary address,
+ and do a PTR query on it.
+
+ FQDN /bin/hostnames are, intuitively or not, the simplest way to go.
+
+------------------------------
+
+Date: Wed Mar 1 11:04:43 EST 1995
+Subject: Q4.10 - Distributing load using named
+
+Q: If you attempt to distribute the load on a system using named, won't
+ the first response be cached, and then later queries use the cached
+ value? (This would be for requests that come through the same
+ server.)
+
+A: Yes. So it can be useful to use a lower TTL on records where this is
+ important. You can use values like 300 or 500 seconds.
+
+ If your local caching server has ROUND_ROBIN, it does not matter
+ what the authoritative servers have -- every response from the cache
+ is rotated.
+
+ But if it doesn't, and the authoritative server site is depending on
+ this feature (or the old "shuffle-A") to do load balancing, then if
+ one doesn't use small TTLs, one could conceivably end up with a
+ really nasty situation, e.g., hundreds of workstations at a branch
+ campus pounding on the same front end at the authoritative server's
+ site during class registration.
+
+ Not nice.
+
+A: Paul Vixie has an example of the ROUND_ROBIN code in action. Here is
+ something that he wrote regarding his example:
+
+ >I want users to be distributed evenly among those 3 hosts.
+
+ Believe it or not :-), BIND offers an ugly way to do this. I offer
+ for your collective amusement the following snippet from the
+ ugly.vix.com zone file:
+
+ hydra cname hydra1
+ cname hydra2
+ cname hydra3
+ hydra1 a 10.1.0.1
+ a 10.1.0.2
+ a 10.1.0.3
+ hydra2 a 10.2.0.1
+ a 10.2.0.2
+ a 10.2.0.3
+ hydra3 a 10.3.0.1
+ a 10.3.0.2
+ a 10.3.0.3
+
+ Note that having multiple CNAME RR's at a given name is
+ meaningless according to the DNS RFCs but BIND doesn't mind (in
+ fact it doesn't even complain). If you call
+ gethostbyname("hydra.ugly.vix.com") (try it!) you will get
+ results like the following. Note that there are two round robin
+ rotations going on: one at ("hydra",CNAME) and one at each
+ ("hydra1",A) et al. I used a layer of CNAME's above the layer of
+ A's to keep the response size down. If you don't have nine
+ addresses you probably don't care and would just use a pile of
+ CNAME's pointing directly at real host names.
+
+ {hydra.ugly.vix.com}
+ name: hydra2.ugly.vix.com
+ aliases: hydra.ugly.vix.com
+ addresses: 10.2.0.2 10.2.0.3 10.2.0.1
+
+ {hydra.ugly.vix.com}
+ name: hydra3.ugly.vix.com
+ aliases: hydra.ugly.vix.com
+ addresses: 10.3.0.2 10.3.0.3 10.3.0.1
+
+ {hydra.ugly.vix.com}
+ name: hydra1.ugly.vix.com
+ aliases: hydra.ugly.vix.com
+ addresses: 10.1.0.2 10.1.0.3 10.1.0.1
+
+ {hydra.ugly.vix.com}
+ name: hydra2.ugly.vix.com
+ aliases: hydra.ugly.vix.com
+ addresses: 10.2.0.3 10.2.0.1 10.2.0.2
+
+ {hydra.ugly.vix.com}
+ name: hydra3.ugly.vix.com
+ aliases: hydra.ugly.vix.com
+ addresses: 10.3.0.3 10.3.0.1 10.3.0.2
+
+
+------------------------------
+
+Date: Sun Dec 4 22:12:32 EST 1994
+Subject: Q4.11 - Order of returned records
+
+Q: Is there any way to tell named to return records, specifically
+ address records, in the order in which they are listed in the
+ database?
+
+ It would appear that named consistently applies a sorting algorithm
+ to address records which seems to be virtually guaranteed to be
+ pessimal for our routers, which have many A records.
+
+A: Sorting, is the *resolver's* responsibility. RFC 1123:
+
+ 6.1.3.4 Multihomed Hosts
+
+ When the host name-to-address function encounters a host
+ with multiple addresses, it SHOULD rank or sort the
+ addresses using knowledge of the immediately connected
+ network number(s) and any other applicable performance or
+ history information.
+
+ DISCUSSION:
+ The different addresses of a multihomed host generally
+ imply different Internet paths, and some paths may be
+ preferable to others in performance, reliability, or
+ administrative restrictions. There is no general way
+ for the domain system to determine the best path. A
+ recommended approach is to base this decision on local
+ configuration information set by the system
+ administrator.
+
+ In BIND 4.9.x's resolver code, the "sortlist" directive in resolv.conf
+ can be used to configure this.
+
+------------------------------
+
+Date: Fri Feb 10 15:46:17 EST 1995
+Subject: Q4.12 - resolv.conf
+
+
+Q: Why should I use "real" IP addresses in /etc/resolv.conf and not 0.0.0.0
+ or 127.0.0.1.
+
+A: Paul Vixie writes on the issue of the contents of resolv.conf:
+
+ It's historical. Some kernels can't unbind a UDP socket's source
+ address, and some resolver versions (notably not including BIND
+ 4.9.2 or 4.9.3's) try to do this. The result can be wide area
+ network traffic with 127.0.0.1 as the source address. Rather than
+ giving out a long and detailed map of version/vendor combinations of
+ kernels/BINDs that have/don't this problem, I just tell folks not to
+ use 127.0.0.1 at all.
+
+ 0.0.0.0 is just an alias for the first interface address assigned
+ after a system boot, and if that interface is a up-and-down point to
+ point link (PPP, SLIP, whatever), there's no guarantee that you'll
+ be able to reach yourself via 0.0.0.0 during the entire lifetime of
+ any system instance. On most kernels you can finesse this by adding
+ static routes to 127.0.0.1 for each of your interface addresses, but
+ some kernels don't like that trick and rather than give a detailed
+ map of which ones work and which ones don't, I just globally
+ recommend against 0.0.0.0.
+
+ If you know enough to know that 127.0.0.1 or 0.0.0.0 is safe on your
+ kernel and resolver, then feel free to use them. If you don't know
+ for sure that it is safe, don't use them. I never use them (except
+ on my laptop, whose hostname is "localhost" and whose 0.0.0.0 is
+ 127.0.0.1 since I ifconfig my lo0 before any other interface). The
+ operational advantage to using a real IP address rather than an
+ wormhole like 0.0.0.0 or 127.0.0.1, is that you can then "rdist" or
+ otherwise share identical copies of your resolv.conf on all the
+ systems on any given subnet, not all of which will be servers.
+
+A: The problem was with older versions of the resolver (4.8.X). If you
+ listed 127.0.0.1 as the first entry in resolv.conf, and for whatever
+ reason the local name server wasn't running and the resolver fell
+ back to the second name server listed, it would send queries to the
+ name server with the source IP address set to 127.0.0.1 (as it was
+ set when the resolver was trying to send to 127.0.0.1--you use the
+ loopback address to send to the loopback address).
+
+------------------------------
+
+Date: Mon Jan 2 13:50:13 EST 1995
+Subject: Q4.13 - Delegating authority
+
+Q: How do I delegate authority for domains within my domain ?
+
+A: When you start having a very big domain that can be broken into logical
+ and separate entities that can look after their own DNS information,
+ you will probably want to do this. Maintain a central area for the
+ things that everyone needs to see and delegate the authority for the
+ other parts of the organization so that they can manage themselves.
+
+ Another essential piece of information is that every domain that
+ exists must have it NS records associated with it. These NS records
+ denote the name servers that are queried for information about that
+ zone. For your zone to be recognized by the outside world, the
+ server responsible for the zone above you must have created a NS
+ record for your machine in your domain. For example, putting the
+ computer club onto the network and giving them control over their
+ own part of the domain space we have the following.
+
+ The machine authorative for gu.uwa.edu.au is mackerel and the machine
+ authorative for ucc.gu.uwa.edu.au is marlin.
+
+ in mackerel's data for gu.uwa.edu.au we have the following
+
+ @ IN SOA ...
+ IN A 130.95.100.3
+ IN MX mackerel.gu.uwa.edu.au.
+ IN MX uniwa.uwa.edu.au.
+
+ marlin IN A 130.95.100.4
+
+ ucc IN NS marlin.gu.uwa.edu.au.
+ IN NS mackerel.gu.uwa.edu.au.
+
+ Marlin is also given an IP in our domain as a convenience. If they
+ blow up their name serving there is less that can go wrong because
+ people can still see that machine which is a start. You could place
+ "marlin.ucc" in the first column and leave the machine totally
+ inside the ucc domain as well.
+
+ The second NS line is because mackerel will be acting as secondary name
+ server for the ucc.gu domain. Do not include this line if you are not
+ authorative for the information included in the sub-domain.
+
+
+------------------------------
+
+Date: Wed Mar 1 11:45:00 EST 1995
+Subject: Q4.14 - DNS instead of NIS on a Sun OS 4.1.x system
+
+Q: I would appreciate any comments on whether running bind 4.9.x will
+ enable sendmail, ftp, telnet and other TCP/IP services to bypass
+ NIS and connect directly to named.
+
+A: How to do this is documented quite well in the comp.sys.sun.admin FAQ in
+ questions one and two. You can get them from:
+
+ ftp://thor.ece.uc.edu/pub/sun-faq/FAQs/sun-faq.general
+ http://www.cis.ohio-state.edu/hypertext/faq/usenet/comp-sys-sun-faq
+
+ as well as from rtfm.mit.edu in the usual place, etc.
+
+
+------------------------------
+
+Date: Mon Jan 2 13:49:43 EST 1995
+Subject: Q5.1 - No address for root server
+
+
+Q: I've been getting the following messages lately from bind-4.9.2..
+ ns_req: no address for root server
+
+We are behind a firewall and have the following for our named.cache file -
+
+ ; list of servers
+ . 99999999 IN NS POBOX.FOOBAR.COM.
+ 99999999 IN NS FOOHOST.FOOBAR.COM.
+ foobar.com. 99999999 IN NS pobox.foobar.com.
+
+A: You can't do that. Your nameserver contacts POBOX.FOOBAR.COM, gets the
+ correct list of root servers from it, then tries again and fails
+ because of your firewall.
+
+ You will need a 'forwarder' definition, to ensure that all requests
+ are forwarded to a host which can penetrate the firewall. And
+ it is unwise to put phony data into 'named.cache'.
+
+------------------------------
+
+Date: Sun Nov 27 23:32:41 EST 1994
+Subject: Q5.2 - Error - No Root Nameservers for Class XX
+
+Q: I've received errors before about "No root nameservers for class XX"
+ but they've been because of network connectivity problems.
+ I believe that Class 1 is Internet Class data.
+ And I think I heard someone say that Class 4 is Hesiod??
+ Does anyone know what the various Class numbers are?
+
+A: From RFC 1700:
+
+ DOMAIN NAME SYSTEM PARAMETERS
+ The Internet Domain Naming System (DOMAIN) includes several
+ parameters. These are documented in [RFC1034] and [RFC1035]. The
+ CLASS parameter is listed here. The per CLASS parameters are
+ defined in separate RFCs as indicated.
+
+ Domain System Parameters:
+
+ Decimal Name References
+ -------- ---- ----------
+ 0 Reserved [PM1]
+ 1 Internet (IN) [RFC1034,PM1]
+ 2 Unassigned [PM1]
+ 3 Chaos (CH) [PM1]
+ 4 Hesoid (HS) [PM1]
+ 5-65534 Unassigned [PM1]
+ 65535 Reserved [PM1]
+
+DNS information for RFC 1700 was taken from
+
+ ftp://ftp.isi.edu/in-notes/iana/assignments/dns-parameters
+
+ Hesiod is class 4, and there are no official root nameservers for class
+ 4, so you can safely declare yourself one if you like. You might want
+ to put up a packet filter so that no one outside your network is capable
+ of making Hesiod queries of your machines, if you define yourself to be
+ a root nameserver for class 4.
+
+------------------------------
+
+Date: Sun Nov 27 23:32:41 EST 1994
+Subject: Q5.3 - Bind 4.9.x and MX querying?
+
+
+Q: If I query a 4.9.x DNS server for MX records, a list of the MX records
+ as well as a list of the authorative nameservers is returned. Why ?
+
+A: Bind 4.9.2 returns the list of nameserver that are authorative
+ for a domain in the response packet, along with their IP
+ addresses in the additional section.
+
+------------------------------
+
+Date: Sat Sep 9 00:36:01 EDT 1995
+Subject: Q5.4 - Some root nameservers don't know localhost
+
+Q: Do I need to define an A record for localhost ?
+
+ Where is the A record for 127.0.0.1 defined? I see where
+ the PTR record is defined pointing to localhost, but can't find
+ where the A record is. And is the A record supposed to be
+ localhost.MY_DOMAIN or just localhost ?
+
+A: Somewhere deep in the BOG (BIND Operations Guide) that came with
+ 4.9.3 (section 5.4.3), it says that you define this yourself
+ (if need be) in the same zone files as your "real" IP addresses
+ for your domain. Quoting the BOG:
+
+ ... As implied by this PTR
+ record, there should be a ``localhost.my.dom.ain''
+ A record (with address 127.0.0.1) in every domain
+ that contains hosts. ``localhost.'' will lose its
+ trailing dot when 1.0.0.127.in-addr.arpa is queried
+ for;...
+
+ The sample files in the BIND distribution show you what needs to be
+ done (see the BOG).
+
+ Some HP boxen (especially those running HP OpenView) will also need
+ "loopback" defined with this IP address. You may set it as a CNAME
+ record pointing to the "localhost." record.
+
+------------------------------
+
+Date: Sun Nov 27 23:32:41 EST 1994
+Subject: Q5.5 - MX records and CNAMES and separate A records for MX targets
+
+Q: The O'Reilly "DNS and Bind" book warns against using non-canonical
+ names in MX records, however, this warning is given in the context
+ of mail hubs that MX to each other for backup purposes. I don't see
+ how this applies to mail spokes. RFC 974 has a similar warning, but
+ I can not see where it specifically prohibits using an alias in an
+ MX record.
+
+A: Without the restrictions in the RFC, a MTA must request the A records
+ for every MX listed to determine if it is in the MX list then reduce
+ the list. This introduces many more lookups than would other wise be
+ required. If you are behind a 1200 bps link YOU DON'T WANT TO DO
+ THIS. The addresses associated with CNAMES are not passed as
+ additional data so you will force additional traffic to result even
+ if you are running a caching server locally.
+
+ There is also the problem of how does the MTA find all of it's
+ IP addresses. This is not straight forward. You have to be able
+ to do this is you allow CNAMEs (or extra A's) as MX targets.
+
+ The letter of the law is that an MX record should point to an A record.
+
+ There is no "real" reason to use CNAMEs for MX targets or separate
+ As for nameservers any more. CNAMEs for services other than mail
+ should be used because there is no specified method for locating the
+ desired server yet.
+
+ People don't care what the names of MX targets are. They're
+ invisible to the process anyway. If you have mail for "mary"
+ redirected to "sue" is totally irrelevant. Having CNAMEs as the
+ targets of MX's just needlessly complicates things, and is more work
+ for the resolver.
+
+ Having separate A's for nameservers like "ns.your.domain" is
+ pointless too, since again nobody cares what the name of your
+ nameserver is, since that too is invisible to the process. If you
+ move your nameserver from "mary.your.domain" to "sue.your.domain"
+ nobody need care except you and your parent domain administrator
+ (and the InterNIC). Even less so for mail servers, since only you
+ are affected.
+
+Q: Given the example -
+
+ hello in cname realname
+ mailx in mx 0 hello
+
+ Now, while reading the operating manual of bind it clearly states
+ that this is *not* valid. These two statements clearly contradict
+ each other. Is there some later rfc than 974 that overrides what is
+ said in there with respect to MX and CNAMEs? Anyone have the
+ reference handy?
+
+A: This isn't what the BOG says at all. See below. You can have a CNAME
+ that points to some other RR type; in fact, all CNAMEs have to point
+ to other names (Canonical ones, hence the C in CNAME). What you
+ can't have is an MX that points to a CNAME. MX RR's that point to
+ names which have only CNAME RR's will not work in many cases, and
+ RFC 974 intimates that it's a bad idea:
+
+ Note that the algorithm to delete irrelevant RRs breaks if LOCAL has
+ a alias and the alias is listed in the MX records for REMOTE. (E.g.
+ REMOTE has an MX of ALIAS, where ALIAS has a CNAME of LOCAL). This
+ can be avoided if aliases are never used in the data section of MX
+ RRs.
+
+ Here's the relevant BOG snippet:
+
+ aliases {ttl} addr-class CNAME Canonical name
+ ucbmonet IN CNAME monet
+
+ The Canonical Name resource record, CNAME, speci-
+ fies an alias or nickname for the official, or
+ canonical, host name. This record should be the
+ only one associated with the alias name. All other
+ resource records should be associated with the
+ canonical name, not with the nickname. Any
+ resource records that include a domain name as
+ their value (e.g., NS or MX) must list the canoni-
+ cal name, not the nickname.
+
+------------------------------
+
+Date: Wed Mar 1 11:14:10 EST 1995
+Subject: Q5.6 - NS is a CNAME
+
+Q: Can I do this ? Is it legal ?
+
+ @ SOA (.........)
+ NS ns.host.this.domain.
+ NS second.host.another.domain.
+ ns CNAME third
+ third IN A xxx.xxx.xxx.xxx
+
+
+A: No. Only one RR type is allowed to refer, in its data field, to a
+ CNAME, and that's CNAME itself. So CNAMEs can refer to CNAMEs but
+ NSs and MXs cannot.
+
+ BIND 4.9.3 (Beta11 and later) explicitly syslogs this case rather than
+ simply failing as pre-4.9 servers did. Here's a current example:
+
+ Dec 7 00:52:18 gw named[17561]: \
+ "foobar.com IN NS" points to a CNAME (foobar.foobar.com)
+
+ Here is the reason why:
+
+ Nameservers are not required to include CNAME records in the
+ Additional Info section returned after a query. It's partly an
+ implementation decision and partly a part of the spec. The
+ algorithm described in RFC 1034 (pp24,25; info also in RFC 1035,
+ section 3.3.11, p 18) says 'Put whatever addresses are available
+ into the additional section, using glue RRs [if necessary]'.
+ Since NS records are speced to contain only primary names of
+ hosts, not CNAMEs, then there's no reason for algorithm to
+ mention them. If, on the other hand, it's decided to allow CNAMEs
+ in NS records (and indeed in other records) then there's no
+ reason that CNAME records might not be included along with A
+ records. The Additional Info section is intended for any
+ information that might be useful but which isn't strictly the
+ answer to the DNS query processed. It's an implementation
+ decision in as much as some servers used to follow CNAMEs in
+ NS references.
+
+
+------------------------------
+
+Date: Fri Dec 2 16:17:31 EST 1994
+Subject: Q5.7 - Nameserver forgets own A record
+
+
+Q: Lately, I've been having trouble with named 4.9.2 and 4.9.3.
+ Periodically, the nameserver will seem to "forget" its own A record,
+ although the other information stays intact. One theory I had was
+ that somehow a site that the nameserver was secondary for was
+ "corrupting" the A record somehow.
+
+A: This is invariably due to not removing ALL of the cached zones
+ when you moved to 4.9.X. Remove ALL cached zones and restart
+ your nameservers.
+
+ You get "ignoreds" because the primaries for the relevant zones are
+ running old versions of BIND which pass out more glue than is
+ required. named-xfer trims off this extra glue.
+
+------------------------------
+
+Date: Sun Dec 4 22:21:22 EST 1994
+Subject: Q5.8 - General problems (core dumps !)
+
+Q: I am running bind 4.9.3b9p1 on a DEC alpha OSF/1 V3.0 and have had it
+ core dump while in debug mode. The last lines printed to named.run
+ were [...]
+
+A: Paul Vixie says:
+
+ I'm always interested in hearing about cases where BIND dumps core.
+ However, I need a stack trace. Compile with -g and not -O (unless
+ you are using gcc and know what you are doing) and then when it
+ dumps core, get into dbx or gdb using the executable and the core
+ file and use "bt" to get a stack trace. Send it to me
+ <paul@vix.com> along with specific circumstances leading to or
+ surrounding the crash (test data, tail of the debug log, tail of the
+ syslog... whatever matters) and ideally you should save your core
+ dump for a day or so in case I have questions you can answer via
+ gdb/dbx.
+
+------------------------------
+
+Date: Mon Jan 2 14:19:22 EST 1995
+Subject: Q5.9 - malloc and DECstations
+
+We have replaced malloc on our DECstations with a malloc that is more
+compact in memory usage, and this helped the operation of bind a lot.
+The source is now available for anonymous ftp from
+
+ ftp://ftp.cs.wisc.edu/pub/misc/malloc.tar.gz
+
+
+------------------------------
+
+Date: Fri Apr 28 13:56:32 EDT 1995
+Subject: Q6 - Acknowledgements
+
+Listed in e-mail address alphabetical order, the following people have
+contributed to this FAQ:
+
+Benoit.Grange@inria.fr (Benoit.Grange)
+D.T.Shield@csc.liv.ac.uk (Dave Shield)
+adam@comptech.demon.co.uk (Adam Goodfellow)
+andras@is.co.za (Andras Salamon)
+barmar@nic.near.net (Barry Margolin)
+barr@pop.psu.edu (David Barr)
+bj@herbison.com (B.J. Herbison)
+bje@cbr.fidonet.org (Ben Elliston)
+brad@birch.ims.disa.mil (Brad Knowles)
+ckd@kei.com (Christopher Davis)
+cdp@hertz.njit.edu (Chris Peckham)
+cricket@hp.com (Cricket Liu)
+cudep@csv.warwick.ac.uk (Ian 'Vato' Dickinson [ID17])
+dparter@cs.wisc.edu (David Parter)
+e07@nikhef.nl (Eric Wassenaar)
+fwp@CC.MsState.Edu (Frank Peters)
+gah@cco.caltech.edu (Glen A. Herrmannsfeldt)
+glenn@popco.com (Glenn Fleishman)
+harvey@indyvax.iupui.edu (James Harvey)
+hubert@cac.washington.edu (Steve Hubert)
+jmalcolm@uunet.uu.net (Joseph Malcolm)
+jhawk@panix.com (John Hawkinson)
+kevin@cfc.com (Kevin Darcy)
+lamont@abstractsoft.com (Sean T. Lamont)
+lavondes@tidtest.total.fr (Michel Lavondes)
+mark@ucsalf.ac.uk (Mark Powell)
+marka@syd.dms.CSIRO.AU (Mark Andrews)
+mathias@unicorn.swi.com.sg (Mathias Koerber)
+mjo@iao.ford.com (Mike O'Connor)
+nick@flapjack.ieunet.ie (Nick Hilliard)
+patrick@oes.amdahl.com (Patrick J. Horgan)
+ph10@cus.cam.ac.uk (Philip Hazel)
+rv@seins.Informatik.Uni-Dortmund.DE (Ruediger Volk)
+shields@tembel.org (Michael Shields)
+tanner@george.arc.nasa.gov (Rob Tanner)
+vixie@vix.com (Paul A Vixie)
+wag@swl.msd.ray.com (William Gianopoulos {84718})
+whg@inel.gov (Bill Gray)
+wolf@pasteur.fr (Christophe Wolfhugel)
+
+Thank you !
+
diff --git a/contrib/bind/doc/misc/IPv6 b/contrib/bind/doc/misc/IPv6
new file mode 100644
index 0000000..49fc3f5
--- /dev/null
+++ b/contrib/bind/doc/misc/IPv6
@@ -0,0 +1,72 @@
+IPv6 notes for BIND 4.9.3 Patch 2 Candidate 5 (and later?)
+Paul Vixie, May 20, 1996
+doc/misc/IPv6
+
+ *** Introduction ***
+
+The IPv6 support in this release is latent, in that its presence is not
+documented. The support is not optional, since its presence ought not to
+affect anyone who does not go looking for it. The support includes:
+
+ inet_ntop() new function.
+ inet_pton() new function.
+ RES_USE_INET6 causes gethostby*() to return either real IPv6
+ addresses (if available) or mapped (::FFFF:a.b.c.d)
+ addresses if only IPv4 address records are found.
+ gethostbyname() can search for T_AAAA in preference to T_A.
+ gethostbyaddr() can search in IP6.INT for PTR RR's.
+ named can load, transfer, cache, and dump T_AAAA RRs.
+
+ *** Some notes on the new functions ***
+
+The inet_pton() and inet_ntop() functions differ from the current (as of
+this writing) IPv6 BSD API draft. Discussions were held, primarily between
+myself and Rich Stevens, on the ipng@sunroof.eng.sun.com mailing list, and
+the BIND definitions of these functions are likely to go into the next draft.
+(If not, and BIND has to change its definitions of these functions, then you
+will know why I chose not to document them yet!)
+
+These functions can return error values, and as such the process of porting
+code that used inet_aton() to use inet_pton() is not just syntactic. Not all
+nonzero values indicate success; consider "-1". Likewise, inet_ntoa() is not
+just smaller than inet_ntop() -- it's a whole new approach. Inet_ntop() does
+not return a static pointer, the caller has to supply a sized buffer. Also,
+inet_ntop() can return NULL, so you should only printf() the result if you
+have verified that your arguments will be seen as error free.
+
+The inet_pton() function is much pickier about its input format than the old
+inet_aton() function has been. You can't abbreviate 10.0.0.53 as 10.53 any
+more. Hexadecimal isn't accepted. You have to supply four decimal numeric
+strings, each of whose value is within the range from 0 to 255. No spaces
+are allowed either before, after, or within an address. If you need the older
+functionality with all the shortcuts and exceptions, continue using inet_aton()
+for your IPv4 address parsing needs.
+
+ *** Some notes on RES_USE_INET6 ***
+
+You can set this by modifying _res.options after calling res_init(), or you
+can turn it on globally by setting "options inet6" in /etc/resolv.conf. This
+latter option ought to be used carefully, since _all_ applications will then
+receive IPv6 style h_addr_list's from their gethostby*() calls. Once you know
+that every application on your system can cope with IPv6 addressing, it is safe
+and reasonable to turn on the global option. Otherwise, don't do it.
+
+ *** Some notes on mapped IPv4 addresses ***
+
+There are two IPv6 prefixes set aside for IPv4 address encapsulation. See
+RFC 1884 for a detailed explaination. The ::a.b.c.d form is used for
+tunnelling, which means wrapping an IPv4 header around IPv6 packets and using
+the existing IPv4 routing infrastructure to reach what are actually IPv6
+endpoints. The ::FFFF:a.b.c.d form can be used on dual-stack (IPv4 and IPv6)
+hosts to signal a predominantly IPv6 stack that it should use ``native'' IPv4
+to reach a given destination, even though the socket's address family is
+AF_INET6.
+
+BIND supports both of these address forms, to the extent that inet_pton() will
+parse them, inet_ntop() will generate them, gethostby*() will map IPv4 into
+IPv6 if the RES_USE_INET6 option is set, and gethostbyaddr() will search the
+IN-ADDR.ARPA domain rather than the IP6.INT domain when it needs a PTR RR.
+This last bit of behaviour is still under discussion and it's not clear that
+tunnelled addresses should be mapped using IN-ADDR.ARPA. In other words, this
+bit of behaviour may change in a subsequent BIND release. So now you know
+another reason why none of this stuff is ``officially'' documented.
diff --git a/contrib/bind/doc/misc/dns-setup b/contrib/bind/doc/misc/dns-setup
new file mode 100644
index 0000000..19f0197
--- /dev/null
+++ b/contrib/bind/doc/misc/dns-setup
@@ -0,0 +1,1081 @@
+ Setting up a basic DNS server for a domain
+ Revision 1.1.1
+
+ Craig Richmond
+ craig@ecel.uwa.edu.au
+ 15th August 1993
+
+
+About this document
+
+I have written this file because it seems that the same questions seem to
+pop up time and time again and when I had to install DNS from scratch the
+first time, we found very little to help us.
+
+This document covers setting up a Domain Name Server with authority over
+your domain and using a few of the more useful but less well known
+(hopefully this document will take care of that) features of nslookup to
+get information about the DNS and to work out why yours isn't working.
+
+If you are using a Sun Workstation and you want to make NIS interact with
+the DNS, then this is not the FAQ for you (but it may well be when you try
+to set up the DNS). Mark J. McIntosh <Mark.McIntosh@engr.UVic.CA> points
+out that it is included in the comp.sys.sun.admin FAQ and for the benefit
+of those of you who can't get that (it is posted in comp.sys.sun.admin,
+comp.sys.sun.misc, comp.unix.solaris, comp.answers and news.answers) I have
+included the relevant parts at the bottom in appendix C.
+
+Contents:
+
+ Contents
+ An Overview of the DNS
+ Installing the DNS
+ *The Boot File
+ *The Cache File
+ *The Forward Mapping File
+ *The Reverse Mapping File
+ Delegating authority for domains within your domain
+ Troubleshooting your named
+ *Named doesn't work! What is wrong?
+ *I changed my named database and my local machine has noticed,
+ but nobody else has the new information?
+ *My local machine knows about all the name server information,
+ but no other sites know about me?
+ *My forward domain names work, but the backward names do not?
+ How to get useful information from nslookup
+ *Getting number to name mappings.
+ *Finding where mail goes when a machine has no IP number.
+ *Getting a list of machines in a domain from nslookup.
+ Appendicies
+ *Appendix A sample root.cache file
+ *Appendix B Excerpt from RFC 1340 - Assigned Numbers - July 1992
+ *Appendix C Installing DNS on a Sun when running NIS
+
+
+An Overview of the DNS:
+
+The Domain Name System is the software that lets you have name to number
+mappings on your computers. The name decel.ecel.uwa.edu.au is the number
+130.95.4.2 and vice versa. This is achieved through the DNS. The DNS is a
+heirarchy. There are a small number of root domain name servers that are
+responsible for tracking the top level domains and who is under them. The
+root domain servers between them know about all the people who have name
+servers that are authoritive for domains under the root.
+
+Being authoritive means that if a server is asked about something in that
+domain, it can say with no ambiguity whether or not a given piece of
+information is true. For example. We have domains x.z and y.z. There are
+by definition authoritive name servers for both of these domains and we
+shall assume that the name server in both of these cases is a machine
+called nic.x.z and nic.y.z but that really makes no difference.
+
+If someone asks nic.x.z whether there is a machine called a.x.z, then
+nic.x.z can authoritively say, yes or no because it is the authoritive name
+server for that domain. If someone asks nic.x.z whether there is a machine
+called a.y.z then nic.x.z asks nic.y.z whether such a machine exists (and
+caches this for future requests). It asks nic.y.z because nic.y.z is the
+authoritive name server for the domain y.z. The information about
+authoritive name servers is stored in the DNS itself and as long as you
+have a pointer to a name server who is more knowledgable than yourself then
+you are set.
+
+When a change is made, it propogates slowly out through the internet to
+eventually reach all machines. The following was supplied by Mark Andrews
+Mark.Andrews@syd.dms.csiro.au.
+
+ If both the primary and all secondaries are up and talking when
+ a zone update occurs and for the refresh period after the
+ update the old data will live for max(refresh + mininum)
+ average (refresh/2 +mininum) for the zone. New information will
+ be available from all servers after refresh.
+
+So with a refresh of 3 hours and a minimum of a day, you can expect
+everything to be working a day after it is changed. If you have a longer
+minimum, it may take a couple of days before things return to normal.
+
+There is also a difference between a zone and a domain. The domain is the
+entire set of machines that are contained within an organisational domain
+name. For example, the domain uwa.edu.au contains all the machines at the
+University of Western Australia. A Zone is the area of the DNS for which a
+server is responsible. The University of Western Australia is a large
+organisation and trying to track all changes to machines at a central
+location would be difficult. The authoritive name server for the zone
+uwa.edu.au delegates the authority for the zone ecel.uwa.edu.au to
+decel.ecel.uwa.edu.au. Machine foo.ecel.uwa.edu.au is in the zone that
+decel is authoritive for. Machine bar.uwa.edu.au is in the zone that
+uniwa.uwa.edu.au is authoritive for.
+
+Installing the DNS:
+
+First I'll assume you already have a copy of the Domain Name Server
+software. It is probably called named or in.named depending on your
+flavour of unix. I never had to get a copy, but if anyone thinks that
+information should be here then by all means tell me and I'll put it in.
+If you intend on using the package called Bind, then you should be sure
+that you get version 4.9, which is the most recent version at this point in
+time.
+
+The Boot File:
+
+First step is to create the file named.boot. This describes to named
+(we'll dispense with the in.named. Take them to be the same) where the
+information that it requires can be found. This file is normally found in
+/etc/named.boot and I personally tend to leave it there because then I know
+where to find it. If you don't want to leave it there but place it in a
+directory with the rest of your named files, then there is usually an
+option on named to specify the location of the boot file.
+
+Your typical boot file will look like this if you are an unimportant leaf
+node and there are other name servers at your site.
+
+directory /etc/namedfiles
+
+cache . root.cache
+primary ecel.uwa.edu.au ecel.uwa.domain
+primary 0.0.127.in-addr.arpa 0.0.127.domain
+primary 4.95.130.in-addr.arpa 4.95.130.domain
+forwarders 130.95.128.1
+
+Here is an alternative layout used by Christophe Wolfhugel
+<Christophe.Wolfhugel@grasp.insa-lyon.fr> He finds this easier because of
+the large number of domains he has. The structure is essentially the same,
+but the file names use the domain name rather than the IP subnet to
+describe the contents.
+
+directory /usr/local/etc/bind
+cache . p/root
+;
+; Primary servers
+;
+primary fr.net p/fr.net
+primary frmug.fr.net p/frmug.fr.net
+primary 127.in-addr.arpa p/127
+;
+; Secondary servers
+;
+secondary ensta.fr 147.250.1.1 s/ensta.fr
+secondary gatelink.fr.net 134.214.100.1 s/gatelink.fr.net
+secondary insa-lyon.fr 134.214.100.1 s/insa-lyon.fr
+secondary loesje.org 145.18.226.21 s/loesje.org
+secondary nl.loesje.org 145.18.226.21 s/nl.loesje.org
+secondary pcl.ac.uk 161.74.160.5 s/pcl.ac.uk
+secondary univ-lyon1.fr 134.214.100.1 s/univ-lyon1.fr
+secondary wmin.ac.uk 161.74.160.5 s/wmin.ac.uk
+secondary westminster.ac.uk 161.74.160.5 s/westminster.ac.uk
+;
+;
+; Secondary for addresses
+;
+secondary 74.161.in-addr.arpa 161.74.160.5 s/161.74
+secondary 214.134.in-addr.arpa 134.214.100.1 s/134.214
+secondary 250.147.in-addr.arpa 147.250.1.1 s/147.250
+;
+; Classes C
+;
+secondary 56.44.192.in-addr.arpa 147.250.1.1 s/192.44.56
+secondary 57.44.192.in-addr.arpa 147.250.1.1 s/192.44.57
+
+The lines in the named.boot file have the following meanings.
+
+directory
+
+This is the path that named will place in front of all file names
+referenced from here on. If no directory is specified, it looks for files
+relative to /etc.
+
+cache
+
+This is the information that named uses to get started. Named must know
+the IP number of some other name servers at least to get started.
+Information in the cache is treated differently depending on your version
+of named. Some versions of named use the information included in the cache
+permenantly and others retain but ignore the cache information once up and
+running.
+
+primary
+
+This is one of the domains for which this machine is authorative for. You
+put the entire domain name in. You need forwards and reverse lookups. The
+first value is the domain to append to every name included in that file.
+(There are some exceptions, but they will be explained later) The name at
+the end of the line is the name of the file (relative to /etc of the
+directory if you specified one). The filename can have slashes in it to
+refer to subdirectories so if you have a lot of domains you may want to
+split it up.
+
+BE VERY CAREFUL TO PUT THE NUMBERS BACK TO FRONT FOR THE REVERSE LOOK UP
+FILE. The example given above is for the subnet ecel.uwa.edu.au whose IP
+address is 130.95.4.*. The reverse name must be 4.95.130.in-addr.arpa.
+It must be backwards and it must end with .in-addr.arpa. If your reverse
+name lookups don't work, check this. If they still don't work, check this
+again.
+
+forwarders
+
+This is a list of IP numbers for forward requests for sites about which we
+are unsure. A good choice here is the name server which is authoritive for
+the zone above you.
+
+secondary (This line is not in the example, but is worth mentioning.)
+
+A secondary line indicates that you wish to be a secondary name server for
+this domain. You do not need to do this usually. All it does is help make
+the DNS more robust. You should have at least one secondary server for
+your site, but you do not need to be a secondary server for anyone else.
+You can by all means, but you don't need to be. If you want to be a
+secondary server for another domain, then place the line
+
+secondary gu.uwa.edu.au 130.95.100.3 130.95.128.1
+
+in your named.boot. This will make your named try the servers on both of
+the machines specified to see if it can obtain the information about those
+domains. You can specify a number of IP addresses for the machines to
+query that probably depends on your machine. Your copy of named will upon
+startup go and query all the information it can get about the domain in
+question and remember it and act as though it were authoritive for that
+domain.
+
+Next you will want to start creating the data files that contain the name
+definitions.
+
+The cache file:
+
+You can get a copy of the cache file from FTP.RS.INTERNIC.NET. The current
+copy can be found in Appendix A.
+
+The Forward Mapping file:
+The file ecel.uwa.edu.au. will be used for the example with a couple of
+machines left in for the purpose of the exercise. Here is a copy of what
+the file looks like with explanations following.
+
+; Authoritative data for ecel.uwa.edu.au
+;
+@ IN SOA decel.ecel.uwa.edu.au. postmaster.ecel.uwa.edu.au. (
+ 93071200 ; Serial (yymmddxx)
+ 10800 ; Refresh 3 hours
+ 3600 ; Retry 1 hour
+ 3600000 ; Expire 1000 hours
+ 86400 ) ; Minimum 24 hours
+ IN A 130.95.4.2
+ IN MX 100 decel
+ IN MX 150 uniwa.uwa.edu.au.
+ IN MX 200 relay1.uu.net.
+ IN MX 200 relay2.uu.net.
+
+localhost IN A 127.0.0.1
+
+decel IN A 130.95.4.2
+ IN HINFO SUN4/110 UNIX
+ IN MX 100 decel
+ IN MX 150 uniwa.uwa.edu.au.
+ IN MX 200 relay1.uu.net
+ IN MX 200 relay2.uu.net
+
+gopher IN CNAME decel.ecel.uwa.edu.au.
+
+accfin IN A 130.95.4.3
+ IN HINFO SUN4/110 UNIX
+ IN MX 100 decel
+ IN MX 150 uniwa.uwa.edu.au.
+ IN MX 200 relay1.uu.net
+ IN MX 200 relay2.uu.net
+
+chris-mac IN A 130.95.4.5
+ IN HINFO MAC-II MACOS
+
+The comment character is ';' so the first two lines are just comments
+indicating the contents of the file.
+
+All values from here on have IN in them. This indicates that the value is
+an InterNet record. There are a couple of other types, but all you need
+concern yourself with is internet ones.
+
+The SOA record is the Start Of Authority record. It contains the
+information that other nameservers will learn about this domain and how to
+treat the information they are given about it. The '@' as the first
+character in the line indicates that you wish to define things about the
+domain for which this file is responsible. The domain name is found in the
+named.boot file in the corresponding line to this filename. All
+information listed refers to the most recent machine/domain name so all
+records from the '@' until 'localhost' refer to the '@'. The SOA record
+has 5 magic numbers. First magic number is the serial number. If you
+change the file, change the serial number. If you don't, no other name
+servers will update their information. The old information will sit around
+for a very long time.
+
+Refresh is the time between refreshing information about the SOA (correct
+me if I am wrong). Retry is the frequency of retrying if an authorative
+server cannot be contacted. Expire is how long a secondary name server
+will keep information about a zone without successfully updating it or
+confirming that the data is up to date. This is to help the information
+withstand fairly lengthy downtimes of machines or connections in the
+network without having to recollect all the information. Minimum is the
+default time to live value handed out by a nameserver for all records in
+a zone without an explicit TTL value. This is how long the data will live
+after being handed out. The two pieces of information before the 5 magic
+numbers are the machine that is considered the origin of all of this
+information. Generally the machine that is running your named is a good
+one for here. The second is an email address for someone who can fix any
+problems that may occur with the DNS. Good ones here are postmaster,
+hostmaster or root. NOTE: You use dots and not '@' for the email address.
+
+eg root.decel.ecel.uwa.edu.au is correct
+ and
+ root@decel.ecel.uwa.edu.au is incorrect.
+
+We now have an address to map ecel.uwa.edu.au to. The address is
+130.95.4.2 which happens to be decel, our main machine. If you try to find
+an IP number for the domain ecel.uwa.edu.au it will get you the machine
+decel.ecel.uwa.edu.au's IP number. This is a nicety which means that
+people who have non-MX record mailers can still mail fred@ecel.uwa.edu.au
+and don't have to find the name of a machine name under the domain to mail.
+
+Now we have a couple of MX records for the domain itself. The MX records
+specify where to send mail destined for the machine/domain that the MX
+record is for. In this case we would prefer if all mail for
+fred@ecel.uwa.edu.au is sent to decel.ecel.uwa.edu.au. If that does not
+work, we would like it to go to uniwa.uwa.edu.au because there are a number
+of machines that might have no idea how to get to us, but may be able to get
+to uniwa. And failing that, try the site relay1.uu.net. A small number
+indicates that this site should be tried first. The larget the number the
+further down the list of sites to try the site is. NOTE: Not all machines
+have mailers that pay attention to MX records. Some only pay attention to
+IP numbers, which is really stupid. All machines are required to have
+MX-capable Mail Transfer Agents (MTA) as there are many addresses that can
+only be reached via this means.
+
+There is an entry for localhost now. Note that this is somewhat of a
+kludge and should probably be handled far more elegantly. By placing
+localhost here, a machine comes into existance called
+localhost.ecel.uwa.edu.au. If you finger it, or telnet to it, you get your
+own machine, because the name lookup returns 127.0.0.1 which is the special
+case for your own machine. I have used a couple of different DNS packages.
+The old BSD one let you put things into the cache which would always work,
+but would not be exported to other nameservers. In the newer Sun one, they
+are left in the cache and are mostly ignored once named is up and running.
+This isn't a bad solution, its just not a good one.
+
+Decel is the main machine in our domain. It has the IP number 130.95.4.2
+and that is what this next line shows. It also has a HINFO entry. HINFO
+is Host Info which is meant to be some sort of an indication of what the
+machine is and what it runs. The values are two white space seperated
+values. First being the hardware and second being the software. HINFO is
+not compulsory, its just nice to have sometimes. We also have some MX
+records so that mail destined for decel has some other avenues before it
+bounces back to the sender if undeliverable.
+
+It is a good idea to give all machines capable of handling mail an MX
+record because this can be cached on remote machines and will help to
+reduce the load on the network.
+
+gopher.ecel.uwa.edu.au is the gopher server in our division. Now because
+we are cheapskates and don't want to go and splurge on a seperate machine
+just for handling gopher requests we have made it a CNAME to our main
+machine. While it may seem pointless it does have one main advantage.
+When we discover that our placing terrabytes of popular quicktime movies
+on our gopher server (no we haven't and we don't intend to) causes an
+unbearable load on our main machine, we can quickly move the CNAME to
+point at a new machine by changing the name mentioned in the CNAME. Then
+the slime of the world can continue to get their essential movies with a
+minimal interuption to the network. Other good CNAMEs to maintain are
+things like ftp, mailhost, netfind, archie, whois, and even dns (though the
+most obvious use for this fails). It also makes it easier for people to
+find these services in your domain.
+
+We should probably start using WKS records for things like gopher and whois
+rather than making DNS names for them. The tools are not in wide
+circulation for this to work though. (Plus all those comments in many DNS
+implementation of "Not implemented" next to the WKS record)
+
+Finally we have a macintosh which belongs to my boss. All it needs is an
+IP number, and we have included the HINFO so that you can see that it is in
+fact a macII running a Mac System. To get the list of preferred values,
+you should get a copy of RFC 1340. It lists lots of useful information
+such as /etc/services values, ethernet manufacturer hardware addresses,
+HINFO defualts and many others. I will include the list as it stands at
+the moment, but if any RFC superceeds 1340, then it will have a more
+complete list. See Appendix B for that list.
+
+NOTE: If Chris had a very high profile and wanted his mac to appear like a
+fully connected unix machine as far as internet services were concerned, he
+could simply place an MX record such as
+
+ IN MX 100 decel
+
+after his machine and any mail sent to chris@chris-mac.ecel.uwa.edu.au
+would be automatically rerouted to decel.
+
+The Reverse Mapping File
+
+The reverse name lookup is handled in a most bizarre fashion. Well it all
+makes sense, but it is not immediately obvious.
+
+All of the reverse name lookups are done by finding the PTR record
+associated with the name w.x.y.z.in-addr.arpa. So to find the name
+associated with the IP number 1.2.3.4, we look for information stored in
+the DNS under the name 4.3.2.1.in-addr.arpa. They are organised this way
+so that when you are allocated a B class subnet for example, you get all of
+the IP numbers in the domain 130.95. Now to turn that into a reverse name
+lookup domain, you have to invert the numbers or your registered domains
+will be spread all over the place. It is a mess and you need not understand
+the finer points of it all. All you need to know is that you put the
+reverse name lookup files back to front.
+
+Here is the sample reverse name lookup files to go with our example.
+
+0.0.127.in-addr.arpa
+--
+; Reverse mapping of domain names 0.0.127.in-addr.arpa
+; Nobody pays attention to this, it is only so 127.0.0.1 -> localhost.
+@ IN SOA decel.ecel.uwa.edu.au. postmaster.ecel.uwa.edu.au. (
+ 91061801 ; Serial (yymmddxx)
+ 10800 ; Refresh 3 hours
+ 3600 ; Retry 1 hour
+ 3600000 ; Expire 1000 hours
+ 86400 ) ; Minimum 24 hours
+;
+1 IN PTR localhost.ecel.uwa.edu.au.
+--
+
+4.95.130.in-addr.arpa
+--
+; reverse mapping of domain names 4.95.130.in-addr.arpa
+;
+@ IN SOA decel.ecel.uwa.edu.au. postmaster.ecel.uwa.edu.au. (
+ 92050300 ; Serial (yymmddxx format)
+ 10800 ; Refresh 3hHours
+ 3600 ; Retry 1 hour
+ 3600000 ; Expire 1000 hours
+ 86400 ) ; Minimum 24 hours
+2 IN PTR decel.ecel.uwa.edu.au.
+3 IN PTR accfin.ecel.uwa.edu.au.
+5 IN PTR chris-mac.ecel.uwa.edu.au.
+--
+
+It is important to remember that you must have a second start of authority
+record for the reverse name lookups. Each reverse name lookup file must
+have its own SOA record. The reverse name lookup on the 127 domain is
+debatable seeing as there is likely to be only one number in the file and
+it is blatantly obvious what it is going to map to.
+
+The SOA details are the same as in the forward mapping.
+
+Each of the numbers listed down the left hand side indicates that the line
+contains information for that number of the subnet. Each of the subnets
+must be the more significant digits. eg the 130.95.4 of an IP number
+130.95.4.2 is implicit for all numbers mentioned in the file.
+
+The PTR must point to a machine that can be found in the DNS. If the name
+is not in the DNS, some versions of named just bomb out at this point.
+
+Reverse name lookups are not compulsory, but nice to have. It means that
+when people log into machines, they get names indicating where they are
+logged in from. It makes it easier for you to spot things that are wrong
+and it is far less cryptic than having lots of numbers everywhere. Also if
+you do not have a name for your machine, some brain dead protocols such as
+talk will not allow you to connect.
+
+Since I had this I had one suggestion of an alternative way to do the
+localhost entry. I think it is a matter of personal opinion so I'll
+include it here in case anyone things that this is a more appropriate
+method.
+
+The following is courtesy of jep@convex.nl (JEP de Bie)
+
+ The way I did it was:
+
+ 1) add in /etc/named.boot:
+
+ primary . localhost
+ primary 127.in-addr.ARPA. IP127
+
+(Craig: It has been suggested by Mark Andrews that this is a bad practice
+ particularly if you have upgraded to Bind 4.9. You also run the risk of
+ polluting the root name servers. This comes down to a battle of idealogy
+ and practicality. Think twice before declaring yourself authorative for
+ the root domain.)
+
+ So I not only declare myself (falsely? - probably, but nobody is going to
+ listen anyway most likely [CPR]:-) athorative in the 127.in-addr.ARPA domain
+ but also in the . (root) domain.
+
+ 2) the file localhost has:
+
+ $ORIGIN .
+ localhost IN A 127.0.0.1
+
+ 3) and the file IP127:
+
+ $ORIGIN 127.in-addr.ARPA.
+ 1.0.0 IN PTR localhost.
+
+ 4) and I have in my own domain file (convex.nl) the line:
+
+ $ORIGIN convex.nl.
+ localhost IN CNAME localhost.
+
+ The advantage (elegancy?) is that a query (A) of localhost. gives the
+ reverse of the query of 1.0.0.127.in-addr.ARPA. And it also shows that
+ localhost.convex.nl is only a nickname to something more absolute.
+ (While the notion of localhost is of course relative :-)).
+
+ And I also think there is a subtle difference between the lines
+
+ primary 127.in-addr.ARPA. IP127
+ and
+ primary 0.0.127.in-addr.ARPA. 4.95.130.domain
+ =============
+ JEP de Bie
+ jep@convex.nl
+ =============
+
+
+
+Delegating authority for domains within your domain:
+
+When you start having a very big domain that can be broken into logical and
+seperate entities that can look after their own DNS information, you will
+probably want to do this. Maintain a central area for the things that
+everyone needs to see and delegate the authority for the other parts of the
+organisation so that they can manage themselves.
+
+Another essential piece of information is that every domain that exists
+must have it NS records associated with it. These NS records denote the
+name servers that are queried for information about that zone. For your
+zone to be recognised by the outside world, the server responsible for the
+zone above you must have created a NS record for your machine in your
+domain. For example, putting the computer club onto the network and giving
+them control over their own part of the domain space we have the following.
+
+The machine authorative for gu.uwa.edu.au is mackerel and the machine
+authorative for ucc.gu.uwa.edu.au is marlin.
+
+in mackerel's data for gu.uwa.edu.au we have the following
+
+@ IN SOA ...
+ IN A 130.95.100.3
+ IN MX mackerel.gu.uwa.edu.au.
+ IN MX uniwa.uwa.edu.au.
+
+marlin IN A 130.95.100.4
+
+ucc IN NS marlin.gu.uwa.edu.au.
+ IN NS mackerel.gu.uwa.edu.au.
+
+Marlin is also given an IP in our domain as a convenience. If they blow up
+their name serving there is less that can go wrong because people can still
+see that machine which is a start. You could place "marlin.ucc" in the
+first column and leave the machine totally inside the ucc domain as well.
+
+The second NS line is because mackerel will be acting as secondary name
+server for the ucc.gu domain. Do not include this line if you are not
+authorative for the information included in the sub-domain.
+
+
+Troubleshooting your named:
+
+Named doesn't work! What is wrong?
+
+Step 1: Run nslookup and see what nameserver it tries to connect you to.
+If nslookup connects you to the wrong nameserver, create a /etc/resolv.conf
+file that points your machine at the correct nameserver. If there is no
+resolv.conf file, the the resolver uses the nameserver on the local
+machine.
+
+Step 2: Make sure that named is actually running.
+
+Step 3: Restart named and see if you get any error messages on the
+console and in also check /usr/adm/messages.
+
+Step 4: If named is running, nslookup connects to the appropriate
+nameserver and nslookup can answer simple questions, but other programs
+such as 'ping' do not work with names, then you need to install resolv+
+most likely.
+
+
+I changed my named database and my local machine has noticed, but nobody
+else has the new information?
+
+Change the serial number in the SOA for any domains that you modified and
+restart named. Wait an hour and check again. The information propogates
+out. It won't change immediately.
+
+
+My local machine knows about all the name server information, but no other
+sites know about me?
+
+Find an upstream nameserver (one that has an SOA for something in your
+domain) and ask them to be a secondary name server for you. eg if you are
+ecel.uwa.edu.au, ask someone who has an SOA for the domain uwa.edu.au.
+Get NS records (and glue) added to your parent zone for your zone. This is
+called delegating. It should be done formally like this or you will get
+inconsistant answers out of the DNS. ALL NAMSERVERS FOR YOUR ZONE SHOULD
+BE LISTED IN THIS MANNER.
+
+
+My forward domain names work, but the backward names do not?
+
+Make sure the numbers are back to front and have the in-addr.arpa on the
+end.
+Make sure you reverse zone is registered. For Class C nets this can be done
+by mailing to hostmaster@internic.net. For class A & B nets make sure that
+you are registeres with the primary for your net and that the net itself
+is registered with hostmaster@internic.net.
+
+
+How to get useful information from nslookup:
+
+Nslookup is a very useful program but I'm sure there are less than 20
+people worldwide who know how to use it to its full usefulness. I'm most
+certainly not one of them. If you don't like using nslookup, there is at
+least one other program called dig, that has most/all(?) of the
+functionality of nslookup and is a hell of a lot easier to use.
+
+I won't go into dig much here except to say that it is a lot easier to get
+this information out of. I won't bother because nslookup ships with almost
+all machines that come with network software.
+
+To run nslookup, you usually just type nslookup. It will tell you the
+server it connects to. You can specify a different server if you want.
+This is useful when you want to tell if your named information is
+consistent with other servers.
+
+Getting name to number mappings.
+
+Type the name of the machine. Typing 'decel' is enough if the machine is
+local.
+
+(Once you have run nslookup successfully)
+> decel
+Server: ecel.uwa.edu.au
+Address: 130.95.4.2
+
+Name: decel.ecel.uwa.edu.au
+Address: 130.95.4.2
+
+>
+
+One curious quirk of some name resolvers is that if you type a
+machine name, they will try a number of permutations. For example if my
+machine is in the domain ecel.uwa.edu.au and I try to find a machine
+called fred, the resolver will try the following.
+
+ fred.ecel.uwa.edu.au.
+ fred.uwa.edu.au.
+ fred.edu.au.
+ fred.au.
+ fred.
+
+This can be useful, but more often than not, you would simply prefer a good
+way to make aliases for machines that are commonly referenced. If you are
+running resolv+, you should just be able to put common machines into the
+host file.
+
+DIG: dig <machine name>
+
+Getting number to name mappings.
+
+Nslookup defaults to finding you the Address of the name specified. For
+reverse lookups you already have the address and you want to find the
+name that goes with it. If you read and understood the bit above where it
+describes how to create the number to name mapping file, you would guess
+that you need to find the PTR record instead of the A record. So you do
+the following.
+
+> set type=ptr
+> 2.4.95.130.in-addr.arpa
+Server: decel.ecel.uwa.edu.au
+Address: 130.95.4.2
+
+2.4.95.130.in-addr.arpa host name = decel.ecel.uwa.edu.au
+>
+
+nslookup tells you that the ptr for the machine name
+2.4.95.130.in-addr.arpa points to the host decel.ecel.uwa.edu.au.
+
+DIG: dig -x <machine number>
+
+Finding where mail goes when a machine has no IP number.
+
+When a machine is not IP connected, it needs to specify to the world, where
+to send the mail so that it can dial up and collect it every now and then.
+This is accomplished by setting up an MX record for the site and not giving
+it an IP number. To get the information out of nslookup as to where the
+mail goes, do the following.
+
+> set type=mx
+> dialix.oz.au
+Server: decel.ecel.uwa.oz.au
+Address: 130.95.4.2
+
+Non-authoritative answer:
+dialix.oz.au preference = 100, mail exchanger = uniwa.uwa.OZ.AU
+dialix.oz.au preference = 200, mail exchanger = munnari.OZ.AU
+Authoritative answers can be found from:
+uniwa.uwa.OZ.AU inet address = 130.95.128.1
+munnari.OZ.AU inet address = 128.250.1.21
+munnari.OZ.AU inet address = 192.43.207.1
+mulga.cs.mu.OZ.AU inet address = 128.250.35.21
+mulga.cs.mu.OZ.AU inet address = 192.43.207.2
+dmssyd.syd.dms.CSIRO.AU inet address = 130.155.16.1
+ns.UU.NET inet address = 137.39.1.3
+
+You tell nslookup that you want to search for mx records and then you give
+it the name of the machine. It tells you the preference for the mail
+(small means more preferable), and who the mail should be sent to. It also
+includes sites that are authorative (have this name in their named database
+files) for this MX record. There are multiple sites as a backup. As can
+be seen, our local public internet access company dialix would like all of
+their mail to be sent to uniwa, where they collect it from. If uniwa is
+not up, send it to munnari and munnari will get it to uniwa eventually.
+
+NOTE: For historical reasons Australia used to be .oz which was changed to
+.oz.au to move to the ISO standard extensions upon the advent of IP. We
+are now moving to a more normal heirarchy which is where the .edu.au comes
+from. Pity, I liked having oz.
+
+DIG: dig <zone> mx
+
+Getting a list of machines in a domain from nslookup.
+
+Find a server that is authorative for the domain or just generally all
+knowing. To find a good server, find all the soa records for a given
+domain. To do this, you set type=soa and enter the domain just like in the
+two previous examples.
+
+Once you have a server type
+
+> ls gu.uwa.edu.au.
+[uniwa.uwa.edu.au]
+Host or domain name Internet address
+ gu server = mackerel.gu.uwa.edu.au
+ gu server = uniwa.uwa.edu.au
+ gu 130.95.100.3
+ snuffle-upagus 130.95.100.131
+ mullet 130.95.100.2
+ mackerel 130.95.100.3
+ marlin 130.95.100.4
+ gugate 130.95.100.1
+ gugate 130.95.100.129
+ helpdesk 130.95.100.180
+ lan 130.95.100.0
+ big-bird 130.95.100.130
+
+To get a list of all the machines in the domain.
+
+If you wanted to find a list of all of the MX records for the domain, you
+can put a -m flag in the ls command.
+
+> ls -m gu.uwa.edu.au.
+[uniwa.uwa.edu.au]
+Host or domain name Metric Host
+ gu 100 mackerel.gu.uwa.edu.au
+ gu 200 uniwa.uwa.edu.au
+
+This only works for a limited selection of the different types.
+
+DIG: dig axfr <zone> @<server>
+
+
+
+Appendix A
+
+
+;
+; This file holds the information on root name servers needed to
+; initialize cache of Internet domain name servers
+; (e.g. reference this file in the "cache . <file>"
+; configuration file of BIND domain name servers).
+;
+; This file is made available by InterNIC registration services
+; under anonymous FTP as
+; file /domain/named.root
+; on server FTP.RS.INTERNIC.NET
+; -OR- under Gopher at RS.INTERNIC.NET
+; under menu InterNIC Registration Services (NSI)
+; submenu InterNIC Registration Archives
+; file named.root
+;
+; last update: April 21, 1993
+; related version of root zone: 930421
+;
+. 99999999 IN NS NS.INTERNIC.NET.
+NS.INTERNIC.NET. 99999999 A 198.41.0.4
+. 99999999 NS KAVA.NISC.SRI.COM.
+KAVA.NISC.SRI.COM. 99999999 A 192.33.33.24
+. 99999999 NS C.NYSER.NET.
+C.NYSER.NET. 99999999 A 192.33.4.12
+. 99999999 NS TERP.UMD.EDU.
+TERP.UMD.EDU. 99999999 A 128.8.10.90
+. 99999999 NS NS.NASA.GOV.
+NS.NASA.GOV. 99999999 A 128.102.16.10
+ 99999999 A 192.52.195.10
+. 99999999 NS NS.NIC.DDN.MIL.
+NS.NIC.DDN.MIL. 99999999 A 192.112.36.4
+. 99999999 NS AOS.ARL.ARMY.MIL.
+AOS.ARL.ARMY.MIL. 99999999 A 128.63.4.82
+ 99999999 A 192.5.25.82
+. 99999999 NS NIC.NORDU.NET.
+NIC.NORDU.NET. 99999999 A 192.36.148.17
+; End of File
+
+
+Appendix B
+
+An Excerpt from
+RFC 1340 Assigned Numbers July 1992
+
+
+ MACHINE NAMES
+
+ These are the Official Machine Names as they appear in the Domain Name
+ System HINFO records and the NIC Host Table. Their use is described in
+ RFC-952 [53].
+
+ A machine name or CPU type may be up to 40 characters taken from the
+ set of uppercase letters, digits, and the two punctuation characters
+ hyphen and slash. It must start with a letter, and end with a letter
+ or digit.
+
+ ALTO DEC-1080
+ ALTOS-6800 DEC-1090
+ AMDAHL-V7 DEC-1090B
+ APOLLO DEC-1090T
+ ATARI-104ST DEC-2020T
+ ATT-3B1 DEC-2040
+ ATT-3B2 DEC-2040T
+ ATT-3B20 DEC-2050T
+ ATT-7300 DEC-2060
+ BBN-C/60 DEC-2060T
+ BURROUGHS-B/29 DEC-2065
+ BURROUGHS-B/4800 DEC-FALCON
+ BUTTERFLY DEC-KS10
+ C/30 DEC-VAX-11730
+ C/70 DORADO
+ CADLINC DPS8/70M
+ CADR ELXSI-6400
+ CDC-170 EVEREX-386
+ CDC-170/750 FOONLY-F2
+ CDC-173 FOONLY-F3
+ CELERITY-1200 FOONLY-F4
+ CLUB-386 GOULD
+ COMPAQ-386/20 GOULD-6050
+ COMTEN-3690 GOULD-6080
+ CP8040 GOULD-9050
+ CRAY-1 GOULD-9080
+ CRAY-X/MP H-316
+ CRAY-2 H-60/68
+ CTIWS-117 H-68
+ DANDELION H-68/80
+ DEC-10 H-89
+ DEC-1050 HONEYWELL-DPS-6
+ DEC-1077 HONEYWELL-DPS-8/70
+ HP3000 ONYX-Z8000
+ HP3000/64 PDP-11
+ IBM-158 PDP-11/3
+ IBM-360/67 PDP-11/23
+ IBM-370/3033 PDP-11/24
+ IBM-3081 PDP-11/34
+ IBM-3084QX PDP-11/40
+ IBM-3101 PDP-11/44
+ IBM-4331 PDP-11/45
+ IBM-4341 PDP-11/50
+ IBM-4361 PDP-11/70
+ IBM-4381 PDP-11/73
+ IBM-4956 PE-7/32
+ IBM-6152 PE-3205
+ IBM-PC PERQ
+ IBM-PC/AT PLEXUS-P/60
+ IBM-PC/RT PLI
+ IBM-PC/XT PLURIBUS
+ IBM-SERIES/1 PRIME-2350
+ IMAGEN PRIME-2450
+ IMAGEN-8/300 PRIME-2755
+ IMSAI PRIME-9655
+ INTEGRATED-SOLUTIONS PRIME-9755
+ INTEGRATED-SOLUTIONS-68K PRIME-9955II
+ INTEGRATED-SOLUTIONS-CREATOR PRIME-2250
+ INTEGRATED-SOLUTIONS-CREATOR-8 PRIME-2655
+ INTEL-386 PRIME-9955
+ INTEL-IPSC PRIME-9950
+ IS-1 PRIME-9650
+ IS-68010 PRIME-9750
+ LMI PRIME-2250
+ LSI-11 PRIME-750
+ LSI-11/2 PRIME-850
+ LSI-11/23 PRIME-550II
+ LSI-11/73 PYRAMID-90
+ M68000 PYRAMID-90MX
+ MAC-II PYRAMID-90X
+ MASSCOMP RIDGE
+ MC500 RIDGE-32
+ MC68000 RIDGE-32C
+ MICROPORT ROLM-1666
+ MICROVAX S1-MKIIA
+ MICROVAX-I SMI
+ MV/8000 SEQUENT-BALANCE-8000
+ NAS3-5 SIEMENS
+ NCR-COMTEN-3690 SILICON-GRAPHICS
+ NEXT/N1000-316 SILICON-GRAPHICS-IRIS
+ NOW SGI-IRIS-2400
+ SGI-IRIS-2500 SUN-3/50
+ SGI-IRIS-3010 SUN-3/60
+ SGI-IRIS-3020 SUN-3/75
+ SGI-IRIS-3030 SUN-3/80
+ SGI-IRIS-3110 SUN-3/110
+ SGI-IRIS-3115 SUN-3/140
+ SGI-IRIS-3120 SUN-3/150
+ SGI-IRIS-3130 SUN-3/160
+ SGI-IRIS-4D/20 SUN-3/180
+ SGI-IRIS-4D/20G SUN-3/200
+ SGI-IRIS-4D/25 SUN-3/260
+ SGI-IRIS-4D/25G SUN-3/280
+ SGI-IRIS-4D/25S SUN-3/470
+ SGI-IRIS-4D/50 SUN-3/480
+ SGI-IRIS-4D/50G SUN-4/60
+ SGI-IRIS-4D/50GT SUN-4/110
+ SGI-IRIS-4D/60 SUN-4/150
+ SGI-IRIS-4D/60G SUN-4/200
+ SGI-IRIS-4D/60T SUN-4/260
+ SGI-IRIS-4D/60GT SUN-4/280
+ SGI-IRIS-4D/70 SUN-4/330
+ SGI-IRIS-4D/70G SUN-4/370
+ SGI-IRIS-4D/70GT SUN-4/390
+ SGI-IRIS-4D/80GT SUN-50
+ SGI-IRIS-4D/80S SUN-100
+ SGI-IRIS-4D/120GTX SUN-120
+ SGI-IRIS-4D/120S SUN-130
+ SGI-IRIS-4D/210GTX SUN-150
+ SGI-IRIS-4D/210S SUN-170
+ SGI-IRIS-4D/220GTX SUN-386i/250
+ SGI-IRIS-4D/220S SUN-68000
+ SGI-IRIS-4D/240GTX SYMBOLICS-3600
+ SGI-IRIS-4D/240S SYMBOLICS-3670
+ SGI-IRIS-4D/280GTX SYMMETRIC-375
+ SGI-IRIS-4D/280S SYMULT
+ SGI-IRIS-CS/12 TANDEM-TXP
+ SGI-IRIS-4SERVER-8 TANDY-6000
+ SPERRY-DCP/10 TEK-6130
+ SUN TI-EXPLORER
+ SUN-2 TP-4000
+ SUN-2/50 TRS-80
+ SUN-2/100 UNIVAC-1100
+ SUN-2/120 UNIVAC-1100/60
+ SUN-2/130 UNIVAC-1100/62
+ SUN-2/140 UNIVAC-1100/63
+ SUN-2/150 UNIVAC-1100/64
+ SUN-2/160 UNIVAC-1100/70
+ SUN-2/170 UNIVAC-1160
+ UNKNOWN
+ VAX-11/725
+ VAX-11/730
+ VAX-11/750
+ VAX-11/780
+ VAX-11/785
+ VAX-11/790
+ VAX-11/8600
+ VAX-8600
+ WANG-PC002
+ WANG-VS100
+ WANG-VS400
+ WYSE-386
+ XEROX-1108
+ XEROX-8010
+ ZENITH-148
+
+ SYSTEM NAMES
+
+ These are the Official System Names as they appear in the Domain Name
+ System HINFO records and the NIC Host Table. Their use is described
+ in RFC-952 [53].
+
+ A system name may be up to 40 characters taken from the set of upper-
+ case letters, digits, and the three punctuation characters hyphen,
+ period, and slash. It must start with a letter, and end with a
+ letter or digit.
+
+ AEGIS LISP SUN OS 3.5
+ APOLLO LISPM SUN OS 4.0
+ AIX/370 LOCUS SWIFT
+ AIX-PS/2 MACOS TAC
+ BS-2000 MINOS TANDEM
+ CEDAR MOS TENEX
+ CGW MPE5 TOPS10
+ CHORUS MSDOS TOPS20
+ CHRYSALIS MULTICS TOS
+ CMOS MUSIC TP3010
+ CMS MUSIC/SP TRSDOS
+ COS MVS ULTRIX
+ CPIX MVS/SP UNIX
+ CTOS NEXUS UNIX-BSD
+ CTSS NMS UNIX-V1AT
+ DCN NONSTOP UNIX-V
+ DDNOS NOS-2 UNIX-V.1
+ DOMAIN NTOS UNIX-V.2
+ DOS OS/DDP UNIX-V.3
+ EDX OS/2 UNIX-PC
+ ELF OS4 UNKNOWN
+ EMBOS OS86 UT2D
+ EMMOS OSX V
+ EPOS PCDOS VM
+ FOONEX PERQ/OS VM/370
+ FUZZ PLI VM/CMS
+ GCOS PSDOS/MIT VM/SP
+ GPOS PRIMOS VMS
+ HDOS RMX/RDOS VMS/EUNICE
+ IMAGEN ROS VRTX
+ INTERCOM RSX11M WAITS
+ IMPRESS RTE-A WANG
+ INTERLISP SATOPS WIN32
+ IOS SCO-XENIX/386 X11R3
+ IRIX SCS XDE
+ ISI-68020 SIMP XENIX
+ ITS SUN
+
+
+
+Appendix C Installing DNS on a Sun when running NIS
+
+====================
+ 2) How to get DNS to be used when running NIS ?
+
+ First setup the appropriate /etc/resolv.conf file.
+ Something like this should do the "trick".
+
+ ;
+ ; Data file for a client.
+ ;
+ domain local domain
+ nameserver address of primary domain nameserver
+ nameserver address of secondary domain nameserver
+
+ where: "local domain" is the domain part of the hostnames.
+ For example, if your hostname is "thor.ece.uc.edu"
+ your "local domain" is "ece.uc.edu".
+
+ You will need to put a copy of this resolv.conf on
+ all NIS(YP) servers including slaves.
+
+ Under SunOS 4.1 and greater, change the "B=" at the top
+ of the /var/yp/Makefile to "B=-b" and setup NIS in the
+ usual fashion.
+
+ You will need reboot or restart ypserv for these changes
+ to take affect.
+
+ Under 4.0.x, edit the Makefile or apply the following "diff":
+
+*** Makefile.orig Wed Jan 10 13:22:11 1990
+--- Makefile Wed Jan 10 13:22:01 1990
+***************
+*** 63 ****
+! | $(MAKEDBM) - $(YPDBDIR)/$(DOM)/hosts.byname; \
+--- 63 ----
+! | $(MAKEDBM) -b - $(YPDBDIR)/$(DOM)/hosts.byname; \
+***************
+*** 66 ****
+! | $(MAKEDBM) - $(YPDBDIR)/$(DOM)/hosts.byaddr; \
+--- 66 ----
+! | $(MAKEDBM) -b - $(YPDBDIR)/$(DOM)/hosts.byaddr; \
+====================
+
diff --git a/contrib/bind/doc/misc/style.txt b/contrib/bind/doc/misc/style.txt
new file mode 100644
index 0000000..a966066
--- /dev/null
+++ b/contrib/bind/doc/misc/style.txt
@@ -0,0 +1,172 @@
+Path: vixie!vixie
+From: vixie@vix.com (Paul A Vixie)
+Newsgroups: comp.protocols.tcp-ip.domains
+Subject: Re: Format of DNS files (style question)
+Date: 28 Aug 94 03:17:08
+Organization: Vixie Enterprises
+Lines: 159
+Distribution: inet
+Message-ID: <VIXIE.94Aug28031708@office.home.vix.com>
+References: <33onnr$i4u@zombie.ncsc.mil>
+NNTP-Posting-Host: office.home.vix.com
+In-reply-to: sjr@zombie.ncsc.mil's message of 27 Aug 1994 21:02:51 -0400
+
+> (Style) Suggestions for how to layout DNS configuration files (both
+> forward and reverse)?
+
+I've gone back and forth on the question of whether the BOG should include a
+section on this topic. I know what I myself prefer, but I'm wary of ramming
+my own stylistic preferences down the throat of every BOG reader. But since
+you ask :-)...
+
+Create /var/named. If your system is too old to have a /var, either create
+one or use /usr/local/adm/named instead. Put your named.boot in it, and make
+/etc/named.boot a symlink to it. If your system doesn't have symlinks, you're
+S-O-L (but you knew that). In named.boot, put a "directory" directive that
+specifies your actual BIND working directory:
+
+ directory /var/named
+
+All relative pathnames used in "primary", "secondary", and "cache" directives
+will be evaluated relative to this directory. Create two subdirectories,
+/var/named/pri and /var/named/sec. Whenever you add a "primary" directive
+to your named.boot, use "pri/WHATEVER" as the path name. And then put the
+primary zone file into "pri/WHATEVER". Likewise when you add "secondary"
+directives, use "sec/WHATEVER" and BIND (really named-xfer) will create the
+files in that subdirectory.
+
+(Variations: (1) make a midlevel directory "zones" and put "pri" and "sec"
+into it; (2) if you tend to pick up a lot of secondaries from a few hosts,
+group them together in their own subdirectories -- something like
+/var/named/zones/uucp if you're a UUCP Project name server.)
+
+For your forward files, name them after the zone. dec.com becomes
+"/var/named/zones/pri/dec.com". For your reverse files, name them after the
+network number. 0.1.16.in-addr.arpa becomes "/var/named/zones/pri/16.1.0".
+
+When creating or maintaining primary zone files, try to use the same SOA
+values everywhere, except for the serial number which varies per zone. Put
+a $ORIGIN directive at the top of the primary zone file, not because it's
+needed (it's not since the default origin is the zone named in the "primary"
+directive) but because it make it easier to remember what you're working on
+when you have a lot of primary zones. Put some comments up there indicating
+contact information for the real owner if you're proxying. Use RCS and put
+the "$Id: style.txt,v 8.1 1995/12/22 21:59:52 vixie Exp $" in a ";" comment near the top of the zone file.
+
+The SOA and other top level information should all be listed together. But
+don't put IN on every line, it defaults nicely. For example:
+
+==============
+@ IN SOA gw.home.vix.com. postmaster.vix.com. (
+ 1994082501 ; serial
+ 3600 ; refresh (1 hour)
+ 1800 ; retry (30 mins)
+ 604800 ; expire (7 days)
+ 3600 ) ; minimum (1 hour)
+
+ NS gw.home.vix.com.
+ NS ns.uu.net.
+ NS uucp-gw-1.pa.dec.com.
+ NS uucp-gw-2.pa.dec.com.
+
+ MX 10 gw.home.vix.com.
+ MX 20 uucp-gw-1.pa.dec.com.
+ MX 20 uucp-gw-1.pa.dec.com.
+==============
+
+I don't necessarily recommend those SOA values. Not every zone is as volatile
+as the example shown. I do recommend that serial number format; it's in date
+format with a 2-digit per-day revision number. This format will last us until
+2147 A.D. at which point I expect a better solution will have been found :-).
+(Note that it would last until 4294 A.D. except that there are some old BINDs
+out there that use a signed quantity for representing serial number interally;
+I suppose that as long as none of these are still running after 2047 A.D.,
+that we can use the above serial number format until 4294 A.D., at which point
+a better solution will HAVE to be found.)
+
+You'll note that I use a tab stop for "IN" even though I never again specify
+it. This leaves room for names longer than 7 bytes without messing up the
+columns. You might also note that I've put the MX priority and destination
+in the same tab stop; this is because both are part of the RRdata and both
+are very different from MX which is an RRtype. Some folks seem to prefer to
+group "MX" and the priority together in one tab stop. While this looks neat
+it's very confusing to newcomers and for them it violates the law of least
+astonishment.
+
+If you have a multi-level zone (one which contains names that have dots in
+them), you can use additional $ORIGIN statements but I recommend against it
+since there is no "back" operator. That is, given the above example you can
+add:
+
+=============
+$ORIGIN home
+gw A 192.5.5.1
+=============
+
+The problem with this is that subsequent RR's had better be somewhere under
+the "home.vix.com" name or else the $ORIGIN that introduces them will have
+to use a fully qualified name. FQDN $ORIGIN's aren't bad and I won't be mad
+if you use them. Unqualified ones as shown above are real trouble. I usually
+stay away from them and just put the whole name in:
+
+=============
+gw.home A 192.5.5.1
+=============
+
+In your reverse zones, you're usually in some good luck because the owner name
+is usually a single short token or sometimes two.
+
+=============
+$ORIGIN 5.5.192.in-addr.arpa.
+@ IN SOA ...
+ NS ...
+1 PTR gw.home.vix.com.
+-------------
+$ORIGIN 1.16.in-addr.arpa.
+@ IN SOA ...
+ NS ...
+2.0 PTR gatekeeper.dec.com.
+=============
+
+It is usually pretty hard to keep your forward and reverse zones in synch.
+You can avoid that whole problem by just using "h2n" (see the ORA book, DNS
+and BIND, and its sample toolkit, included in the BIND distribution or on
+ftp.uu.net (use the QUOTE SITE EXEC INDEX command there to find this -- I
+never can remember where it's at). "h2n" and many tools like it can just
+read your old /etc/hosts file and churn it into DNS zone files. (May I
+recommend contrib/decwrl/mkdb.pl from the BIND distribution?) However, if
+you (like me) prefer to edit these things by hand, you need to follow the
+simple convention of making all of your holes consistent. If you use
+192.5.5.1 and 192.5.5.3 but not (yet) 192.5.5.2, then in your forward file
+you will have something like
+
+=============
+...
+gw.home A 192.5.5.1
+;avail A 192.5.5.2
+pc.home A 192.5.5.3
+=============
+
+and in your reverse file you will have something like
+
+=============
+...
+1 PTR gw.home.vix.com.
+;2 PTR avail
+3 PTR pc.home.vix.com.
+=============
+
+This convention will allow you to keep your sanity and make fewer errors.
+Any kind of automation (h2n, mkdb, or your own perl/tcl/awk/python tools)
+will help you maintain a consistent universe even if it's also a complex
+one. Editing by hand doesn't have to be deadly but you MUST take care.
+
+Anyone who wants to know how to maintain nonleaf zones, i.e., zones which
+have few or no hosts in them but have hundreds or thousands of delegations,
+should attend Usenix LISA in San Diego and be there for the SENDS talk.
+Contact office@usenix.org for conference information.
+--
+Paul Vixie
+Redwood City, CA
+decwrl!vixie!paul
+<paul@vix.com>
diff --git a/contrib/bind/include/Makefile b/contrib/bind/include/Makefile
new file mode 100644
index 0000000..13df424
--- /dev/null
+++ b/contrib/bind/include/Makefile
@@ -0,0 +1,74 @@
+# ++Copyright++ 1993
+# -
+# 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--
+
+SUBDIRS = arpa
+HFILES = netdb.h resolv.h
+
+DESTDIR=
+DESTINC= /usr/include
+
+MARGS= DESTDIR="${DESTDIR}" DESTINC="${DESTINC}" INSTALL="${INSTALL}" \
+ MAKE="${MAKE}"
+
+all depend clean install::
+ @for x in ${SUBDIRS}; do \
+ (cd $$x; pwd; ${MAKE} ${MARGS} $@); \
+ done
+
+clean::
+ rm -f *~ *.BAK *.CKP *.orig
+
+install::
+ @set -x; for x in ${HFILES}; do \
+ ${INSTALL} -c -m 444 $$x ${DESTDIR}${DESTINC}/$$x; \
+ done
diff --git a/contrib/bind/include/arpa/Makefile b/contrib/bind/include/arpa/Makefile
new file mode 100644
index 0000000..491252d
--- /dev/null
+++ b/contrib/bind/include/arpa/Makefile
@@ -0,0 +1,67 @@
+# ++Copyright++ 1993
+# -
+# 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--
+
+HFILES = inet.h nameser.h
+
+DESTDIR =
+DESTINC = /usr/include
+
+all depend:
+
+clean:
+ rm -f *~ *.BAK *.CKP *.orig
+
+install:
+ set -x; for x in ${HFILES}; do \
+ ${INSTALL} -c -m 444 $$x ${DESTDIR}${DESTINC}/arpa/$$x; \
+ done
diff --git a/contrib/bind/include/arpa/inet.h b/contrib/bind/include/arpa/inet.h
new file mode 100644
index 0000000..3451a09
--- /dev/null
+++ b/contrib/bind/include/arpa/inet.h
@@ -0,0 +1,88 @@
+/*
+ * ++Copyright++ 1983, 1993
+ * -
+ * Copyright (c) 1983, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * -
+ * Portions Copyright (c) 1993 by Digital Equipment Corporation.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies, and that
+ * the name of Digital Equipment Corporation not be used in advertising or
+ * publicity pertaining to distribution of the document or software without
+ * specific, written prior permission.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
+ * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ * -
+ * --Copyright--
+ */
+
+/*
+ * @(#)inet.h 8.1 (Berkeley) 6/2/93
+ * $Id: inet.h,v 8.5 1996/05/22 04:56:29 vixie Exp $
+ */
+
+#ifndef _INET_H_
+#define _INET_H_
+
+/* External definitions for functions in inet(3) */
+
+#include <sys/param.h>
+#if (!defined(BSD)) || (BSD < 199306)
+# include <sys/bitypes.h>
+#else
+# include <sys/types.h>
+#endif
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+unsigned long inet_addr __P((const char *));
+int inet_aton __P((const char *, struct in_addr *));
+unsigned long inet_lnaof __P((struct in_addr));
+struct in_addr inet_makeaddr __P((u_long , u_long));
+unsigned long inet_netof __P((struct in_addr));
+unsigned long inet_network __P((const char *));
+char *inet_ntoa __P((struct in_addr));
+int inet_pton __P((int af, const char *src, void *dst));
+const char *inet_ntop __P((int af, const void *src, char *dst, size_t s));
+u_int inet_nsap_addr __P((const char *, u_char *, int maxlen));
+char *inet_nsap_ntoa __P((int, const u_char *, char *ascii));
+__END_DECLS
+
+#endif /* !_INET_H_ */
diff --git a/contrib/bind/include/arpa/nameser.h b/contrib/bind/include/arpa/nameser.h
new file mode 100644
index 0000000..d99bf49
--- /dev/null
+++ b/contrib/bind/include/arpa/nameser.h
@@ -0,0 +1,346 @@
+/*
+ * ++Copyright++ 1983, 1989, 1993
+ * -
+ * Copyright (c) 1983, 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * -
+ * Portions Copyright (c) 1993 by Digital Equipment Corporation.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies, and that
+ * the name of Digital Equipment Corporation not be used in advertising or
+ * publicity pertaining to distribution of the document or software without
+ * specific, written prior permission.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
+ * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ * -
+ * --Copyright--
+ */
+
+/*
+ * @(#)nameser.h 8.1 (Berkeley) 6/2/93
+ * $Id: nameser.h,v 8.5 1996/08/05 08:31:28 vixie Exp $
+ */
+
+#ifndef _NAMESER_H_
+#define _NAMESER_H_
+
+#include <sys/param.h>
+#if (!defined(BSD)) || (BSD < 199306)
+# include <sys/bitypes.h>
+#else
+# include <sys/types.h>
+#endif
+#include <sys/cdefs.h>
+
+#ifdef _AUX_SOURCE
+#include <sys/types.h> /* ech for A/UX */
+#define res_send ucb_res_send /* already def'd in libc */
+#define _res_close _ucb_res_close /* removing res_send.o from the library */
+#endif /* gives an undefined symbol... */
+
+/*
+ * revision information. this is the release date in YYYYMMDD format.
+ * it can change every day so the right thing to do with it is use it
+ * in preprocessor commands such as "#if (__BIND > 19931104)". do not
+ * compare for equality; rather, use it to determine whether your resolver
+ * is new enough to contain a certain feature.
+ */
+
+#define __BIND 19950621 /* interface version stamp */
+
+/*
+ * Define constants based on rfc883
+ */
+#define PACKETSZ 512 /* maximum packet size */
+#define MAXDNAME 256 /* maximum domain name */
+#define MAXCDNAME 255 /* maximum compressed domain name */
+#define MAXLABEL 63 /* maximum length of domain label */
+#define HFIXEDSZ 12 /* #/bytes of fixed data in header */
+#define QFIXEDSZ 4 /* #/bytes of fixed data in query */
+#define RRFIXEDSZ 10 /* #/bytes of fixed data in r record */
+#define INT32SZ 4 /* for systems without 32-bit ints */
+#define INT16SZ 2 /* for systems without 16-bit ints */
+#define INADDRSZ 4 /* IPv4 T_A */
+#define IN6ADDRSZ 16 /* IPv6 T_AAAA */
+
+/*
+ * Internet nameserver port number
+ */
+#define NAMESERVER_PORT 53
+
+/*
+ * Currently defined opcodes
+ */
+#define QUERY 0x0 /* standard query */
+#define IQUERY 0x1 /* inverse query */
+#define STATUS 0x2 /* nameserver status query */
+/*#define xxx 0x3*/ /* 0x3 reserved */
+#define NS_NOTIFY_OP 0x4 /* notify secondary of SOA change */
+#ifdef ALLOW_UPDATES
+ /* non standard - supports ALLOW_UPDATES stuff from Mike Schwartz */
+# define UPDATEA 0x9 /* add resource record */
+# define UPDATED 0xa /* delete a specific resource record */
+# define UPDATEDA 0xb /* delete all named resource record */
+# define UPDATEM 0xc /* modify a specific resource record */
+# define UPDATEMA 0xd /* modify all named resource record */
+# define ZONEINIT 0xe /* initial zone transfer */
+# define ZONEREF 0xf /* incremental zone referesh */
+#endif
+
+/*
+ * Currently defined response codes
+ */
+#define NOERROR 0 /* no error */
+#define FORMERR 1 /* format error */
+#define SERVFAIL 2 /* server failure */
+#define NXDOMAIN 3 /* non existent domain */
+#define NOTIMP 4 /* not implemented */
+#define REFUSED 5 /* query refused */
+#ifdef ALLOW_UPDATES
+ /* non standard */
+# define NOCHANGE 0xf /* update failed to change db */
+#endif
+
+/*
+ * Type values for resources and queries
+ */
+#define T_A 1 /* host address */
+#define T_NS 2 /* authoritative server */
+#define T_MD 3 /* mail destination */
+#define T_MF 4 /* mail forwarder */
+#define T_CNAME 5 /* canonical name */
+#define T_SOA 6 /* start of authority zone */
+#define T_MB 7 /* mailbox domain name */
+#define T_MG 8 /* mail group member */
+#define T_MR 9 /* mail rename name */
+#define T_NULL 10 /* null resource record */
+#define T_WKS 11 /* well known service */
+#define T_PTR 12 /* domain name pointer */
+#define T_HINFO 13 /* host information */
+#define T_MINFO 14 /* mailbox information */
+#define T_MX 15 /* mail routing information */
+#define T_TXT 16 /* text strings */
+#define T_RP 17 /* responsible person */
+#define T_AFSDB 18 /* AFS cell database */
+#define T_X25 19 /* X_25 calling address */
+#define T_ISDN 20 /* ISDN calling address */
+#define T_RT 21 /* router */
+#define T_NSAP 22 /* NSAP address */
+#define T_NSAP_PTR 23 /* reverse NSAP lookup (deprecated) */
+#define T_SIG 24 /* security signature */
+#define T_KEY 25 /* security key */
+#define T_PX 26 /* X.400 mail mapping */
+#define T_GPOS 27 /* geographical position (withdrawn) */
+#define T_AAAA 28 /* IP6 Address */
+#define T_LOC 29 /* Location Information */
+ /* non standard */
+#define T_UINFO 100 /* user (finger) information */
+#define T_UID 101 /* user ID */
+#define T_GID 102 /* group ID */
+#define T_UNSPEC 103 /* Unspecified format (binary data) */
+ /* Query type values which do not appear in resource records */
+#define T_AXFR 252 /* transfer zone of authority */
+#define T_MAILB 253 /* transfer mailbox records */
+#define T_MAILA 254 /* transfer mail agent records */
+#define T_ANY 255 /* wildcard match */
+
+/*
+ * Values for class field
+ */
+
+#define C_IN 1 /* the arpa internet */
+#define C_CHAOS 3 /* for chaos net (MIT) */
+#define C_HS 4 /* for Hesiod name server (MIT) (XXX) */
+ /* Query class values which do not appear in resource records */
+#define C_ANY 255 /* wildcard match */
+
+/*
+ * Status return codes for T_UNSPEC conversion routines
+ */
+#define CONV_SUCCESS 0
+#define CONV_OVERFLOW (-1)
+#define CONV_BADFMT (-2)
+#define CONV_BADCKSUM (-3)
+#define CONV_BADBUFLEN (-4)
+
+#ifndef BYTE_ORDER
+#if (BSD >= 199103)
+# include <machine/endian.h>
+#else
+#ifdef linux
+# include <endian.h>
+#else
+#define LITTLE_ENDIAN 1234 /* least-significant byte first (vax, pc) */
+#define BIG_ENDIAN 4321 /* most-significant byte first (IBM, net) */
+#define PDP_ENDIAN 3412 /* LSB first in word, MSW first in long (pdp)*/
+
+#if defined(vax) || defined(ns32000) || defined(sun386) || defined(i386) || \
+ defined(MIPSEL) || defined(_MIPSEL) || defined(BIT_ZERO_ON_RIGHT) || \
+ defined(__alpha__) || defined(__alpha)
+#define BYTE_ORDER LITTLE_ENDIAN
+#endif
+
+#if defined(sel) || defined(pyr) || defined(mc68000) || defined(sparc) || \
+ defined(is68k) || defined(tahoe) || defined(ibm032) || defined(ibm370) || \
+ defined(MIPSEB) || defined(_MIPSEB) || defined(_IBMR2) || defined(DGUX) ||\
+ defined(apollo) || defined(__convex__) || defined(_CRAY) || \
+ defined(__hppa) || defined(__hp9000) || \
+ defined(__hp9000s300) || defined(__hp9000s700) || \
+ defined (BIT_ZERO_ON_LEFT) || defined(m68k)
+#define BYTE_ORDER BIG_ENDIAN
+#endif
+#endif /* linux */
+#endif /* BSD */
+#endif /* BYTE_ORDER */
+
+#if !defined(BYTE_ORDER) || \
+ (BYTE_ORDER != BIG_ENDIAN && BYTE_ORDER != LITTLE_ENDIAN && \
+ BYTE_ORDER != PDP_ENDIAN)
+ /* you must determine what the correct bit order is for
+ * your compiler - the next line is an intentional error
+ * which will force your compiles to bomb until you fix
+ * the above macros.
+ */
+ error "Undefined or invalid BYTE_ORDER";
+#endif
+
+/*
+ * Structure for query header. The order of the fields is machine- and
+ * compiler-dependent, depending on the byte/bit order and the layout
+ * of bit fields. We use bit fields only in int variables, as this
+ * is all ANSI requires. This requires a somewhat confusing rearrangement.
+ */
+
+typedef struct {
+ unsigned id :16; /* query identification number */
+#if BYTE_ORDER == BIG_ENDIAN
+ /* fields in third byte */
+ unsigned qr: 1; /* response flag */
+ unsigned opcode: 4; /* purpose of message */
+ unsigned aa: 1; /* authoritive answer */
+ unsigned tc: 1; /* truncated message */
+ unsigned rd: 1; /* recursion desired */
+ /* fields in fourth byte */
+ unsigned ra: 1; /* recursion available */
+ unsigned unused :3; /* unused bits (MBZ as of 4.9.3a3) */
+ unsigned rcode :4; /* response code */
+#endif
+#if BYTE_ORDER == LITTLE_ENDIAN || BYTE_ORDER == PDP_ENDIAN
+ /* fields in third byte */
+ unsigned rd :1; /* recursion desired */
+ unsigned tc :1; /* truncated message */
+ unsigned aa :1; /* authoritive answer */
+ unsigned opcode :4; /* purpose of message */
+ unsigned qr :1; /* response flag */
+ /* fields in fourth byte */
+ unsigned rcode :4; /* response code */
+ unsigned unused :3; /* unused bits (MBZ as of 4.9.3a3) */
+ unsigned ra :1; /* recursion available */
+#endif
+ /* remaining bytes */
+ unsigned qdcount :16; /* number of question entries */
+ unsigned ancount :16; /* number of answer entries */
+ unsigned nscount :16; /* number of authority entries */
+ unsigned arcount :16; /* number of resource entries */
+} HEADER;
+
+/*
+ * Defines for handling compressed domain names
+ */
+#define INDIR_MASK 0xc0
+
+/*
+ * Structure for passing resource records around.
+ */
+struct rrec {
+ int16_t r_zone; /* zone number */
+ int16_t r_class; /* class number */
+ int16_t r_type; /* type number */
+ u_int32_t r_ttl; /* time to live */
+ int r_size; /* size of data area */
+ char *r_data; /* pointer to data */
+};
+
+extern u_int16_t _getshort __P((const u_char *));
+extern u_int32_t _getlong __P((const u_char *));
+
+/*
+ * Inline versions of get/put short/long. Pointer is advanced.
+ *
+ * These macros demonstrate the property of C whereby it can be
+ * portable or it can be elegant but rarely both.
+ */
+#define GETSHORT(s, cp) { \
+ register u_char *t_cp = (u_char *)(cp); \
+ (s) = ((u_int16_t)t_cp[0] << 8) \
+ | ((u_int16_t)t_cp[1]) \
+ ; \
+ (cp) += INT16SZ; \
+}
+
+#define GETLONG(l, cp) { \
+ register u_char *t_cp = (u_char *)(cp); \
+ (l) = ((u_int32_t)t_cp[0] << 24) \
+ | ((u_int32_t)t_cp[1] << 16) \
+ | ((u_int32_t)t_cp[2] << 8) \
+ | ((u_int32_t)t_cp[3]) \
+ ; \
+ (cp) += INT32SZ; \
+}
+
+#define PUTSHORT(s, cp) { \
+ register u_int16_t t_s = (u_int16_t)(s); \
+ register u_char *t_cp = (u_char *)(cp); \
+ *t_cp++ = t_s >> 8; \
+ *t_cp = t_s; \
+ (cp) += INT16SZ; \
+}
+
+#define PUTLONG(l, cp) { \
+ register u_int32_t t_l = (u_int32_t)(l); \
+ register u_char *t_cp = (u_char *)(cp); \
+ *t_cp++ = t_l >> 24; \
+ *t_cp++ = t_l >> 16; \
+ *t_cp++ = t_l >> 8; \
+ *t_cp = t_l; \
+ (cp) += INT32SZ; \
+}
+
+#endif /* !_NAMESER_H_ */
diff --git a/contrib/bind/include/netdb.h b/contrib/bind/include/netdb.h
new file mode 100644
index 0000000..82faf7d
--- /dev/null
+++ b/contrib/bind/include/netdb.h
@@ -0,0 +1,170 @@
+/*
+ * ++Copyright++ 1980, 1983, 1988, 1993
+ * -
+ * Copyright (c) 1980, 1983, 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * -
+ * Portions Copyright (c) 1993 by Digital Equipment Corporation.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies, and that
+ * the name of Digital Equipment Corporation not be used in advertising or
+ * publicity pertaining to distribution of the document or software without
+ * specific, written prior permission.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
+ * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ * -
+ * --Copyright--
+ */
+
+/*
+ * @(#)netdb.h 8.1 (Berkeley) 6/2/93
+ * $Id: netdb.h,v 8.7 1996/05/09 05:59:09 vixie Exp $
+ */
+
+#ifndef _NETDB_H_
+#define _NETDB_H_
+
+#include <sys/param.h>
+#if (!defined(BSD)) || (BSD < 199306)
+# include <sys/bitypes.h>
+#endif
+#include <sys/cdefs.h>
+
+#define _PATH_HEQUIV "/etc/hosts.equiv"
+#define _PATH_HOSTS "/etc/hosts"
+#define _PATH_NETWORKS "/etc/networks"
+#define _PATH_PROTOCOLS "/etc/protocols"
+#define _PATH_SERVICES "/etc/services"
+
+extern int h_errno;
+
+/*
+ * Structures returned by network data base library. All addresses are
+ * supplied in host order, and returned in network order (suitable for
+ * use in system calls).
+ */
+struct hostent {
+ char *h_name; /* official name of host */
+ char **h_aliases; /* alias list */
+ int h_addrtype; /* host address type */
+ int h_length; /* length of address */
+ char **h_addr_list; /* list of addresses from name server */
+#define h_addr h_addr_list[0] /* address, for backward compatiblity */
+};
+
+/*
+ * Assumption here is that a network number
+ * fits in an unsigned long -- probably a poor one.
+ */
+struct netent {
+ char *n_name; /* official name of net */
+ char **n_aliases; /* alias list */
+ int n_addrtype; /* net address type */
+ unsigned long n_net; /* network # */
+};
+
+struct servent {
+ char *s_name; /* official service name */
+ char **s_aliases; /* alias list */
+ int s_port; /* port # */
+ char *s_proto; /* protocol to use */
+};
+
+struct protoent {
+ char *p_name; /* official protocol name */
+ char **p_aliases; /* alias list */
+ int p_proto; /* protocol # */
+};
+
+/*
+ * Error return codes from gethostbyname() and gethostbyaddr()
+ * (left in extern int h_errno).
+ */
+
+#define NETDB_INTERNAL -1 /* see errno */
+#define NETDB_SUCCESS 0 /* no problem */
+#define HOST_NOT_FOUND 1 /* Authoritative Answer Host not found */
+#define TRY_AGAIN 2 /* Non-Authoritive Host not found, or SERVERFAIL */
+#define NO_RECOVERY 3 /* Non recoverable errors, FORMERR, REFUSED, NOTIMP */
+#define NO_DATA 4 /* Valid name, no data record of requested type */
+#define NO_ADDRESS NO_DATA /* no address, look for MX record */
+
+__BEGIN_DECLS
+void endhostent __P((void));
+void endnetent __P((void));
+void endprotoent __P((void));
+void endservent __P((void));
+struct hostent *gethostbyaddr __P((const char *, int, int));
+struct hostent *gethostbyname __P((const char *));
+struct hostent *gethostbyname2 __P((const char *, int));
+struct hostent *gethostent __P((void));
+struct netent *getnetbyaddr __P((unsigned long, int));
+struct netent *getnetbyname __P((const char *));
+struct netent *getnetent __P((void));
+struct protoent *getprotobyname __P((const char *));
+struct protoent *getprotobynumber __P((int));
+struct protoent *getprotoent __P((void));
+struct servent *getservbyname __P((const char *, const char *));
+struct servent *getservbyport __P((int, const char *));
+struct servent *getservent __P((void));
+void herror __P((const char *));
+const char *hstrerror __P((int));
+void sethostent __P((int));
+/* void sethostfile __P((const char *)); */
+void setnetent __P((int));
+void setprotoent __P((int));
+void setservent __P((int));
+__END_DECLS
+
+/* This is nec'y to make this include file properly replace the sun version. */
+#ifdef sun
+#ifdef __GNU_LIBRARY__
+#include <rpc/netdb.h>
+#else
+struct rpcent {
+ char *r_name; /* name of server for this rpc program */
+ char **r_aliases; /* alias list */
+ int r_number; /* rpc program number */
+};
+struct rpcent *getrpcbyname(), *getrpcbynumber(), *getrpcent();
+#endif /* __GNU_LIBRARY__ */
+#endif /* sun */
+
+#endif /* !_NETDB_H_ */
diff --git a/contrib/bind/include/resolv.h b/contrib/bind/include/resolv.h
new file mode 100644
index 0000000..c9c7bf3
--- /dev/null
+++ b/contrib/bind/include/resolv.h
@@ -0,0 +1,254 @@
+/*
+ * ++Copyright++ 1983, 1987, 1989, 1993
+ * -
+ * Copyright (c) 1983, 1987, 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * -
+ * Portions Copyright (c) 1993 by Digital Equipment Corporation.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies, and that
+ * the name of Digital Equipment Corporation not be used in advertising or
+ * publicity pertaining to distribution of the document or software without
+ * specific, written prior permission.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
+ * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ * -
+ * --Copyright--
+ */
+
+/*
+ * @(#)resolv.h 8.1 (Berkeley) 6/2/93
+ * $Id: resolv.h,v 8.11 1996/06/02 08:20:38 vixie Exp $
+ */
+
+#ifndef _RESOLV_H_
+#define _RESOLV_H_
+
+#include <sys/param.h>
+#if (!defined(BSD)) || (BSD < 199306)
+# include <sys/bitypes.h>
+#else
+# include <sys/types.h>
+#endif
+#include <sys/cdefs.h>
+#include <stdio.h>
+
+/*
+ * revision information. this is the release date in YYYYMMDD format.
+ * it can change every day so the right thing to do with it is use it
+ * in preprocessor commands such as "#if (__RES > 19931104)". do not
+ * compare for equality; rather, use it to determine whether your resolver
+ * is new enough to contain a certain feature.
+ */
+
+#define __RES 19960229
+
+/*
+ * Resolver configuration file.
+ * Normally not present, but may contain the address of the
+ * inital name server(s) to query and the domain search list.
+ */
+
+#ifndef _PATH_RESCONF
+#define _PATH_RESCONF "/etc/resolv.conf"
+#endif
+
+/*
+ * Global defines and variables for resolver stub.
+ */
+#define MAXNS 3 /* max # name servers we'll track */
+#define MAXDFLSRCH 3 /* # default domain levels to try */
+#define MAXDNSRCH 6 /* max # domains in search path */
+#define LOCALDOMAINPARTS 2 /* min levels in name that is "local" */
+
+#define RES_TIMEOUT 5 /* min. seconds between retries */
+#define MAXRESOLVSORT 10 /* number of net to sort on */
+#define RES_MAXNDOTS 15 /* should reflect bit field size */
+
+struct __res_state {
+ int retrans; /* retransmition time interval */
+ int retry; /* number of times to retransmit */
+ u_long options; /* option flags - see below. */
+ int nscount; /* number of name servers */
+ struct sockaddr_in
+ nsaddr_list[MAXNS]; /* address of name server */
+#define nsaddr nsaddr_list[0] /* for backward compatibility */
+ u_short id; /* current packet id */
+ char *dnsrch[MAXDNSRCH+1]; /* components of domain to search */
+ char defdname[MAXDNAME]; /* default domain */
+ u_long pfcode; /* RES_PRF_ flags - see below. */
+ unsigned ndots:4; /* threshold for initial abs. query */
+ unsigned nsort:4; /* number of elements in sort_list[] */
+ char unused[3];
+ struct {
+ struct in_addr addr;
+ u_int32_t mask;
+ } sort_list[MAXRESOLVSORT];
+ char pad[72]; /* On an i38this means 512b total. */
+};
+
+/*
+ * Resolver options (keep these in synch with res_debug.c, please)
+ */
+#define RES_INIT 0x00000001 /* address initialized */
+#define RES_DEBUG 0x00000002 /* print debug messages */
+#define RES_AAONLY 0x00000004 /* authoritative answers only (!IMPL)*/
+#define RES_USEVC 0x00000008 /* use virtual circuit */
+#define RES_PRIMARY 0x00000010 /* query primary server only (!IMPL) */
+#define RES_IGNTC 0x00000020 /* ignore trucation errors */
+#define RES_RECURSE 0x00000040 /* recursion desired */
+#define RES_DEFNAMES 0x00000080 /* use default domain name */
+#define RES_STAYOPEN 0x00000100 /* Keep TCP socket open */
+#define RES_DNSRCH 0x00000200 /* search up local domain tree */
+#define RES_INSECURE1 0x00000400 /* type 1 security disabled */
+#define RES_INSECURE2 0x00000800 /* type 2 security disabled */
+#define RES_NOALIASES 0x00001000 /* shuts off HOSTALIASES feature */
+#define RES_USE_INET6 0x00002000 /* use/map IPv6 in gethostbyname() */
+
+#define RES_DEFAULT (RES_RECURSE | RES_DEFNAMES | RES_DNSRCH)
+
+/*
+ * Resolver "pfcode" values. Used by dig.
+ */
+#define RES_PRF_STATS 0x00000001
+/* 0x00000002 */
+#define RES_PRF_CLASS 0x00000004
+#define RES_PRF_CMD 0x00000008
+#define RES_PRF_QUES 0x00000010
+#define RES_PRF_ANS 0x00000020
+#define RES_PRF_AUTH 0x00000040
+#define RES_PRF_ADD 0x00000080
+#define RES_PRF_HEAD1 0x00000100
+#define RES_PRF_HEAD2 0x00000200
+#define RES_PRF_TTLID 0x00000400
+#define RES_PRF_HEADX 0x00000800
+#define RES_PRF_QUERY 0x00001000
+#define RES_PRF_REPLY 0x00002000
+#define RES_PRF_INIT 0x00004000
+/* 0x00008000 */
+
+/* hooks are still experimental as of 4.9.2 */
+typedef enum { res_goahead, res_nextns, res_modified, res_done, res_error }
+ res_sendhookact;
+
+typedef res_sendhookact (*res_send_qhook)__P((struct sockaddr_in * const *ns,
+ const u_char **query,
+ int *querylen,
+ u_char *ans,
+ int anssiz,
+ int *resplen));
+
+typedef res_sendhookact (*res_send_rhook)__P((const struct sockaddr_in *ns,
+ const u_char *query,
+ int querylen,
+ u_char *ans,
+ int anssiz,
+ int *resplen));
+
+extern struct __res_state _res;
+
+/* Private routines shared between libc/net, named, nslookup and others. */
+#define res_hnok __res_hnok
+#define res_ownok __res_ownok
+#define res_mailok __res_mailok
+#define res_dnok __res_dnok
+#define loc_ntoa __loc_ntoa
+#define loc_aton __loc_aton
+#define dn_skipname __dn_skipname
+#define fp_query __fp_query
+#define fp_nquery __fp_nquery
+#define hostalias __hostalias
+#define putlong __putlong
+#define putshort __putshort
+#define p_class __p_class
+#define p_time __p_time
+#define p_type __p_type
+#define p_cdnname __p_cdnname
+#define p_cdname __p_cdname
+#define p_fqname __p_fqname
+#define p_rr __p_rr
+#define p_option __p_option
+#define res_randomid __res_randomid
+#define res_isourserver __res_isourserver
+#define res_nameinquery __res_nameinquery
+#define res_queriesmatch __res_queriesmatch
+__BEGIN_DECLS
+int __res_hnok __P((const char *));
+int __res_ownok __P((const char *));
+int __res_mailok __P((const char *));
+int __res_dnok __P((const char *));
+int __loc_aton __P((const char *ascii, u_char *binary));
+char * __loc_ntoa __P((const u_char *binary, char *ascii));
+int __dn_skipname __P((const u_char *, const u_char *));
+void __fp_resstat __P((struct __res_state *, FILE *));
+void __fp_query __P((const u_char *, FILE *));
+void __fp_nquery __P((const u_char *, int, FILE *));
+char *__hostalias __P((const char *));
+void __putlong __P((u_int32_t, u_char *));
+void __putshort __P((u_int16_t, u_char *));
+char *__p_time __P((u_int32_t));
+void __p_query __P((const u_char *));
+const u_char *__p_cdnname __P((const u_char *, const u_char *, int, FILE *));
+const u_char *__p_cdname __P((const u_char *, const u_char *, FILE *));
+const u_char *__p_fqname __P((const u_char *, const u_char *, FILE *));
+const u_char *__p_rr __P((const u_char *, const u_char *, FILE *));
+const char *__p_type __P((int));
+const char *__p_class __P((int));
+const char *__p_option __P((u_long option));
+int dn_comp __P((const char *, u_char *, int, u_char **, u_char **));
+int dn_expand __P((const u_char *, const u_char *, const u_char *,
+ char *, int));
+int res_init __P((void));
+u_int16_t res_randomid __P((void));
+int res_query __P((const char *, int, int, u_char *, int));
+int res_search __P((const char *, int, int, u_char *, int));
+int res_querydomain __P((const char *, const char *, int, int,
+ u_char *, int));
+int res_mkquery __P((int, const char *, int, int, const u_char *, int,
+ const u_char *, u_char *, int));
+int res_send __P((const u_char *, int, u_char *, int));
+int res_isourserver __P((const struct sockaddr_in *));
+int res_nameinquery __P((const char *, int, int,
+ const u_char *, const u_char *));
+int res_queriesmatch __P((const u_char *, const u_char *,
+ const u_char *, const u_char *));
+__END_DECLS
+
+#endif /* !_RESOLV_H_ */
diff --git a/contrib/bind/man/Makefile b/contrib/bind/man/Makefile
new file mode 100644
index 0000000..26c6af5
--- /dev/null
+++ b/contrib/bind/man/Makefile
@@ -0,0 +1,451 @@
+#
+# Makefile to install the BIND 4.9 manual entries.
+#
+# Default Configuration:
+# There are a set of default assignments immediately following this
+# note. These defaults are for BSD4.4, BSD/386, other net2-alikes,
+# and will install manual entries with following characteristics:
+# o They will be catable (i.e., passed through nroff)
+# o They will be installed in the directories
+# /usr/share/man/catN, where N is 1, 3, 5, 7, 8
+# o They will have an extension of `.0'
+#
+# Don't change these defaults. Instead, following the default configuration
+# are sets of commented values for particular systems that can be used
+# to override the default values.
+#
+
+#
+# Target directory for the manual directory tree. Eg., may be used to
+# specify the path of an NFS-mounted directory for common files.
+#
+DESTDIR=
+
+#
+# Default location for manual section directories.
+#
+DESTMAN= /usr/share/man
+
+#
+# Install manuals in ${MANDIR}N. For systems that generate catable manual
+# entries on the fly, use
+# MANDIR = man
+#
+MANDIR = cat
+
+#
+# Default extension for manual entries. To install the manual entries under
+# their `real' extensions use
+# CATEXT = $$N
+#
+CATEXT = 0
+
+#
+# Command to install manual entries
+#
+INSTALL= install
+
+#
+# `install' options to set Owner and Group for manual entries. Eg. for
+# BSD `install' use
+# MAN_OWNER = -o bin
+# MAN_GROUP = -g bin
+#
+MAN_OWNER =
+MAN_GROUP =
+
+SHELL= /bin/sh
+
+INDOT=
+XFER_INDOT=
+#
+# Uppercase versions of the above variables (`INDOT_U' and `XFER_INDOT_U')
+# are defined for use in `.TH' lines.
+#
+
+#
+# Command used to generate a manual entry. By default this produces catable
+# manual entries.
+#
+# For systems that store manuals in source form (eg SunOS 4.x and SunOS 5.x)
+# and generate catable manual entries on the fly the following assignment
+# can be used.
+# MANROFF = cat
+#
+MANROFF = ( tbl | nroff -man )
+
+#
+# Default extensions for installed manual entries. The following variables
+# have been defined to allow BIND's manual entries to be installed in the
+# right place for a given platform.
+#
+# CMD_EXT = extension for user commands (eg, dig)
+# LIB_NETWORK_EXT = extension for network library routines (eg,
+# gethostbyname)
+# FORMAT_EXT = extension for files describing file formats
+# (eg, resolver)
+# DESC_EXT = extension for descriptive files (eg, mailaddr)
+# SYS_OPS_EXT = extension system operation and maintenance commands
+# and applications. (eg, named, named-xfer, syslog)
+#
+# Associated with each variable is an additional variable with the suffix
+# `_DIR' that specifies the suffix to ${MANDIR}. It's needed because on
+# some systems, eg., Ultrix, multiple subsections (eg 3x, 3m 3n) are
+# stored in generic manual section directories (eg., man3).
+#
+# Associated with each variable is an additional variable with the suffix
+# `_U' which gives the upper case form of the variable for use in `.TH'
+# commands. Useful for platforms (such as Solaris 2) that include letters
+# in manual sections.
+#
+CMD_EXT = 1
+CMD_EXT_DIR = ${CMD_EXT}
+LIB_NETWORK_EXT = 3
+LIB_NETWORK_EXT_DIR = ${LIB_NETWORK_EXT}
+FORMAT_EXT = 5
+FORMAT_EXT_DIR = ${FORMAT_EXT}
+DESC_EXT = 7
+DESC_EXT_DIR = ${DESC_EXT}
+SYS_OPS_EXT = 8
+SYS_OPS_EXT_DIR = ${SYS_OPS_EXT}
+
+#
+# Additional variables are defined for cross-references within manual
+# entries:
+# SYSCALL_EXT = extension for system calls
+# BSD_SYSCALL_EXT = extension for BSD-specifc system calls. On some
+# systems (eg Ultrix) these appear in section 2.
+# On other system (eg SunOS 5) these are implemented
+# via a BSD-compatibility library and appear in
+# section 3.
+# LIB_C_EXT = extension for C library routines (eg, signal)
+#
+SYSCALL_EXT = 2
+SYSCALL_EXT_DIR = ${SYSCALL_EXT}
+BSD_SYSCALL_EXT = 2
+BSD_SYSCALL_EXT_DIR = ${BSD_SYSCALL_EXT}
+LIB_C_EXT = 3
+LIB_C_EXT_DIR = ${LIB_C_EXT}
+
+#
+# Platform specific assignments start here:
+#
+
+#
+# (CRAY)
+#
+
+#
+# (DEC AXP OSF/1)
+#
+#DESTMAN= /usr/share/man
+#MANDIR = man
+#CATEXT = $$N
+#MAN_OWNER = -o root
+#MAN_GROUP = -g root
+#INSTALL = installbsd
+#MANROFF = cat
+## Extensions for DEC AXP OSF/1 manual entries
+#CMD_EXT = 1
+#SYS_OPS_EXT = 8
+#LIB_NETWORK_EXT = 3
+#FORMAT_EXT = 4
+#DESC_EXT = 5
+#
+#SYSCALL_EXT = 2
+#BSD_SYSCALL_EXT = 2
+#LIB_C_EXT = 3
+
+#
+# (irix4)
+#
+
+#
+# (irix5)
+#
+
+#
+# (sunos4.x)
+#
+
+#
+# (ULTRIX, sunos, other 4.[23]bsd-alikes)
+#
+#DESTMAN= /usr/man
+#MANDIR = man
+#CATEXT = $$N
+#MAN_OWNER = -o root
+#MAN_GROUP = -g root
+#INSTALL = install
+#MANROFF = cat
+## Extensions for ULTRIX, sunos, other 4.[23]bsd-alikes manual entries
+#CMD_EXT = 1
+#SYS_OPS_EXT = 8
+#LIB_NETWORK_EXT = 3n
+#LIB_NETWORK_EXT_DIR = 3
+#FORMAT_EXT = 5
+#DESC_EXT = 7
+#
+#SYSCALL_EXT = 2
+#BSD_SYSCALL_EXT = 2
+#LIB_C_EXT = 3
+
+#
+# SunOS 5.x (Solaris 2.x)
+#
+#DESTMAN= /usr/share/man
+#MANDIR = man
+#CATEXT = $$N
+#MAN_OWNER = -o bin
+#MAN_GROUP = -g bin
+#INSTALL = /usr/ucb/install
+#MANROFF = cat
+#INDOT = in.
+#XFER_INDOT =
+## Extensions for Solaris 2.x manual entries
+#CMD_EXT = 1
+#SYS_OPS_EXT = 1m
+#LIB_NETWORK_EXT = 3n
+#FORMAT_EXT = 4
+#DESC_EXT = 5
+#
+#SYSCALL_EXT = 2
+#BSD_SYSCALL_EXT = 3b
+#LIB_C_EXT = 3c
+
+#
+# (hpux9.0)
+#
+
+#
+# (apollo domainos)
+#
+
+#
+# (AIX3)
+#
+
+#
+# (ConvexOS-10.x)
+#
+
+#
+# (NEC EWS4800 EWS-UX/V Rel4.0/Rel4.2)
+#
+
+#
+# SCO Unix 3.4.2 / ODT 3.0
+#
+
+#
+# (NeXTstep 2.1 and 3.0)
+#
+
+#
+# (Sequent Dynix/PTX)
+#
+
+######################################################################
+#
+# No user changes needed past this point.
+#
+######################################################################
+#
+# This sed command is used to update the manual entries so they refer to
+# the appropriate section of the manual for a given platform.
+#
+EXT_SED_CMD = INDOT_U=`echo "${INDOT}"|tr "[a-z]" "[A-Z]"`; \
+ export INDOT_U; \
+ XFER_INDOT_U=`echo "${XFER_INDOT}"|tr "[a-z]" "[A-Z]"`; \
+ export XFER_INDOT_U; \
+ CMD_EXT_U=`echo "${CMD_EXT}"|tr "[a-z]" "[A-Z]"`; \
+ export CMD_EXT_U; \
+ SYS_OPS_EXT_U=`echo "${SYS_OPS_EXT}"|tr "[a-z]" "[A-Z]"`; \
+ export SYS_OPS_EXT_U; \
+ LIB_NETWORK_EXT_U=`echo "${LIB_NETWORK_EXT}"|tr "[a-z]" "[A-Z]"`; \
+ export LIB_NETWORK_EXT_U; \
+ FORMAT_EXT_U=`echo "${FORMAT_EXT}"|tr "[a-z]" "[A-Z]"`; \
+ export FORMAT_EXT_U; \
+ DESC_EXT_U=`echo "${DESC_EXT}"|tr "[a-z]" "[A-Z]"`; \
+ export DESC_EXT_U; \
+ SYSCALL_EXT_U=`echo "${SYSCALL_EXT}"|tr "[a-z]" "[A-Z]"`; \
+ export SYSCALL_EXT_U; \
+ BSD_SYSCALL_EXT_U=`echo "${BSD_SYSCALL_EXT}"|tr "[a-z]" "[A-Z]"`; \
+ export BSD_SYSCALL_EXT_U; \
+ LIB_C_EXT_U=`echo "${LIB_C_EXT}"|tr "[a-z]" "[A-Z]"`; \
+ export LIB_C_EXT_U; \
+ sed -e "s/@INDOT@/${INDOT}/g" \
+ -e "s/@INDOT_U@/$${INDOT_U}/g" \
+ -e "s/@XFER_INDOT@/${XFER_INDOT}/g" \
+ -e "s/@XFER_INDOT_U@/$${XFER_INDOT_U}/g" \
+ -e "s/@CMD_EXT@/${CMD_EXT}/g" \
+ -e "s/@CMD_EXT_U@/$${CMD_EXT_U}/g" \
+ -e "s/@LIB_NETWORK_EXT@/${LIB_NETWORK_EXT}/g" \
+ -e "s/@LIB_NETWORK_EXT_U@/$${LIB_NETWORK_EXT_U}/g" \
+ -e "s/@FORMAT_EXT@/${FORMAT_EXT}/g" \
+ -e "s/@FORMAT_EXT_U@/$${FORMAT_EXT_U}/g" \
+ -e "s/@DESC_EXT@/${DESC_EXT}/g" \
+ -e "s/@DESC_EXT_U@/$${DESC_EXT_U}/g" \
+ -e "s/@SYS_OPS_EXT@/${SYS_OPS_EXT}/g" \
+ -e "s/@SYS_OPS_EXT_U@/$${SYS_OPS_EXT_U}/g" \
+ -e "s/@SYSCALL_EXT@/${SYSCALL_EXT}/g" \
+ -e "s/@SYSCALL_EXT_U@/$${SYSCALL_EXT_U}/g" \
+ -e "s/@BSD_SYSCALL_EXT@/${BSD_SYSCALL_EXT}/g" \
+ -e "s/@BSD_SYSCALL_EXT_U@/$${BSD_SYSCALL_EXT_U}/g" \
+ -e "s/@LIB_C_EXT@/${LIB_C_EXT}/g" \
+ -e "s/@LIB_C_EXT_U@/$${LIB_C_EXT_U}/g"
+
+#
+# Command used to produce manual entries
+#
+MK_MANFILE = ( ${EXT_SED_CMD} | ${MANROFF} )
+
+#
+# Extensions for the generated manual entries
+#
+CMD_OUT_EXT = out${CMD_EXT}
+LIB_NETWORK_OUT_EXT = out${LIB_NETWORK_EXT}
+FORMAT_OUT_EXT = out${FORMAT_EXT}
+DESC_OUT_EXT = out${DESC_EXT}
+SYS_OPS_OUT_EXT = out${SYS_OPS_EXT}
+
+#
+# User command manual entries
+#
+CMD_BASE = dig host dnsquery
+CMD_SRC_EXT = 1
+CMD_SRC = dig.${CMD_SRC_EXT} host.${CMD_SRC_EXT} dnsquery.${CMD_SRC_EXT}
+CMD_OUT = dig.${CMD_OUT_EXT} host.${CMD_OUT_EXT} dnsquery.${CMD_OUT_EXT}
+
+#
+# named manual entries
+#
+NAMED_BASE = named named.reload named.restart ndc
+SYS_OPS_SRC_EXT = 8
+NAMED_SRC = named.${SYS_OPS_SRC_EXT} named.reload.${SYS_OPS_SRC_EXT} \
+ named.restart.${SYS_OPS_SRC_EXT} ndc.${SYS_OPS_SRC_EXT}
+NAMED_OUT = named.${SYS_OPS_OUT_EXT} named.reload.${SYS_OPS_OUT_EXT} \
+ named.restart.${SYS_OPS_OUT_EXT} ndc.${SYS_OPS_OUT_EXT}
+
+#
+# named-xfer manual entry
+#
+NAMED_XFER_BASE = named-xfer
+NAMED_XFER_SRC = named-xfer.${SYS_OPS_SRC_EXT}
+NAMED_XFER_OUT = named-xfer.${SYS_OPS_OUT_EXT}
+
+#
+# nslookup manual entry
+#
+NSLOOKUP_BASE = nslookup
+NSLOOKUP_SRC = nslookup.${SYS_OPS_SRC_EXT}
+NSLOOKUP_OUT = nslookup.${SYS_OPS_OUT_EXT}
+
+#
+# Network library routines manual entries
+#
+LIB_NETWORK_BASE = gethostbyname resolver getnetent
+LIB_NETWORK_SRC_EXT = 3
+LIB_NETWORK_SRC = gethostbyname.${LIB_NETWORK_SRC_EXT} \
+ resolver.${LIB_NETWORK_SRC_EXT} \
+ getnetent.${LIB_NETWORK_SRC_EXT}
+LIB_NETWORK_OUT = gethostbyname.${LIB_NETWORK_OUT_EXT} \
+ resolver.${LIB_NETWORK_OUT_EXT} \
+ getnetent.${LIB_NETWORK_OUT_EXT}
+
+#
+# File format manual entries
+#
+FORMAT_BASE = resolver
+FORMAT_SRC_EXT = 5
+FORMAT_SRC = resolver.${FORMAT_SRC_EXT}
+FORMAT_OUT = resolver.${FORMAT_OUT_EXT}
+
+#
+# Feature Description manual entries
+#
+DESC_BASE = hostname mailaddr
+DESC_SRC_EXT = 7
+DESC_SRC = hostname.${DESC_SRC_EXT} mailaddr.${DESC_SRC_EXT}
+DESC_OUT = hostname.${DESC_OUT_EXT} mailaddr.${DESC_OUT_EXT}
+
+.SUFFIXES: .${CMD_SRC_EXT} .${CMD_OUT_EXT} \
+ .${SYS_OPS_SRC_EXT} .${SYS_OPS_OUT_EXT} \
+ .${LIB_NETWORK_SRC_EXT} .${LIB_NETWORK_OUT_EXT} \
+ .${FORMAT_SRC_EXT} .${FORMAT_OUT_EXT} \
+ .${DESC_SRC_EXT} .${DESC_OUT_EXT}
+
+.${CMD_SRC_EXT}.${CMD_OUT_EXT}:
+ ${MK_MANFILE} <$*.${CMD_SRC_EXT} >$*.${CMD_OUT_EXT}
+
+.${SYS_OPS_SRC_EXT}.${SYS_OPS_OUT_EXT}:
+ ${MK_MANFILE} <$*.${SYS_OPS_SRC_EXT} >$*.${SYS_OPS_OUT_EXT}
+
+.${LIB_NETWORK_SRC_EXT}.${LIB_NETWORK_OUT_EXT}:
+ ${MK_MANFILE} <$*.${LIB_NETWORK_SRC_EXT} >$*.${LIB_NETWORK_OUT_EXT}
+
+.${FORMAT_SRC_EXT}.${FORMAT_OUT_EXT}:
+ ${MK_MANFILE} <$*.${FORMAT_SRC_EXT} >$*.${FORMAT_OUT_EXT}
+
+.${DESC_SRC_EXT}.${DESC_OUT_EXT}:
+ ${MK_MANFILE} <$*.${DESC_SRC_EXT} >$*.${DESC_OUT_EXT}
+
+OUTFILES = ${CMD_OUT} ${NAMED_OUT} ${NAMED_XFER_OUT} ${NSLOOKUP_OUT} \
+ ${LIB_NETWORK_OUT} ${FORMAT_OUT} ${DESC_OUT}
+
+all: ${OUTFILES}
+
+install: ${OUTFILES} \
+ ${DESTDIR}${DESTMAN}/${MANDIR}${CMD_EXT_DIR} \
+ ${DESTDIR}${DESTMAN}/${MANDIR}${SYS_OPS_EXT_DIR} \
+ ${DESTDIR}${DESTMAN}/${MANDIR}${LIB_NETWORK_EXT_DIR} \
+ ${DESTDIR}${DESTMAN}/${MANDIR}${FORMAT_EXT_DIR} \
+ ${DESTDIR}${DESTMAN}/${MANDIR}${DESC_EXT_DIR}
+ @set -x; N=${CMD_EXT}; for f in ${CMD_BASE}; do \
+ ${INSTALL} -c -m 444 ${MAN_OWNER} ${MAN_GROUP} \
+ $${f}.${CMD_OUT_EXT} \
+ ${DESTDIR}${DESTMAN}/${MANDIR}${CMD_EXT_DIR}/$${f}.${CATEXT}; \
+ done
+ @set -x; N=${SYS_OPS_EXT}; for f in ${NAMED_BASE}; do \
+ ${INSTALL} -c -m 444 ${MAN_OWNER} ${MAN_GROUP} \
+ $${f}.${SYS_OPS_OUT_EXT} \
+ ${DESTDIR}${DESTMAN}/${MANDIR}${SYS_OPS_EXT_DIR}/${INDOT}$${f}.${CATEXT}; \
+ done
+ @set -x; N=${SYS_OPS_EXT}; for f in ${NAMED_XFER_BASE}; do \
+ ${INSTALL} -c -m 444 ${MAN_OWNER} ${MAN_GROUP} \
+ $${f}.${SYS_OPS_OUT_EXT} \
+ ${DESTDIR}${DESTMAN}/${MANDIR}${SYS_OPS_EXT_DIR}/${XFER_INDOT}$${f}.${CATEXT}; \
+ done
+ @set -x; N=${SYS_OPS_EXT}; for f in ${NSLOOKUP_BASE}; do \
+ ${INSTALL} -c -m 444 ${MAN_OWNER} ${MAN_GROUP} \
+ $${f}.${SYS_OPS_OUT_EXT} \
+ ${DESTDIR}${DESTMAN}/${MANDIR}${SYS_OPS_EXT_DIR}/$${f}.${CATEXT}; \
+ done
+ @set -x; N=${LIB_NETWORK_EXT}; for f in ${LIB_NETWORK_BASE}; do \
+ ${INSTALL} -c -m 444 ${MAN_OWNER} ${MAN_GROUP} \
+ $${f}.${LIB_NETWORK_OUT_EXT} \
+ ${DESTDIR}${DESTMAN}/${MANDIR}${LIB_NETWORK_EXT_DIR}/$${f}.${CATEXT}; \
+ done
+ @set -x; N=${FORMAT_EXT}; for f in ${FORMAT_BASE}; do \
+ ${INSTALL} -c -m 444 ${MAN_OWNER} ${MAN_GROUP} \
+ $${f}.${FORMAT_OUT_EXT} \
+ ${DESTDIR}${DESTMAN}/${MANDIR}${FORMAT_EXT_DIR}/$${f}.${CATEXT}; \
+ done
+ @set -x; N=${DESC_EXT}; for f in ${DESC_BASE}; do \
+ ${INSTALL} -c -m 444 ${MAN_OWNER} ${MAN_GROUP} \
+ $${f}.${DESC_OUT_EXT} \
+ ${DESTDIR}${DESTMAN}/${MANDIR}${DESC_EXT_DIR}/$${f}.${CATEXT}; \
+ done
+
+${DESTDIR}${DESTMAN}/${MANDIR}${CMD_EXT_DIR} \
+${DESTDIR}${DESTMAN}/${MANDIR}${SYS_OPS_EXT_DIR} \
+${DESTDIR}${DESTMAN}/${MANDIR}${LIB_NETWORK_EXT_DIR} \
+${DESTDIR}${DESTMAN}/${MANDIR}${FORMAT_EXT_DIR} \
+${DESTDIR}${DESTMAN}/${MANDIR}${DESC_EXT_DIR}:
+ mkdir $@
+
+depend:
+
+clean:
+ rm -f *~ *.BAK *.CKP *.orig
+ rm -f ${OUTFILES}
diff --git a/contrib/bind/man/dig.1 b/contrib/bind/man/dig.1
new file mode 100644
index 0000000..53f33f9
--- /dev/null
+++ b/contrib/bind/man/dig.1
@@ -0,0 +1,364 @@
+.\" $Id: dig.1,v 8.1 1994/12/15 06:24:10 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--
+.\"
+.\" Distributed with 'dig' version 2.0 from University of Southern
+.\" California Information Sciences Institute (USC-ISI).
+.\"
+.\" dig.1 2.0 (USC-ISI) 8/30/90
+.\"
+.\" Man page reformatted for this release by Andrew Cherenson
+.\" (arc@sgi.com)
+.\"
+.TH DIG @CMD_EXT_U@ "August 30, 1990"
+.SH NAME
+dig \- send domain name query packets to name servers
+.SH SYNOPSIS
+.B dig
+.RI [ @\fIserver\fP ]
+.I domain
+.RI [ "<query-type>" ]
+.RI [ "<query-class>" ]
+.RI [ "+<query-option>" ]
+.RI [ "\-<dig-option>" ]
+.RI [ "%comment" ]
+.SH DESCRIPTION
+\fIDig\fP (domain information groper) is a flexible command line tool
+which can be used to gather information from the Domain
+Name System servers. \fIDig\fP has two modes: simple interactive mode
+which makes a single query, and batch which executes a query for
+each in a list of several query lines. All query options are
+accessible from the command line.
+.PP
+The usual simple use of \fIdig\fP will take the form:
+.sp 1
+ dig @server domain query-type query-class
+.sp 1
+where:
+.IP \fIserver\fP
+may be either a domain name or a dot-notation
+Internet address. If this optional field is omitted, \fIdig\fP
+will attempt to use the default name server for your machine.
+.sp 1
+\fBNote:\fP If a domain name is specified, this will be resolved
+using the domain name system resolver (i.e., BIND). If your
+system does not support DNS, you may \fIhave\fP to specify a
+dot-notation address. Alternatively, if there is a server
+at your disposal somewhere, all that is required is that
+/etc/resolv.conf be present and indicate where the default
+name servers reside, so that \fIserver\fP itself can be
+resolved. See
+.IR resolver (@FORMAT_EXT@)
+for information on /etc/resolv.conf.
+(WARNING: Changing /etc/resolv.conf will affect
+the standard resolver library and potentially several
+programs which use it.) As an option, the user may set the
+environment variable LOCALRES to name a file which is to
+be used instead of /etc/resolv.conf (LOCALRES is specific
+to the \fIdig\fP resolver and not referenced by the standard
+resolver). If the LOCALRES variable is not set or the file
+is not readable then /etc/resolv.conf will be used.
+.IP \fIdomain\fP
+is the domain name for which you are requesting information.
+See OPTIONS [-x] for convenient way to specify inverse address
+query.
+.IP \fIquery-type\fP
+is the type of information (DNS query type) that
+you are requesting. If omitted, the default is "a" (T_A = address).
+The following types are recognized:
+.sp 1
+.ta \w'hinfoXX'u +\w'T_HINFOXX'u
+.nf
+a T_A network address
+any T_ANY all/any information about specified domain
+mx T_MX mail exchanger for the domain
+ns T_NS name servers
+soa T_SOA zone of authority record
+hinfo T_HINFO host information
+axfr T_AXFR zone transfer
+ (must ask an authoritative server)
+txt T_TXT arbitrary number of strings
+.fi
+.sp 1
+(See RFC 1035 for the complete list.)
+.IP \fIquery-class\fP
+is the network class requested in the query. If
+omitted, the default is "in" (C_IN = Internet).
+The following classes are recognized:
+.sp 1
+.ta \w'hinfoXX'u +\w'T_HINFOXX'u
+.nf
+in C_IN Internet class domain
+any C_ANY all/any class information
+.fi
+.sp 1
+(See RFC 1035 for the complete list.)
+.sp 1
+\fBNote:\fP
+"Any" can be used to specify a class and/or a type of
+query. \fIDig\fP will parse the first occurrence of "any"
+to mean query-type = T_ANY. To specify query-class =
+C_ANY you must either specify "any" twice, or set
+query-class using "\-c" option (see below).
+.SH OTHER OPTIONS
+.IP "%ignored-comment"
+"%" is used to included an argument that is simply not
+parsed. This may be useful if running \fIdig\fP in batch
+mode. Instead of resolving every @server-domain-name in
+a list of queries, you can avoid the overhead of doing
+so, and still have the domain name on the command line
+as a reference. Example:
+.sp 1
+ dig @128.9.0.32 %venera.isi.edu mx isi.edu
+.sp 1
+.IP "\-<dig option>"
+"\-" is used to specify an option which effects the
+operation of \fIdig\fP. The following options are currently
+available (although not guaranteed to be useful):
+.RS
+.IP "\-x \fIdot-notation-address\fP"
+Convenient form to specify inverse address mapping.
+Instead of "dig 32.0.9.128.in-addr.arpa" one can
+simply "dig -x 128.9.0.32".
+.IP "\-f \fIfile\fP"
+File for \fIdig\fP batch mode. The file contains a list
+of query specifications (\fIdig\fP command lines) which
+are to be executed successively. Lines beginning
+with ';', '#', or '\\n' are ignored. Other options
+may still appear on command line, and will be in
+effect for each batch query.
+.IP "\-T \fItime\fP"
+Time in seconds between start of successive
+queries when running in batch mode. Can be used
+to keep two or more batch \fIdig\fP commands running
+roughly in sync. Default is zero.
+.IP "\-p \fIport\fP"
+Port number. Query a name server listening to a
+non-standard port number. Default is 53.
+.IP "\-P[\fIping-string\fP]"
+After query returns, execute a
+.IR ping (@SYS_OPS_EXT@)
+command
+for response time comparison. This rather
+unelegantly makes a call to the shell. The last
+three lines of statistics is printed for the
+command:
+.sp 1
+ ping \-s server_name 56 3
+.sp 1
+If the optional "ping string" is present, it
+replaces "ping \-s" in the shell command.
+.IP "\-t \fIquery-type\fP"
+Specify type of query. May specify either an
+integer value to be included in the type field
+or use the abbreviated mnemonic as discussed
+above (i.e., mx = T_MX).
+.IP "\-c \fIquery-class\fP"
+Specify class of query. May specify either an
+integer value to be included in the class field
+or use the abbreviated mnemonic as discussed
+above (i.e., in = C_IN).
+.IP "\-envsav"
+This flag specifies that the \fIdig\fP environment
+(defaults, print options, etc.), after
+all of the arguments are parsed, should be saved
+to a file to become the default environment.
+Useful if you do not like the standard set of
+defaults and do not desire to include a
+large number of options each time \fIdig\fP is used.
+The environment consists of resolver state
+variable flags, timeout, and retries as well as
+the flags detailing \fIdig\fP output (see below).
+If the shell environment variable LOCALDEF is set
+to the name of a file, this is where the default
+\fIdig\fP environment is saved. If not, the file
+"DiG.env" is created in the current working directory.
+.sp 1
+\fBNote:\fP LOCALDEF is specific to the \fIdig\fP resolver,
+and will not affect operation of the standard
+resolver library.
+.sp 1
+Each time \fIdig\fP is executed, it looks for "./DiG.env"
+or the file specified by the shell environment variable
+LOCALDEF. If such file exists and is readable, then the
+environment is restored from this file
+before any arguments are parsed.
+.IP "\-envset"
+This flag only affects
+batch query runs. When "\-envset" is
+specified on a line in a \fIdig\fP batch file,
+the \fIdig\fP environment after the arguments are parsed,
+becomes the default environment for the duration of
+the batch file, or until the next line which specifies
+"\-envset".
+.IP "\-[no]stick"
+This flag only affects batch query runs.
+It specifies that the \fIdig\fP environment (as read initially
+or set by "\-envset" switch) is to be restored before each query
+(line) in a \fIdig\fP batch file.
+The default "\-nostick" means that the \fIdig\fP environment
+does not stick, hence options specified on a single line
+in a \fIdig\fP batch file will remain in effect for
+subsequent lines (i.e. they are not restored to the
+"sticky" default).
+
+.RE
+.IP "+<query option>"
+"+" is used to specify an option to be changed in the
+query packet or to change \fIdig\fP output specifics. Many
+of these are the same parameters accepted by
+.IR nslookup (@SYS_OPS_EXT@).
+If an option requires a parameter, the form is as
+follows:
+.sp 1
+ +keyword[=value]
+.sp 1
+Most keywords can be abbreviated. Parsing of the "+"
+options is very simplistic \(em a value must not be
+separated from its keyword by white space. The following
+keywords are currently available:
+.sp 1
+.nf
+.ta \w'domain=NAMEXX'u +\w'(deb)XXX'u
+Keyword Abbrev. Meaning [default]
+
+[no]debug (deb) turn on/off debugging mode [deb]
+[no]d2 turn on/off extra debugging mode [nod2]
+[no]recurse (rec) use/don't use recursive lookup [rec]
+retry=# (ret) set number of retries to # [4]
+time=# (ti) set timeout length to # seconds [4]
+[no]ko keep open option (implies vc) [noko]
+[no]vc use/don't use virtual circuit [novc]
+[no]defname (def) use/don't use default domain name [def]
+[no]search (sea) use/don't use domain search list [sea]
+domain=NAME (do) set default domain name to NAME
+[no]ignore (i) ignore/don't ignore trunc. errors [noi]
+[no]primary (pr) use/don't use primary server [nopr]
+[no]aaonly (aa) authoritative query only flag [noaa]
+[no]sort (sor) sort resource records [nosor]
+[no]cmd echo parsed arguments [cmd]
+[no]stats (st) print query statistics [st]
+[no]Header (H) print basic header [H]
+[no]header (he) print header flags [he]
+[no]ttlid (tt) print TTLs [tt]
+[no]cl print class info [nocl]
+[no]qr print outgoing query [noqr]
+[no]reply (rep) print reply [rep]
+[no]ques (qu) print question section [qu]
+[no]answer (an) print answer section [an]
+[no]author (au) print authoritative section [au]
+[no]addit (ad) print additional section [ad]
+pfdef set to default print flags
+pfmin set to minimal default print flags
+pfset=# set print flags to #
+ (# can be hex/octal/decimal)
+pfand=# bitwise and print flags with #
+pfor=# bitwise or print flags with #
+.fi
+.sp 1
+The retry and time options affect the retransmission strategy used by resolver
+library when sending datagram queries. The algorithm is as follows:
+.sp 1
+.in +5n
+.nf
+for i = 0 to retry \- 1
+ for j = 1 to num_servers
+ send_query
+ wait((time * (2**i)) / num_servers)
+ end
+end
+.fi
+.in -5n
+.sp 1
+(Note: \fIdig\fP always uses a value of 1 for num_servers.)
+.SH DETAILS
+\fIDig\fP once required a slightly modified version of the BIND
+.IR resolver (@LIB_NETWORK_EXT@)
+library. BIND's resolver has (as of BIND 4.9) been augmented to work
+properly with \fIDig\fP. Essentially, \fIDig\fP is a straight-forward
+(albeit not pretty) effort of parsing arguments and setting appropriate
+parameters. \fIDig\fP uses resolver routines res_init(), res_mkquery(),
+res_send() as well as accessing _res structure.
+.SH FILES
+.ta \w'/etc/resolv.confXX'u
+/etc/resolv.conf initial domain name and name server
+\./DiG.env default save file for default options
+.br
+ addresses
+.SH ENVIRONMENT
+LOCALRES file to use in place of /etc/resolv.conf
+.br
+LOCALDEF default environment file
+.SH AUTHOR
+Steve Hotz
+hotz@isi.edu
+.SH ACKNOWLEDGMENTS
+\fIDig\fP uses functions from
+.IR nslookup (@SYS_OPS_EXT@)
+authored by Andrew Cherenson.
+.SH BUGS
+\fIDig\fP has a serious case of "creeping featurism" -- the result of
+considering several potential uses during it's development. It would
+probably benefit from a rigorous diet. Similarly, the print flags
+and granularity of the items they specify make evident their
+rather ad hoc genesis.
+.PP
+\fIDig\fP does not consistently exit nicely (with appropriate status)
+when a problem occurs somewhere in the resolver (NOTE: most of the common
+exit cases are handled). This is particularly annoying when running in
+batch mode. If it exits abnormally (and is not caught), the entire
+batch aborts; when such an event is trapped, \fIdig\fP simply
+continues with the next query.
+.SH SEE ALSO
+@INDOT@named(@SYS_OPS_EXT@), resolver(@LIB_NETWORK_EXT@), resolver(@FORMAT_EXT@), nslookup(@SYS_OPS_EXT@)
diff --git a/contrib/bind/man/dnsquery.1 b/contrib/bind/man/dnsquery.1
new file mode 100644
index 0000000..510053a
--- /dev/null
+++ b/contrib/bind/man/dnsquery.1
@@ -0,0 +1,164 @@
+.TH DNSQUERY @CMD_EXT_U@ "10 March 1990"
+.UC 6
+.SH NAME
+dnsquery \- query domain name servers using resolver
+.SH SYNOPSIS
+.B dnsquery
+[-n
+.I nameserver]
+[-t
+.I type]
+[-c
+.I class]
+[-r
+.I retry]
+[-p
+.I retry period]
+[-d] [-s] [-v] host
+.SH DESCRIPTION
+The
+.IR dnsquery
+program is a general interface to nameservers via
+BIND resolver library calls. The program supports
+queries to the nameserver with an opcode of QUERY.
+This program is intended to be a replacement or
+supplement to programs like nstest, nsquery and
+nslookup. All arguments except for
+.IR host
+and
+.IR ns
+are treated without case-sensitivity.
+.SH OPTIONS
+.TP 1i
+.B \-n
+The nameserver to be used in the query. Nameservers can appear as either
+Internet addresses of the form w.x.y.z or can appear as domain names.
+(default: as specified in /etc/resolv.conf)
+.TP 1i
+.B \-t
+The type of resource record of interest. Types include:
+.RS 1.5i
+.TP 1i
+A
+address
+.PD 0
+.TP 1i
+NS
+nameserver
+.TP 1i
+CNAME
+canonical name
+.TP 1i
+PTR
+domain name pointer
+.TP 1i
+SOA
+start of authority
+.TP 1i
+WKS
+well-known service
+.TP 1i
+HINFO
+host information
+.TP 1i
+MINFO
+mailbox information
+.TP 1i
+MX
+mail exchange
+.TP 1i
+RP
+responsible person
+.TP 1i
+MG
+mail group member
+.TP 1i
+AFSDB
+DCE or AFS server
+.TP 1i
+ANY
+wildcard
+.RE
+.PD
+.IP
+Note that any case may be used. (default: ANY)
+.TP 1i
+.B \-c
+The class of resource records of interest.
+Classes include:
+.RS 2i
+.TP 1i
+IN
+Internet
+.PD 0
+.TP 1i
+HS
+Hesiod
+.TP 1i
+CHAOS
+Chaos
+.TP 1i
+ANY
+wildcard
+.RE
+.PD
+.IP
+Note that any case may be used. (default: IN)
+.TP 1i
+.B \-r
+The number of times to retry if the nameserver is
+not responding. (default: 4)
+.TP 1i
+.B \-p
+Period to wait before timing out. (default: RES_TIMEOUT)
+.IR options
+field. (default: any answer)
+.TP 1i
+.B \-d
+Turn on debugging. This sets the RES_DEBUG bit of the resolver's
+.IR options
+field. (default: no debugging)
+.TP 1i
+.B \-s
+Use a
+.IR stream
+rather than a packet. This uses a TCP stream connection with
+the nameserver rather than a UDP datagram. This sets the
+RES_USEVC bit of the resolver's
+.IR options
+field. (default: UDP)
+.TP 1i
+.B \-v
+Synonym for the 's' flag.
+.TP 1i
+.B host
+The name of the host (or domain) of interest.
+.SH FILES
+/etc/resolv.conf to get the default ns and search lists
+.br
+<arpa/nameser.h> list of usable RR types and classes
+.br
+<resolv.h> list of resolver flags
+.SH "SEE ALSO"
+nslookup(@SYS_OPS_EXT@), nstest(@CMD_EXT@), nsquery(@CMD_EXT@),
+named(@SYS_OPS_EXT@), resolver(@FORMAT_EXT@)
+.SH DIAGNOSTICS
+If the resolver fails to answer the query and debugging has not been
+turned on,
+.IR dnsquery
+will simply print a message like:
+.TP 1i
+Query failed (rc = 1) : Unknown host
+.LP
+The value of the return code is supplied by h_errno.
+.SH BUGS
+Queries of a class other than IN can have interesting results
+since ordinarily a nameserver only has a list of root nameservers
+for class IN resource records.
+.PP
+Query uses a call to inet_addr() to determine if the argument
+for the '-n' option is a valid Internet address. Unfortunately,
+inet_addr() seems to cause a segmentation fault with some (bad)
+addresses (e.g. 1.2.3.4.5).
+.SH AUTHOR
+Bryan Beecher
diff --git a/contrib/bind/man/gethostbyname.3 b/contrib/bind/man/gethostbyname.3
new file mode 100644
index 0000000..23432a0
--- /dev/null
+++ b/contrib/bind/man/gethostbyname.3
@@ -0,0 +1,226 @@
+.\" Copyright (c) 1983, 1987 The Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms are permitted provided
+.\" that: (1) source distributions retain this entire copyright notice and
+.\" comment, and (2) distributions including binaries display the following
+.\" acknowledgement: ``This product includes software developed by the
+.\" University of California, Berkeley and its contributors'' in the
+.\" documentation or other materials provided with the distribution and in
+.\" all advertising materials mentioning features or use of this software.
+.\" 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+.\"
+.\" @(#)gethostbyname.3 6.12 (Berkeley) 6/23/90
+.\"
+.TH GETHOSTBYNAME @LIB_NETWORK_EXT_U@ "June 23, 1990"
+.UC 5
+.SH NAME
+gethostbyname, gethostbyaddr, gethostent, sethostent, endhostent, herror \- get network host entry
+.SH SYNOPSIS
+.B "#include <netdb.h>
+.PP
+.B "extern int h_errno;
+.PP
+.B "struct hostent *gethostbyname(name)
+.br
+.B "char *name;
+.PP
+.B "struct hostent *gethostbyname2(name, af)
+.br
+.B "char *name; int af;
+.PP
+.B "struct hostent *gethostbyaddr(addr, len, type)
+.br
+.B "char *addr; int len, type;
+.PP
+.B "struct hostent *gethostent()
+.PP
+.B "sethostent(stayopen)
+.br
+.B "int stayopen;
+.PP
+.B "endhostent()
+.PP
+.B "herror(string)
+.br
+.B "char *string;
+.PP
+.SH DESCRIPTION
+.IR Gethostbyname ,
+.IR gethostbyname2 ,
+and
+.I gethostbyaddr
+each return a pointer to an object with the
+following structure describing an internet host
+referenced by name or by address, respectively.
+This structure contains either the information obtained from the name server,
+.IR @INDOT@named (@SYS_OPS_EXT@),
+or broken-out fields from a line in
+.IR /etc/hosts .
+If the local name server is not running these routines do a lookup in
+.IR /etc/hosts .
+.RS
+.PP
+.nf
+struct hostent {
+ char *h_name; /* official name of host */
+ char **h_aliases; /* alias list */
+ int h_addrtype; /* host address type */
+ int h_length; /* length of address */
+ char **h_addr_list; /* list of addresses from name server */
+};
+#define h_addr h_addr_list[0] /* address, for backward compatibility */
+.ft R
+.ad
+.fi
+.RE
+.PP
+The members of this structure are:
+.TP \w'h_addr_list'u+2n
+h_name
+Official name of the host.
+.TP \w'h_addr_list'u+2n
+h_aliases
+A zero terminated array of alternate names for the host.
+.TP \w'h_addr_list'u+2n
+h_addrtype
+The type of address being returned; usually AF_INET.
+.TP \w'h_addr_list'u+2n
+h_length
+The length, in bytes, of the address.
+.TP \w'h_addr_list'u+2n
+h_addr_list
+A zero terminated array of network addresses for the host.
+Host addresses are returned in network byte order.
+.TP \w'h_addr_list'u+2n
+h_addr
+The first address in h_addr_list; this is for backward compatibility.
+.PP
+When using the nameserver,
+.I gethostbyname
+will search for the named host in the current domain and its parents
+unless the name ends in a dot.
+If the name contains no dot, and if the environment variable ``HOSTALAIASES''
+contains the name of an alias file, the alias file will first be searched
+for an alias matching the input name.
+See
+.IR hostname (@DESC_EXT@)
+for the domain search procedure and the alias file format.
+.PP
+.I Gethostbyname2
+is an evolution of
+.I gethostbyname
+intended to allow lookups in address families other than AF_INET, for example
+AF_INET6. Currently the
+.I af
+argument must be specified as
+.I AF_INET
+else the function will return \s-2NULL\s+2 after having set
+.I h_errno
+to \s-2NETDB_INTERNAL\s+2.
+.PP
+.I Sethostent
+may be used to request the use of a connected TCP socket for queries.
+If the
+.I stayopen
+flag is non-zero,
+this sets the option to send all queries to the name server using TCP
+and to retain the connection after each call to
+.I gethostbyname
+or
+.IR gethostbyaddr .
+Otherwise, queries are performed using UDP datagrams.
+.PP
+.I Endhostent
+closes the TCP connection.
+.SH DIAGNOSTICS
+.PP
+Error return status from
+.I gethostbyname
+and
+.I gethostbyaddr
+is indicated by return of a null pointer.
+The external integer
+.IR h_errno
+may then be checked to see whether this is a temporary failure
+or an invalid or unknown host.
+The routine
+.I herror
+can be used to print an error message describing the failure.
+If its argument
+.I string
+is non-NULL, it is printed, followed by a colon and a space.
+The error message is printed with a trailing newline.
+.PP
+.IR h_errno
+can have the following values:
+.RS
+.IP NETDB_INTERNAL \w'HOST_NOT_FOUND'u+2n
+This indicates an internal error in the library, unrelated to the network
+or name service.
+.I errno
+will be valid in this case; see
+.IR perror (3).
+.IP HOST_NOT_FOUND \w'HOST_NOT_FOUND'u+2n
+No such host is known.
+.IP TRY_AGAIN \w'HOST_NOT_FOUND'u+2n
+This is usually a temporary error
+and means that the local server did not receive
+a response from an authoritative server.
+A retry at some later time may succeed.
+.IP NO_RECOVERY \w'HOST_NOT_FOUND'u+2n
+Some unexpected server failure was encountered.
+This is a non-recoverable error.
+.IP NO_DATA \w'HOST_NOT_FOUND'u+2n
+The requested name is valid but does not have an IP address;
+this is not a temporary error.
+This means that the name is known to the name server but there is no address
+associated with this name.
+Another type of request to the name server using this domain name
+will result in an answer;
+for example, a mail-forwarder may be registered for this domain.
+.RE
+.SH FILES
+/etc/hosts
+.SH "SEE ALSO"
+resolver(@LIB_NETWORK_EXT@), hosts(@FORMAT_EXT@), hostname(@DESC_EXT@), @INDOT@named(@SYS_OPS_EXT@)
+.SH CAVEAT
+.PP
+.I Gethostent
+is defined, and
+.I sethostent
+and
+.I endhostent
+are redefined,
+when
+.IR libc
+is built to use only the routines to lookup in
+.IR /etc/hosts
+and not the name server.
+.PP
+.I Gethostent
+reads the next line of
+.IR /etc/hosts ,
+opening the file if necessary.
+.PP
+.I Sethostent
+is redefined to open and rewind the file. If the
+.I stayopen
+argument is non-zero,
+the hosts data base will not be closed after each call to
+.I gethostbyname
+or
+.IR gethostbyaddr .
+.I Endhostent
+is redefined to close the file.
+.SH BUGS
+All information
+is contained in a static area
+so it must be copied if it is
+to be saved. Only the Internet
+address format is currently understood.
diff --git a/contrib/bind/man/getnetent.3 b/contrib/bind/man/getnetent.3
new file mode 100644
index 0000000..22b394e
--- /dev/null
+++ b/contrib/bind/man/getnetent.3
@@ -0,0 +1,133 @@
+.\" $Id: getnetent.3,v 8.2 1996/05/09 05:59:10 vixie Exp $
+.TH getnetent @LIB_NETWORK_EXT_U@
+.SH NAME
+getnetent, getnetbyaddr, getnetbyname, setnetent, endnetent \- get networks
+entry
+.SH SYNTAX
+.nf
+.B #include <netdb.h>
+.PP
+.B struct netent *getnetent()
+.PP
+.B struct netent *getnetbyname(\fIname\fP)
+.B char *\fIname\fP;
+.PP
+.B struct netent *getnetbyaddr(\fInet\fP, \fItype\fP)
+.B unsigned long \fInet\fP; int \fItype\fP;
+.PP
+.B void setnetent(\fIstayopen\fP)
+.B int \fIstayopen\fP;
+.PP
+.B void endnetent()
+.fi
+.SH DESCRIPTION
+The
+.IR getnetent ,
+.IR getnetbyname ,
+and
+.I getnetbyaddr
+subroutines
+each return a pointer to an object with the
+following structure
+containing the broken-out
+fields of a line in the
+.I networks
+database.
+.RS
+.PP
+.nf
+struct netent {
+ char *n_name; /* official name of net */
+ char **n_aliases; /* alias list */
+ int n_addrtype; /* net number type */
+ long n_net; /* net number */
+};
+.ft R
+.ad
+.fi
+.RE
+.PP
+The members of this structure are:
+.TP \w'n_addrtype'u+2n
+n_name
+The official name of the network.
+.TP \w'n_addrtype'u+2n
+n_aliases
+A zero terminated list of alternate names for the network.
+.TP \w'n_addrtype'u+2n
+n_addrtype
+The type of the network number returned: AF_INET.
+.TP \w'n_addrtype'u+2n
+n_net
+The network number. Network numbers are returned in machine byte
+order.
+.PP
+If the
+.I stayopen
+flag on a
+.I setnetent
+subroutine is NULL, the
+.I networks
+database is opened. Otherwise the
+.I setnetent
+has the effect of rewinding the
+.I networks
+database.
+The
+.I endnetent
+may be called to
+close the
+.I networks
+database when processing is complete.
+.PP
+The
+.I getnetent
+subroutine simply reads the next
+line while
+.I getnetbyname
+and
+.I getnetbyaddr
+search until a matching
+.I name
+or
+.I net
+number is found
+(or until EOF is encountered). The \fItype\fP must be AF_INET.
+The
+.I getnetent
+subroutine keeps a pointer in the database, allowing
+successive calls to be used
+to search the entire file.
+.PP
+A call to
+.I setnetent
+must be made before a
+.I while
+loop using
+.I getnetent
+in order to perform initialization and an
+.I endnetent
+must be used after the loop. Both
+.I getnetbyname
+and
+.I getnetbyaddr
+make calls to
+.I setnetent
+and
+.I endnetent .
+.SH FILES
+.I /etc/networks
+.SH DIAGNOSTICS
+Null pointer (0) returned on EOF or error.
+.SH SEE ALSO
+.nf
+networks(@FORMAT_EXT@)
+RFC 1101
+.SH HISTORY
+The getnetent(), getnetbyaddr(), getnetbyname(), setnetent(), and
+endnetent() functions appeared in 4.2BSD.
+.SH BUGS
+The data space used by these functions is static; if future use requires the
+data, it should be copied before any subsequent calls to these functions
+overwrite it. Only Internet network numbers are currently understood.
+Expecting network numbers to fit in no more than 32 bits is probably naive.
diff --git a/contrib/bind/man/host.1 b/contrib/bind/man/host.1
new file mode 100644
index 0000000..9ade617
--- /dev/null
+++ b/contrib/bind/man/host.1
@@ -0,0 +1,207 @@
+.\" ++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--
+.\" $Id: host.1,v 8.1 1994/12/15 06:24:10 vixie Exp $
+.TH HOST @CMD_EXT_U@
+.SH NAME
+host \- look up host names using domain server
+.SH SYNOPSIS
+host [-l] [-v] [-w] [-r] [-d] [-t querytype] [-a] host [ server ]
+.SH DESCRIPTION
+.I Host
+looks for information about Internet hosts. It gets this information
+from a set of interconnected servers that are spread across the
+country. By default, it simply converts between host names and
+Internet addresses. However with the -t or -a options, it can be used
+to find all of the information about this host that is maintained
+by the domain server.
+.PP
+The arguments can be either host names or host numbers. The program
+first attempts to interpret them as host numbers. If this fails,
+it will treat them as host names. A host number consists of
+first decimal numbers separated by dots, e.g. 128.6.4.194
+A host name
+consists of names separated by dots, e.g. topaz.rutgers.edu.
+Unless the name ends in a dot, the local domain
+is automatically tacked on the end. Thus a Rutgers user can say
+"host topaz", and it will actually look up "topaz.rutgers.edu".
+If this fails, the name is tried unchanged (in this case, "topaz").
+This same convention is used for mail and other network utilities.
+The actual suffix to tack on the end is obtained
+by looking at the results of a "hostname" call, and using everything
+starting at the first dot. (See below for a description of
+how to customize the host name lookup.)
+.PP
+The first argument is the host name you want to look up.
+If this is a number, an "inverse query" is done, i.e. the domain
+system looks in a separate set of databases used to convert numbers
+to names.
+.PP
+The second argument is optional. It
+allows you to specify a particular server to query. If you don't
+specify this argument, the default server (normally the local machine)
+is used.
+.PP
+If a name is specified, you may see output of three different kinds.
+Here is an example that shows all of them:
+.br
+ % host sun4
+.br
+ sun4.rutgers.edu is a nickname for ATHOS.RUTGERS.EDU
+.br
+ ATHOS.RUTGERS.EDU has address 128.6.5.46
+.br
+ ATHOS.RUTGERS.EDU has address 128.6.4.4
+.br
+ ATHOS.RUTGERS.EDU mail is handled by ARAMIS.RUTGERS.EDU
+.br
+The user has typed the command "host sun4". The first line indicates
+that the name "sun4.rutgers.edu" is actually a nickname. The official
+host name is "ATHOS.RUTGERS.EDU'. The next two lines show the
+address. If a system has more than one network interface, there
+will be a separate address for each. The last line indicates
+that ATHOS.RUTGERS.EDU does not receive its own mail. Mail for
+it is taken by ARAMIS.RUTGERS.EDU. There may be more than one
+such line, since some systems have more than one other system
+that will handle mail for them. Technically, every system that
+can receive mail is supposed to have an entry of this kind. If
+the system receives its own mail, there should be an entry
+the mentions the system itself, for example
+"XXX mail is handled by XXX". However many systems that receive
+their own mail do not bother to mention that fact. If a system
+has a "mail is handled by" entry, but no address, this indicates
+that it is not really part of the Internet, but a system that is
+on the network will forward mail to it. Systems on Usenet, Bitnet,
+and a number of other networks have entries of this kind.
+.PP
+There are a number of options that can be used before the
+host name. Most of these options are meaningful only to the
+staff who have to maintain the domain database.
+.PP
+The option -w causes host to wait forever for a response. Normally
+it will time out after around a minute.
+.PP
+The option -v causes printout to be in a "verbose" format. This
+is the official domain master file format, which is documented
+in the man page for "named". Without this option, output still follows
+this format in general terms, but some attempt is made to make it
+more intelligible to normal users. Without -v,
+"a", "mx", and "cname" records
+are written out as "has address", "mail is handled by", and
+"is a nickname for", and TTL and class fields are not shown.
+.PP
+The option -r causes recursion to be turned off in the request.
+This means that the name server will return only data it has in
+its own database. It will not ask other servers for more
+information.
+.PP
+The option -d turns on debugging. Network transactions are shown
+in detail.
+.PP
+The option -t allows you to specify a particular type of information
+to be looked up. The arguments are defined in the man page for
+"named". Currently supported types are a, ns, md, mf, cname,
+soa, mb, mg, mr, null, wks, ptr, hinfo, minfo, mx, uinfo,
+uid, gid, unspec, and the wildcard, which may be written
+as either "any" or "*". Types must be given in lower case.
+Note that the default is to look first for "a", and then "mx", except
+that if the verbose option is turned on, the default is only "a".
+.PP
+The option -a (for "all") is equivalent to "-v -t any".
+.PP
+The option -l causes a listing of a complete domain. E.g.
+.br
+ host -l rutgers.edu
+.br
+will give a listing of all hosts in the rutgers.edu domain. The -t
+option is used to filter what information is presented, as you
+would expect. The default is address information, which also
+include PTR and NS records. The command
+.br
+ host -l -v -t any rutgers.edu
+.br
+will give a complete download of the zone data for rutgers.edu,
+in the official master file format. (However the SOA record is
+listed twice, for arcane reasons.) NOTE: -l is implemented by
+doing a complete zone transfer and then filtering out the information
+the you have asked for. This command should be used only if it
+is absolutely necessary.
+.SH CUSTOMIZING HOST NAME LOOKUP
+In general, if the name supplied by the user does not
+have any dots in it, a default domain is appended to the end.
+This domain can be defined in /etc/resolv.conf, but is normally derived
+by taking the local hostname after its first dot. The user can override
+this, and specify a different default domain, using the environment
+variable
+.IR LOCALDOMAIN .
+In addition, the user can supply his own abbreviations for host names.
+They should be in a file consisting of one line per abbreviation.
+Each line contains an abbreviation, a space, and then the full
+host name. This file must be pointed to by an environment variable
+.IR HOSTALIASES ,
+which is the name of the file.
+.SH "See Also"
+@INDOT@named (@SYS_OPS_EXT@)
+.SH BUGS
+Unexpected effects can happen when you type a name that is not
+part of the local domain. Please always keep in mind the
+fact that the local domain name is tacked onto the end of every
+name, unless it ends in a dot. Only if this fails is the name
+used unchanged.
+.PP
+The -l option only tries the first name server listed for the
+domain that you have requested. If this server is dead, you
+may need to specify a server manually. E.g. to get a listing
+of foo.edu, you could try "host -t ns foo.edu" to get a list
+of all the name servers for foo.edu, and then try "host -l foo.edu xxx"
+for all xxx on the list of name servers, until you find one that
+works.
diff --git a/contrib/bind/man/hostname.7 b/contrib/bind/man/hostname.7
new file mode 100644
index 0000000..255c53c
--- /dev/null
+++ b/contrib/bind/man/hostname.7
@@ -0,0 +1,108 @@
+.\" Copyright (c) 1987 The Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms are permitted
+.\" provided that the above copyright notice and this paragraph are
+.\" duplicated in all such forms and that any documentation,
+.\" advertising materials, and other materials related to such
+.\" distribution and use acknowledge that the software was developed
+.\" by the University of California, Berkeley. The name of the
+.\" University may not be used to endorse or promote products derived
+.\" from this software without specific prior written permission.
+.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+.\" IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+.\" WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+.\"
+.\" @(#)hostname.7 6.4 (Berkeley) 1/16/90
+.\"
+.TH HOSTNAME @DESC_EXT_U@ "February 16, 1994"
+.UC 5
+.SH NAME
+hostname \- host name resolution description
+.SH DESCRIPTION
+Hostnames are domains. A domain is a hierarchical, dot-separated list
+of subdomains. For example, the machine \fImonet\fP, in the \fIBerkeley\fP
+subdomain of the \fIEDU\fP subdomain of the Internet Domain Name System
+would be represented as
+.br
+ \fImonet\fP.\fIBerkeley\fP.\fIEDU\fP
+.br
+(with no trailing dot).
+.PP
+Hostnames are often used with network client and server programs,
+which must generally translate the name to an address for use.
+(This task is usually performed by the library routine
+.IR gethostbyname (@LIB_NETWORK_EXT@).)
+The default method for resolving hostnames by the Internet name resolver is
+to follow \s-1RFC\s+1 1535's security recommendations. Actions can be taken
+by the administrator to override these recommendations and to have the
+resolver behave the same as earlier, non-\s-1RFC\s+1 1535 resolvers.
+.PP
+The default method (using \s-1RFC\s+1 1535 guidelines) follows:
+.PP
+If the name consists of a single component, i.e. contains no dot, and if the
+environment variable ``\s-1HOSTALIASES\s+1'' is set to the name of a file,
+that file is searched for a string matching the input hostname. The file
+should consist of lines made up of two strings separated by white-space, the
+first of which is the hostname alias, and the second of which is the complete
+hostname to be substituted for that alias. If a case-insensitive match is
+found between the hostname to be resolved and the first field of a line in
+the file, the substituted name is looked up with no further processing.
+.PP
+If there is at least one dot in the name, then the name is first tried as
+is. The number of dots to cause this action is configurable by setting the
+threshold using the ``\fIndots\fP'' option in
+.I /etc/resolv.conf
+(default: \fI1\fP). If the name ends with a dot, the trailing dot is
+removed, and the remaining name is looked up (regardless of the setting of
+the 'ndots' option) and no further processing is done.
+.PP
+If the input name does not end with a trailing dot, it is looked up by
+searching through a list of domains until a match is found. If neither the
+search option in the
+.I /etc/resolv.conf
+file or the ``\s-1LOCALDOMAIN\s+1'' environment variable is used, then the
+search list of domains contains only the full domain specified by the domain
+option (in
+.IR /etc/resolv.conf )
+or the domain used in the local hostname (see
+.IR hostname (@CMD_EXT@)
+and
+.IR resolver (@FORMAT_EXT@)).
+For example, if the ``\fIdomain\fP'' option is set to \fICS.Berkeley.EDU\fP,
+then only CS.Berkeley.EDU will be in the search list and will be the only
+domain appended to the partial hostname, for example, ``\fIlithium\fP'',
+making \fIlithium.CS.Berkeley.EDU\fP the only name to be tried using the
+search list.
+.PP
+If the search option is used in
+.I /etc/resolv.conf
+or the environment variable, ``\s-1LOCALDOMAIN\s+1'' is set by the user, then
+the search list will include what is set by these methods. For
+example, if the ``\fIsearch\fP'' option contained
+.br
+ \fICS.Berkeley.EDU CChem.Berkeley.EDU Berkeley.EDU\fP
+.br
+then the partial hostname (e.g., ``\fIlithium\fP'') will be tried with each
+domainname appended (in the same order specified). The resulting hostnames
+that would be tried are:
+.nf
+ \fIlithium.CS.Berkeley.EDU\fP
+ \fIlithium.CChem.Berkeley.EDU\fP
+ \fIlithium.Berkeley.EDU\fP
+.fi
+.PP
+The environment variable ``\s-1LOCALDOMAIN\s+1'' overrides the
+``\fIsearch\fP'' and ``\fIdomain\fP'' options, and if both search and domain
+options are present in the resolver configuration file, then only the last
+one listed is used (see
+.IR resolver (@FORMAT_EXT@)).
+.PP
+If the name was not previously tried ``as is'' (i.e., it fell below the
+``\fIndots\fP'' threshold or did not contain a dot), then the name as
+originally provided is attempted.
+.SH SEE ALSO
+.IR gethostbyname (@LIB_NETWORK_EXT@),
+.IR resolver (@FORMAT_EXT@),
+.IR mailaddr (@DESC_EXT@),
+.IR @INDOT@named (@SYS_OPS_EXT@)
diff --git a/contrib/bind/man/mailaddr.7 b/contrib/bind/man/mailaddr.7
new file mode 100644
index 0000000..9a69a4d
--- /dev/null
+++ b/contrib/bind/man/mailaddr.7
@@ -0,0 +1,135 @@
+.\" Copyright (c) 1983, 1987 The Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms are permitted
+.\" provided that the above copyright notice and this paragraph are
+.\" duplicated in all such forms and that any documentation,
+.\" advertising materials, and other materials related to such
+.\" distribution and use acknowledge that the software was developed
+.\" by the University of California, Berkeley. The name of the
+.\" University may not be used to endorse or promote products derived
+.\" from this software without specific prior written permission.
+.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+.\" IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+.\" WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+.\"
+.\" @(#)mailaddr.7 6.5 (Berkeley) 2/14/89
+.\"
+.TH MAILADDR @DESC_EXT_U@ "February 14, 1989"
+.UC 5
+.SH NAME
+mailaddr \- mail addressing description
+.SH DESCRIPTION
+Mail addresses are based on the ARPANET protocol listed at the end of this
+manual page. These addresses are in the general format
+.PP
+ user@domain
+.PP
+where a domain is a hierarchical dot separated list of subdomains. For
+example, the address
+.PP
+ eric@monet.berkeley.edu
+.PP
+is normally interpreted from right to left: the message should go to the
+ARPA name tables (which do not correspond exactly to the physical ARPANET),
+then to the Berkeley gateway, after which it should go to the local host
+monet. When the message reaches monet it is delivered to the user ``eric''.
+.PP
+Unlike some other forms of addressing, this does not imply any routing.
+Thus, although this address is specified as an ARPA address, it might
+travel by an alternate route if that were more convenient or efficient.
+For example, at Berkeley, the associated message would probably go directly
+to monet over the Ethernet rather than going via the Berkeley ARPANET
+gateway.
+.SS Abbreviation.
+.PP
+Under certain circumstances it may not be necessary to type the entire
+domain name. In general, anything following the first dot may be omitted
+if it is the same as the domain from which you are sending the message.
+For example, a user on ``calder.berkeley.edu'' could send to ``eric@monet''
+without adding the ``berkeley.edu'' since it is the same on both sending
+and receiving hosts.
+.PP
+Certain other abbreviations may be permitted as special cases. For
+example, at Berkeley, ARPANET hosts may be referenced without adding
+the ``berkeley.edu'' as long as their names do not conflict with a local
+host name.
+.SS Compatibility.
+.PP
+Certain old address formats are converted to the new format to provide
+compatibility with the previous mail system. In particular,
+.PP
+ user@host.ARPA
+.PP
+is allowed and
+.PP
+ host:user
+.PP
+is converted to
+.PP
+ user@host
+.PP
+to be consistent with the \fIrcp\fP(@CMD_EXT@) command.
+.PP
+Also, the syntax
+.PP
+ host!user
+.PP
+is converted to:
+.PP
+ user@host.UUCP
+.PP
+This is normally converted back to the ``host!user'' form before being sent
+on for compatibility with older UUCP hosts.
+.PP
+The current implementation is not able to route messages automatically through
+the UUCP network. Until that time you must explicitly tell the mail system
+which hosts to send your message through to get to your final destination.
+.SS Case Distinctions.
+.PP
+Domain names (i.e., anything after the ``@'' sign) may be given in any mixture
+of upper and lower case with the exception of UUCP hostnames. Most hosts
+accept any combination of case in user names, with the notable exception of
+MULTICS sites.
+.SS Route-addrs.
+.PP
+Under some circumstances it may be necessary to route a message through
+several hosts to get it to the final destination. Normally this routing
+is done automatically, but sometimes it is desirable to route the message
+manually. Addresses which show these relays are termed ``route-addrs.''
+These use the syntax:
+.PP
+ <@hosta,@hostb:user@hostc>
+.PP
+This specifies that the message should be sent to hosta, from there to hostb,
+and finally to hostc. This path is forced even if there is a more efficient
+path to hostc.
+.PP
+Route-addrs occur frequently on return addresses, since these are generally
+augmented by the software at each host. It is generally possible to ignore
+all but the ``user@domain'' part of the address to determine the actual
+sender.
+.SS Postmaster.
+.PP
+Every site is required to have a user or user alias designated ``postmaster''
+to which problems with the mail system may be addressed.
+.SS Other Networks.
+.PP
+Some other networks can be reached by giving the name of the network as the
+last component of the domain. \fIThis is not a standard feature\fP and may
+not be supported at all sites. For example, messages to CSNET or BITNET sites
+can often be sent to ``user@host.CSNET'' or ``user@host.BITNET'' respectively.
+.SH BUGS
+The RFC822 group syntax (``group:user1,user2,user3;'') is not supported
+except in the special case of ``group:;'' because of a conflict with old
+berknet-style addresses.
+.PP
+Route-Address syntax is grotty.
+.PP
+UUCP- and ARPANET-style addresses do not coexist politely.
+.SH SEE ALSO
+mail(@CMD_EXT@), sendmail(@SYS_OPS_EXT@);
+Crocker, D. H.,
+.ul
+Standard for the Format of Arpa Internet Text Messages,
+RFC822.
diff --git a/contrib/bind/man/named-xfer.8 b/contrib/bind/man/named-xfer.8
new file mode 100644
index 0000000..54ae2be
--- /dev/null
+++ b/contrib/bind/man/named-xfer.8
@@ -0,0 +1,146 @@
+.\" ++Copyright++ 1985
+.\" -
+.\" Copyright (c) 1985
+.\" 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--
+.\"
+.\" from named.8 6.6 (Berkeley) 2/14/89
+.\"
+.TH @XFER_INDOT_U@NAMED-XFER @SYS_OPS_EXT_U@ "June 26, 1993"
+.UC 4
+.SH NAME
+@XFER_INDOT@named-xfer \- ancillary agent for inbound zone transfers
+.SH SYNOPSIS
+.B named-xfer
+.B \-z
+.I zone_to_transfer
+.B \-f
+.I db_file
+.B \-s
+.I serial_no
+[
+.B \-d
+.I debuglevel
+] [
+.B \-l
+.I debug_log_file
+] [
+.B \-t
+.I trace_file
+] [
+.B \-p
+.I port#
+] [
+.B \-S
+]
+.I nameserver
+...
+.SH DESCRIPTION
+.I Named-xfer
+is an ancillary program executed by
+.IR @INDOT@named (@SYS_OPS_EXT@)
+to perform an inbound zone transfer. It is rarely executed directly, and
+only by system administrators who are trying to debug a zone transfer problem.
+See RFC's 1033, 1034, and 1035 for more information on the Internet
+name-domain system.
+.PP
+Options are:
+.TP
+.B \-z
+specifies the name of the zone to be transferred.
+.TP
+.B \-f
+specifies the name of the file into which the zone should be dumped
+when it is received from the primary server.
+.TP
+.B \-s
+specifies the serial number of our current copy of this zone. If the
+\s-1SOA RR\s+1 we get from the primary server does not have a serial
+number higher than this, the transfer will be aborted.
+.TP
+.B \-d
+Print debugging information.
+A number after the ``d'' determines the level of
+messages printed.
+.TP
+.B \-l
+Specifies a log file for debugging messages. The default is system-
+dependent but is usually in
+.I /var/tmp
+or
+.IR /usr/tmp .
+Note that this only applies if
+.I \-d
+is also specified.
+.TP
+.B \-t
+Specifies a trace file which will contain a protocol trace of the zone
+transfer. This is probably only of interest to people debugging the name
+server itself.
+.TP
+.B \-p
+Use a different port number. The default is the standard port number
+as returned by getservbyname(@LIB_NETWORK_EXT@) for service ``domain''.
+.TP
+.B \-S
+Perform a restricted transfer of only the SOA, NS records and glue A records
+for the zone. The SOA record will not be loaded by named but will be used to
+determine when to verify the NS records. See the ``stubs'' directive in
+.IR @INDOT@named (@SYS_OPS_EXT@)
+for more information.
+.PP
+Additional arguments are taken as name server addresses in so-called
+``dotted-quad'' syntax only; no host name are allowed here. At least
+one address must be specified. Any additional addresses will be tried
+in order if the first one fails to transfer to us successfully.
+.SH "SEE ALSO"
+@INDOT@named(@SYS_OPS_EXT@), resolver(@LIB_NETWORK_EXT@), resolver(@FORMAT_EXT@), hostname(@DESC_EXT@),
+RFC 882, RFC 883, RFC 973, RFC 974, RFC 1033, RFC 1034, RFC 1035, RFC 1123,
+\fIName Server Operations Guide for \s-1BIND\s+1\fR
diff --git a/contrib/bind/man/named.8 b/contrib/bind/man/named.8
new file mode 100644
index 0000000..fae5d51
--- /dev/null
+++ b/contrib/bind/man/named.8
@@ -0,0 +1,435 @@
+.\" ++Copyright++ 1985
+.\" -
+.\" Copyright (c) 1985
+.\" 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--
+.\"
+.\" @(#)named.8 6.6 (Berkeley) 2/14/89
+.\"
+.TH @INDOT_U@NAMED @SYS_OPS_EXT_U@ "June 20, 1995"
+.UC 4
+.SH NAME
+@INDOT@named \- Internet domain name server
+.SH SYNOPSIS
+.B @INDOT@named
+[
+.B \-d
+.I debuglevel
+] [
+.B \-p
+.IR port# [\fB/\fP\fIlocalport#\fP]
+] [{\-b}
+.I bootfile
+] [
+.B \-q
+] [
+.B \-r
+]
+.SH DESCRIPTION
+.I Named
+is the Internet domain name server.
+See RFC's 1033, 1034, and 1035 for more information on the Internet
+name-domain system. Without any arguments,
+.I named
+will read the default boot file
+.IR /etc/named.boot ,
+read any initial data and listen for queries.
+.PP
+Options are:
+.TP
+.B \-d
+Print debugging information.
+A number after the ``d'' determines the level of
+messages printed.
+.TP
+.B \-p
+Use nonstandard port numbers. The default is the standard port number
+as returned by getservbyname(@LIB_NETWORK_EXT@) for service ``domain''.
+The argument can specify two port numbers separated by a slash (``\fB/\fP'')
+in which case the first port is that used when contacting remote servers,
+and the second one is the service port bound by the local instance of
+.IR named .
+This is used mostly for debugging purposes.
+.TP
+.B \-b
+Use an alternate boot file. This is optional and allows you to
+specify a file with a leading dash.
+.TP
+.B \-q
+Trace all incoming queries if \fInamed\fP has been compiled with
+\fIQRYLOG\fP defined. \fINOTE:\fP this option is deprecated in favour
+of the boot file directive ``options query-log''.
+.TP
+.B \-r
+Turns recursion off in the server. Answers can come only from local
+(primary or secondary) zones. This can be used on root servers.
+\fINOTE:\fP this option is deprecated in favour
+of the boot file directive ``options no-recursion''.
+.PP
+Any additional argument is taken as the name of the boot file.
+If multiple boot files are specified, only the last is used.
+.PP
+The boot file contains information about where the name server is to get
+its initial data.
+Lines in the boot file cannot be continued on subsequent lines.
+The following is a small example:
+.in +2m
+.nf
+
+;
+; boot file for name server
+;
+directory /usr/local/adm/named
+
+.ta \w'forwarders\ 'u +\w'6.32.128.IN-ADDR.ARPA\ 'u +\w'128.32.137.8 128.32.137.3\ 'u
+; type domain source host/file backup file
+
+cache . root.cache
+primary Berkeley.EDU berkeley.edu.zone
+primary 32.128.IN-ADDR.ARPA ucbhosts.rev
+secondary CC.Berkeley.EDU 128.32.137.8 128.32.137.3 cc.zone.bak
+secondary 6.32.128.IN-ADDR.ARPA 128.32.137.8 128.32.137.3 cc.rev.bak
+primary 0.0.127.IN-ADDR.ARPA localhost.rev
+forwarders 10.0.0.78 10.2.0.78
+limit transfers-in 10
+limit datasize 64M
+options forward-only query-log fake-iquery
+check-names primary fail
+check-names secondary warn
+check-names response ignore
+
+.DT
+.fi
+.in
+The ``directory'' line causes the server to change its working directory to
+the directory specified. This can be important for the correct processing
+of \s-1$INCLUDE\s+1 files in primary zone files.
+.LP
+The ``cache'' line specifies that data in ``root.cache'' is to be placed in
+the backup cache. Its main use is to specify data such as locations of root
+domain servers. This cache is not used during normal operation, but is used
+as ``hints'' to find the current root servers. The file ``root.cache'' is
+in the same format as ``berkeley.edu.zone''. There can be more than one
+``cache'' file specified. The ``root.cache'' file should be retrieved
+periodically from \s-1FTP.RS.INTERNIC.NET\s+1 since it contains a list of
+root servers, and this list changes periodically.
+.LP
+The first example ``primary'' line states that the file
+``berkeley.edu.zone'' contains authoritative data for the ``Berkeley.EDU''
+zone. The file ``berkeley.edu.zone'' contains data in the master file
+format described in RFC 883. All domain names are relative to the origin, in
+this case, ``Berkeley.EDU'' (see below for a more detailed description).
+The second ``primary'' line states that the file ``ucbhosts.rev'' contains
+authoritative data for the domain ``32.128.IN-ADDR.ARPA,'' which is used to
+translate addresses in network 128.32 to hostnames. Each master file should
+begin with an SOA record for the zone (see below).
+.LP
+The first example ``secondary'' line specifies that all authoritative data
+under ``CC.Berkeley.EDU'' is to be transferred from the name server at
+128.32.137.8. If the transfer fails it will try 128.32.137.3 and continue
+trying the addresses, up to 10, listed on this line. The secondary copy is
+also authoritative for the specified domain. The first non-dotted-quad
+address on this line will be taken as a filename in which to backup the
+transferred zone. The name server will load the zone from this backup file
+if it exists when it boots, providing a complete copy even if the master
+servers are unreachable. Whenever a new copy of the domain is received by
+automatic zone transfer from one of the master servers, this file will be
+updated. If no file name is given, a temporary file will be used, and will
+be deleted after each successful zone transfer. This is not recommended
+since it is a needless waste of bandwidth. The second example ``secondary''
+line states that the address-to-hostname mapping for the subnet 128.32.136
+should be obtained from the same list of master servers as the previous zone.
+.LP
+The ``forwarders'' line specifies the addresses of sitewide servers that
+will accept recursive queries from other servers. If the boot file
+specifies one or more forwarders, then the server will send all queries for
+data not in the cache to the forwarders first. Each forwarder will be asked
+in turn until an answer is returned or the list is exhausted. If no answer
+is forthcoming from a forwarder, the server will continue as it would have
+without the forwarders line unless it is in ``forward-only'' mode. The
+forwarding facility is useful to cause a large sitewide cache to be
+generated on a master, and to reduce traffic over links to outside servers.
+It can also be used to allow servers to run that do not have direct access
+to the Internet, but wish to look up exterior names anyway.
+.LP
+The ``slave'' line (deprecated) is allowed for backward compatibility. Its
+meaning is identical to ``options forward-only''.
+.LP
+The ``sortlist'' line can be used to indicate networks that are to be
+preferred over other networks. Queries for host addresses from hosts on the
+same network as the server will receive responses with local network
+addresses listed first, then addresses on the sort list, then other
+addresses.
+.LP
+The ``xfrnets'' directive (not shown) can be used to implement primitive
+access control. If this directive is given, then your name server will
+only answer zone transfer requests from hosts which are on networks listed
+in your ``xfrnets'' directives. This directive may also be given as
+``tcplist'' for compatibility with older, interim servers.
+.LP
+The ``include'' directive (not shown) can be used to process the contents
+of some other file as though they appeared in place of the ``include''
+directive. This is useful if you have a lot of zones or if you have
+logical groupings of zones which are maintained by different people.
+The ``include'' directive takes one argument, that being the name of the
+file whose contents are to be included. No quotes are necessary around
+the file name.
+.LP
+The ``bogusns'' directive (not shown) tells \s-1BIND\s+1 that no queries
+are to be sent to the specified name server addresses (which are specified
+as dotted quads, not as domain names). This is useful when you know that
+some popular server has bad data in a zone or cache, and you want to avoid
+contamination while the problem is being fixed.
+.LP
+The ``limit'' directive can be used to change \s-1BIND\s+1's internal limits,
+some of which (\fBdatasize\fP, for example) are implemented by the system and
+others (like \fBtransfers-in\fP) by \s-1BIND\s+1 itself. The number following
+the limit name can be scaled by postfixing a ``k,'' ``m,'' or ``g'' for
+kilobytes, megabytes, and gigabytes respectively.
+\fBdatasize\fP's argument sets the process data size enforced by the kernel.
+\fINote:\fP not all systems provide a call to implement this -- on such
+systems, the use of the \fBdatasize\fP parameter of ``limit'' will result in
+a warning message.
+\fBtransfers-in\fP's argument is the number of \fInamed-xfer\fP subprocesses
+which \s-1BIND\s+1 will spawn at any one time.
+\fBtransfers-per-ns\fP's argument is the maximum number of zone transfers to
+be simultaneously initiated to any given remote name server.
+.LP
+The ``options'' directive introduces a boolean specifier that changes the
+behaviour of \s-1BIND\s+1. More than one option can be specified in a single
+directive. The currently defined options are as follows:
+\fBno-recursion\fP, which will cause \s-1BIND\s+1 to answer with a referral
+rather than actual data whenever it receives a query for a name it is not
+authoritative for -- don't set this on a server that is listed in any host's
+\fIresolv.conf\fP file;
+\fBno-fetch-glue\fP, which keeps \s-1BIND\s+1 from fetching missing glue when
+constructing the ``additional data'' section of a response; this can be used
+in conjunction with \fBno-recursion\fP to prevent \s-1BIND\s+1's cache from
+ever growing in size or becoming corrupted;
+\fBquery-log\fP, which causes all queries to be logged via
+syslog(@SYS_OPS_EXT@) -- this is a lot of data, don't turn it on lightly;
+\fBforward-only\fP, which causes the server to query only its forwarders --
+this option is normally used on machine that wishes to run a server but for
+physical or administrative reasons cannot be given access to the Internet;
+and \fBfake-iquery\fP, which tells \s-1BIND\s+1 to send back a useless and
+bogus reply to ``inverse queries'' rather than responding with an error --
+this is helpful if you have a lot of microcomputers or SunOS hosts or both.
+.LP
+The ``check-names'' directive tells \s-1BIND\s+1 to check names in either
+``primary'' or ``secondary'' zone files, or in messages (``response'')
+received during recursion (for example, those which would be forwarded back
+to a firewalled requestor). For each type of name,
+\s-1BIND\s+1 can be told to ``fail'', such that a zone would not be loaded
+or a response would not be cached or forwarded, or merely ``warn'' which
+would cause a message to be emitted in the system operations logs, or to
+``ignore'' the badness of a name and process it in the traditional fashion.
+Names are considered good if they match RFC 952's expectations (if they are
+host names), or if they consist only of printable \s-1ASCII\s+1 characters
+(if they are not host names).
+.LP
+The ``max-fetch'' directive (not shown) is allowed for backward compatibility;
+its meaning is identical to ``limit transfers-in''.
+.PP
+The master file consists of control information and a list of resource
+records for objects in the zone of the forms:
+.RS
+.nf
+
+$INCLUDE <filename> <opt_domain>
+$ORIGIN <domain>
+<domain> <opt_ttl> <opt_class> <type> <resource_record_data>
+
+.fi
+.RE
+where
+.I domain
+is "." for root, "@" for the current origin, or a standard domain
+name. If
+.I domain
+is a standard domain name that does not end with ``.'', the current origin
+is appended to the domain. Domain names ending with ``.'' are
+unmodified.
+The
+.I opt_domain
+field is used to define an origin for the data in an included file.
+It is equivalent to placing a $ORIGIN statement before the first
+line of the included file. The field is optional.
+Neither the
+.I opt_domain
+field nor $ORIGIN statements in the included file modify the current origin
+for this file.
+The
+.I opt_ttl
+field is an optional integer number for the time-to-live field.
+It defaults to zero, meaning the minimum value specified in the SOA
+record for the zone.
+The
+.I opt_class
+field is the object address type; currently only one type is supported,
+.BR IN ,
+for objects connected to the DARPA Internet.
+The
+.I type
+field contains one of the following tokens; the data expected in the
+.I resource_record_data
+field is in parentheses.
+.TP "\w'MINFO 'u"
+A
+a host address (dotted quad)
+.IP NS
+an authoritative name server (domain)
+.IP MX
+a mail exchanger (domain), preceded by a preference value (0..32767),
+with lower numeric values representing higher logical preferences.
+.IP CNAME
+the canonical name for an alias (domain)
+.IP SOA
+marks the start of a zone of authority (domain of originating host,
+domain address of maintainer, a serial number and the following
+parameters in seconds: refresh, retry, expire and minimum TTL (see RFC 883)).
+.IP NULL
+a null resource record (no format or data)
+.IP RP
+a Responsible Person for some domain name (mailbox, TXT-referral)
+.IP PTR
+a domain name pointer (domain)
+.IP HINFO
+host information (cpu_type OS_type)
+.PP
+Resource records normally end at the end of a line,
+but may be continued across lines between opening and closing parentheses.
+Comments are introduced by semicolons and continue to the end of the line.
+.PP
+Note that there are other resource record types, not shown here. You should
+consult the \s-1BIND\s+1 Operations Guide (``\s-1BOG\s+1'') for the complete
+list. Some resource record types may have been standardized in newer RFC's
+but not yet implemented in this version of \s-1BIND\s+1.
+.PP
+Each master zone file should begin with an SOA record for the zone.
+An example SOA record is as follows:
+.LP
+.nf
+@ IN SOA ucbvax.Berkeley.EDU. rwh.ucbvax.Berkeley.EDU. (
+ 1989020501 ; serial
+ 10800 ; refresh
+ 3600 ; retry
+ 3600000 ; expire
+ 86400 ) ; minimum
+.fi
+.LP
+The SOA specifies a serial number, which should be changed each time the
+master file is changed. Note that the serial number can be given as a
+dotted number, but this is a \fIvery\fP unwise thing to do since the
+translation to normal integers is via concatenation rather than
+multiplication and addition. You can spell out the year, month, day of
+month, and 0..99 version number and still fit inside the unsigned 32-bit
+size of this field. It's true that we will have to rethink this strategy in
+the year 4294 (Greg.) but we're not worried about it. Secondary servers
+check the serial number at intervals specified by the refresh time in
+seconds; if the serial number changes, a zone transfer will be done to load
+the new data. If a master server cannot be contacted when a refresh is due,
+the retry time specifies the interval at which refreshes should be attempted.
+If a master server cannot be contacted within the interval given by the
+expire time, all data from the zone is discarded by secondary servers. The
+minimum value is the time-to-live (``\s-1TTL\s+1'') used by records in the
+file with no explicit time-to-live value.
+.SH NOTES
+The boot file directives ``domain'' and ``suffixes'' have been
+obsoleted by a more useful resolver-based implementation of
+suffixing for partially qualified domain names. The prior mechanisms
+could fail under a number of situations, especially when then local
+nameserver did not have complete information.
+.sp
+The following signals have the specified effect when sent to the
+server process using the
+.IR kill (@CMD_EXT@)
+command.
+.IP SIGHUP
+Causes server to read named.boot and reload the database. If the server
+is built with the FORCED_RELOAD compile-time option, then SIGHUP will
+also cause the server to check the serial number on all secondary zones.
+Normally the serial numbers are only checked at the SOA-specified intervals.
+.IP SIGINT
+Dumps the current data base and cache to /var/tmp/named_dump.db
+.IP SIGIOT
+Dumps statistics data into /var/tmp/named.stats if the server is
+compiled with -DSTATS. Statistics data is appended to the file. Some
+systems use SIGABRT rather than SIGIOT for this.
+.IP SIGSYS
+Dumps the profiling data in /var/tmp if the server is compiled
+with profiling (server forks, chdirs and exits).
+.IP SIGTERM
+Dumps the primary and secondary database files.
+Used to save modified data on shutdown if the
+server is compiled with dynamic updating enabled.
+.IP SIGUSR1
+Turns on debugging; each SIGUSR1 increments debug level.
+(SIGEMT on older systems without SIGUSR1)
+.IP SIGUSR2
+Turns off debugging completely.
+(SIGFPE on older systems without SIGUSR2)
+.IP SIGWINCH
+Toggles logging of all incoming queries via syslog(@SYS_OPS_EXT@)
+(requires server to have been built with the QRYLOG option).
+.SH FILES
+.nf
+.ta \w'/var/tmp/named_dump.db 'u
+/etc/named.boot name server configuration boot file
+/etc/named.pid the process id (on older systems)
+/var/run/named.pid the process id (on newer systems)
+/var/tmp/named_dump.db dump of the name server database
+/var/tmp/named.run debug output
+/var/tmp/named.stats nameserver statistics data
+.fi
+.SH "SEE ALSO"
+kill(@CMD_EXT@), gethostbyname(@LIB_NETWORK_EXT@), signal(@SYSCALL_EXT@),
+resolver(@LIB_NETWORK_EXT@), resolver(@FORMAT_EXT@), hostname(@DESC_EXT@),
+RFC 882, RFC 883, RFC 973, RFC 974, RFC 1033, RFC 1034, RFC 1035, RFC 1123,
+\fIName Server Operations Guide for \s-1BIND\s+1\fR
diff --git a/contrib/bind/man/named.reload.8 b/contrib/bind/man/named.reload.8
new file mode 100644
index 0000000..b838ea0
--- /dev/null
+++ b/contrib/bind/man/named.reload.8
@@ -0,0 +1,69 @@
+.\" ++Copyright++ 1987, 1993
+.\" -
+.\" Copyright (c) 1987, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\" -
+.\" Portions Copyright (c) 1993 by Digital Equipment Corporation.
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies, and that
+.\" the name of Digital Equipment Corporation not be used in advertising or
+.\" publicity pertaining to distribution of the document or software without
+.\" specific, written prior permission.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
+.\" WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
+.\" OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
+.\" CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+.\" DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+.\" PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+.\" ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+.\" SOFTWARE.
+.\" -
+.\" --Copyright--
+.\"
+.\" from hostname.7 6.4 (Berkeley) 1/16/90
+.\"
+.TH @INDOT_U@NAMED.RELOAD @SYS_OPS_EXT_U@ "June 26, 1993"
+.UC 5
+.SH NAME
+@INDOT@named.reload \- cause the name server to synchronize its database
+.SH DESCRIPTION
+This command sends a \s-1SIGHUP\s+1 to the running name server. This
+signal is documented in
+.IR named (@SYS_OPS_EXT@).
+.SH BUGS
+Does not check to see if the name server is actually running, and could
+use a stale PID cache file which may result in the death of an unrelated
+process.
+.SH SEE ALSO
+@INDOT@named(@SYS_OPS_EXT@), @INDOT@named.restart(@SYS_OPS_EXT@)
diff --git a/contrib/bind/man/named.restart.8 b/contrib/bind/man/named.restart.8
new file mode 100644
index 0000000..034bebd
--- /dev/null
+++ b/contrib/bind/man/named.restart.8
@@ -0,0 +1,73 @@
+.\" ++Copyright++ 1987, 1993
+.\" -
+.\" Copyright (c) 1987, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\" -
+.\" Portions Copyright (c) 1993 by Digital Equipment Corporation.
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies, and that
+.\" the name of Digital Equipment Corporation not be used in advertising or
+.\" publicity pertaining to distribution of the document or software without
+.\" specific, written prior permission.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
+.\" WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
+.\" OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
+.\" CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+.\" DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+.\" PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+.\" ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+.\" SOFTWARE.
+.\" -
+.\" --Copyright--
+.\"
+.\" from hostname.7 6.4 (Berkeley) 1/16/90
+.\"
+.TH @INDOT_U@NAMED.RESTART @SYS_OPS_EXT_U@ "June 26, 1993"
+.UC 5
+.SH NAME
+@INDOT@named.restart \- stop and restart the name server
+.SH DESCRIPTION
+This command sends a \s-1SIGKILL\s+1 to the running name server and then
+starts a new one.
+.SH BUGS
+Does not check to see if the name server is actually running, and could
+use a stale PID cache file which may result in the death of an unrelated
+process.
+.PP
+Does not wait after killing the old server before starting a new one; since
+the server could take some time to die and the new one will experience a
+fatal error if the old one isn't gone by the time it starts, you can be left
+in a situation where you have no name server at all.
+.SH SEE ALSO
+@INDOT@named(@SYS_OPS_EXT@), @INDOT@named.reload(@SYS_OPS_EXT@)
diff --git a/contrib/bind/man/ndc.8 b/contrib/bind/man/ndc.8
new file mode 100644
index 0000000..6d9ecfa
--- /dev/null
+++ b/contrib/bind/man/ndc.8
@@ -0,0 +1,127 @@
+.\" Copyright (c) 1994
+.\" 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.
+.\"
+.TH @INDOT_U@NDC @SYS_OPS_EXT_U@ "November 27, 1994"
+.UC 5
+.SH NAME
+@INDOT@ndc \- name daemon control interface
+.SH SYNOPSIS
+.B @INDOT@ndc
+.I directive
+[ ... ]
+.SH DESCRIPTION
+This command allows the name server administrator to send various signals
+to the name server, or to restart it. Zero or more directives may be given,
+from the following list:
+.TP
+.B status
+Displays the current status of
+.B @INDOT@named
+as shown by
+.BR ps (1).
+.TP
+.B dumpdb
+Causes
+.B @INDOT@named
+to dump its database and cache to
+.B /var/tmp/named_dump.db
+(uses the INT signal.)
+.TP
+.B reload
+Causes
+.B @INDOT@named
+to check the serial numbers of all primary and secondary zones
+and to reload those that have changed (uses the HUP signal.)
+.TP
+.B stats
+Causes
+.B @INDOT@named
+to dump its statistics to
+.B /var/tmp/named.stats
+(uses the IOT or ABRT signal.)
+.TP
+.B trace
+Causes
+.B @INDOT@named
+to increment its ``tracing level'' by one. Whenever the tracing level
+is nonzero, trace information will be written to
+.BR /var/tmp/named.run .
+Higher tracing levels result in more detailed information.
+(Uses the USR1 signal.)
+.TP
+.B notrace
+Causes
+.B @INDOT@named
+to set its ``tracing level'' to zero, closing
+.B /var/tmp/named.run
+if it is open (uses the USR2 signal.)
+.TP
+.B querylog
+Causes
+.B @INDOT@named
+to toggle the ``query logging'' feature, which while on will result in a
+.BR syslog (3)
+of each incoming query (uses the WINCH signal.) Note that query logging
+consumes quite a lot of log file space. This directive may also be given as
+.BR qrylog .
+.TP
+.B start
+Causes
+.B @INDOT@named
+to be started, as long as it isn't already running.
+.TP
+.B stop
+Causes
+.B @INDOT@named
+to be stopped, if it is running.
+.TP
+.B restart
+Causes
+.B @INDOT@named
+to be killed and restarted.
+.SH BUGS
+Arguments to
+.B @INDOT@named
+are not preserved by
+.BR restart ,
+or known by
+.BR start .
+Some mechanism for controlling the parameters and environment should exist.
+.PP
+Implemented as a
+.BR sh (1)
+script.
+.SH AUTHOR
+Paul Vixie (Internet Software Consortium)
+.SH SEE ALSO
+@INDOT@named(@SYS_OPS_EXT@),
+@INDOT@named.reload(@SYS_OPS_EXT@),
+@INDOT@named.restart(@SYS_OPS_EXT@)
diff --git a/contrib/bind/man/nslookup.8 b/contrib/bind/man/nslookup.8
new file mode 100644
index 0000000..de0306a
--- /dev/null
+++ b/contrib/bind/man/nslookup.8
@@ -0,0 +1,387 @@
+.\"
+.\" ++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--
+.\"
+.\" @(#)nslookup.8 5.3 (Berkeley) 6/24/90
+.\"
+.TH NSLOOKUP @SYS_OPS_EXT_U@ "June 24, 1990"
+.UC 6
+.SH NAME
+nslookup \- query Internet name servers interactively
+.SH SYNOPSIS
+.B nslookup
+[
+.I \-option ...
+]
+[
+.I host-to-find
+| \- [
+.I server
+]]
+.SH DESCRIPTION
+.I Nslookup
+is a program to query Internet domain name servers.
+Nslookup has two modes: interactive and non-interactive.
+Interactive mode allows the user to query name servers for
+information about various hosts and domains or to print a list of hosts
+in a domain.
+Non-interactive mode is used to print just the name and requested information
+for a host or domain.
+.sp 1
+.SH ARGUMENTS
+Interactive mode is entered in the following cases:
+.IP a) 4
+when no arguments are given (the default name server will be used),
+.IP b) 4
+when the first argument is a hyphen (\-) and the second argument
+is the host name or Internet address of a name server.
+.LP
+Non-interactive mode is used when the name or Internet address
+of the host to be looked up
+is given as the first argument. The optional second argument specifies
+the host name or address of a name server.
+.LP
+The options listed under the ``set'' command below can be specified in
+the .nslookuprc file in the user's home directory if they are listed
+one per line. Options can also be specified
+on the command line if they precede the arguments and are prefixed with
+a hyphen. For example, to change the default query type to host information,
+and the initial timeout to 10 seconds, type:
+.sp .5v
+ nslookup \-query=hinfo \-timeout=10
+.sp .5v
+.SH "INTERACTIVE COMMANDS"
+Commands may be interrupted at any time by typing a control-C.
+To exit, type a control-D (EOF) or type exit.
+The command line length must be less than 256 characters.
+To treat a built-in command as a host name,
+precede it with an escape character (\e).
+\fBN.B.\fP an unrecognized command will be interpreted as a host name.
+.sp .5v
+.IP "\fIhost\fP [\fIserver\fP]"
+Look up information for \fIhost\fP using the current default server
+or using \fIserver\fP if specified.
+If \fIhost\fP is an Internet address and the query type is A or PTR, the
+name of the host is returned.
+If \fIhost\fP is a name and does not have a trailing period, the default
+domain name is appended to the name. (This behavior depends on the state of the
+\fBset\fP options \fBdomain\fP, \fBsrchlist\fP,
+\fBdefname\fP, and \fBsearch\fP).
+To look up a host not in the current domain, append a period to
+the name.
+.sp 1
+.IP "\fBserver\fP \fIdomain\fP"
+.ns
+.IP "\fBlserver\fP \fIdomain\fP"
+Change the default server to \fIdomain\fP.
+\fBLserver\fP uses the initial server to look up
+information about \fIdomain\fP while \fBserver\fP
+uses the current default server.
+If an authoritative answer can't be found, the names of servers
+that might have the answer are returned.
+.sp 1
+.IP \fBroot\fP
+Changes the default server to the server for the root of the domain name space.
+Currently, the host ns.internic.net is used.
+(This command is a synonym for \fBlserver ns.internic.net.\fP)
+The name of the root server can be changed with the \fBset root\fP command.
+.sp 1
+.IP "\fBfinger\fP [\fIname\fP] [\fB>\fP \fIfilename\fP]"
+.ns
+.IP "\fBfinger\fP [\fIname\fP] [\fB>>\fP \fIfilename\fP]"
+Connects with the finger server on the current host.
+The current host is defined when a previous lookup for a host
+was successful and returned address information (see the
+\fBset querytype=A\fP command).
+\fIName\fP is optional.
+\fB>\fP and \fB>>\fP can be used to redirect output in the
+usual manner.
+.sp 1
+.IP "\fBls\fR [\fIoption\fR] \fIdomain\fR [\fB>\fR \fIfilename\fR]"
+.ns
+.IP "\fBls\fR [\fIoption\fR] \fIdomain\fR [\fB>>\fR \fIfilename\fR]"
+List the information available for \fIdomain\fP, optionally creating
+or appending to \fIfilename\fP.
+The default output contains host names and their Internet addresses.
+.I Option
+can be one of the following:
+.RS
+.IP "\fB\-t \fIquerytype\fP" 4
+lists all records of the specified type (see \fIquerytype\fP below).
+.IP \fB\-a\fP 4
+lists aliases of hosts in the domain.
+synonym for \fB\-t\ \ CNAME\fP.
+.IP \fB\-d\fP 4
+lists all records for the domain.
+synonym for \fB\-t\ \ ANY\fP.
+.IP \fB\-h\fP 4
+lists CPU and operating system information for the domain.
+synonym for \fB\-t\ \ HINFO\fP.
+.IP \fB\-s\fP 4
+lists well-known services of hosts in the domain.
+synonym for \fB\-t\ \ WKS\fP.
+.P
+When output is directed to a file, hash marks are printed for every
+50 records received from the server.
+.RE
+.sp 1
+.IP "\fBview\fP \fIfilename\fP"
+Sorts and lists the output of previous \fBls\fP command(s) with
+\fImore\fP(@CMD_EXT@).
+.sp 1
+.ne 4
+.IP "\fBhelp\fP"
+.ns
+.IP "\fB?\fP"
+Prints a brief summary of commands.
+.sp 1
+.IP "\fBexit\fP"
+Exits the program.
+.sp 1
+.IP "\fBset\fP \fIkeyword\fP[=\fIvalue\fP]"
+This command is used to change state information that affects the lookups.
+Valid keywords are:
+.RS
+.IP "\fBall\fP"
+Prints the current values of the frequently-used options to \fBset\fP.
+Information about the current default server and host is also printed.
+.IP "\fBclass=\fIvalue\fR"
+Change the query class to one of:
+.RS
+.IP IN 10
+the Internet class.
+.IP CHAOS 10
+the Chaos class.
+.IP HESIOD 10
+the MIT Athena Hesiod class.
+.IP ANY 10
+wildcard (any of the above).
+.P
+The class specifies the protocol group of the information.
+.br
+(Default = IN, abbreviation = cl)
+.RE
+.IP "\fB[no]debug\fP"
+Turn debugging mode on. A lot more information is printed about the
+packet sent to the server and the resulting answer.
+.br
+(Default = nodebug, abbreviation = [no]deb)
+.IP "\fB[no]d2\fP"
+Turn exhaustive debugging mode on.
+Essentially all fields of every packet are printed.
+.br
+(Default = nod2)
+.IP "\fBdomain=\fIname\fR"
+Change the default domain name to \fIname\fP.
+The default domain name is appended to a lookup request depending on the
+state of the \fBdefname\fP and \fBsearch\fP options.
+The domain search list contains the parents of the default domain if it has
+at least two components in its name.
+For example, if the default domain
+is CC.Berkeley.EDU, the search list is CC.Berkeley.EDU and Berkeley.EDU.
+Use the \fBset srchlist\fP command to specify a different list.
+Use the \fBset all\fP command to display the list.
+.br
+(Default = value from hostname, /etc/resolv.conf or LOCALDOMAIN,
+abbreviation = do)
+.IP "\fBsrchlist=\fIname1/name2/...\fR"
+Change the default domain name to \fIname1\fP and the domain search list
+to \fIname1\fP, \fIname2\fP, etc. A maximum of 6 names separated by slashes (/)
+can be specified.
+For example,
+.sp .5v
+ set\ srchlist=lcs.MIT.EDU/ai.MIT.EDU/MIT.EDU
+.sp .5v
+sets the domain to lcs.MIT.EDU and the search list to the three names.
+This command overrides the
+default domain name and search list of the \fBset domain\fP command.
+Use the \fBset all\fP command to display the list.
+.br
+(Default = value based on hostname, /etc/resolv.conf or LOCALDOMAIN,
+abbreviation = srchl)
+.IP "\fB[no]defname\fP"
+If set, append the default domain name to a single-component lookup request
+(i.e., one that does not contain a period).
+.br
+(Default = defname, abbreviation = [no]def)
+.IP "\fB[no]search\fP"
+If the lookup request contains at least one period but doesn't end
+with a trailing period,
+append the domain names in the domain search list
+to the request until an answer is received.
+.br
+(Default = search, abbreviation = [no]sea)
+.IP "\fBport=\fIvalue\fR"
+Change the default TCP/UDP name server port to \fIvalue\fP.
+.br
+(Default = 53, abbreviation = po)
+.IP "\fBquerytype=\fIvalue\fR"
+.ns
+.IP "\fBtype=\fIvalue\fR"
+.ns
+Change the type of information query to one of:
+.RS
+.IP A 10
+the host's Internet address.
+.IP CNAME 10
+the canonical name for an alias.
+.IP HINFO 10
+the host CPU and operating system type.
+.IP MINFO 10
+the mailbox or mail list information.
+.IP MX 10
+the mail exchanger.
+.IP NS 10
+the name server for the named zone.
+.IP PTR 10
+the host name if the query is an Internet address,
+otherwise the pointer to other information.
+.IP SOA 10
+the domain's ``start-of-authority'' information.
+.IP TXT 10
+the text information.
+.IP UINFO 10
+the user information.
+.IP WKS 10
+the supported well-known services.
+.P
+Other types (ANY, AXFR, MB, MD, MF, NULL) are described in the
+RFC-1035 document.
+.br
+(Default = A, abbreviations = q, ty)
+.RE
+.IP "\fB[no]recurse\fP"
+Tell the name server to query other servers if it does not have the
+information.
+.br
+(Default = recurse, abbreviation = [no]rec)
+.IP \fBretry=\fInumber\fR
+Set the number of retries to \fInumber\fP.
+When a reply to a request is not received within a certain
+amount of time (changed with \fBset timeout\fP),
+the timeout period is doubled and the request is resent.
+The retry value controls how many times a request is resent before giving up.
+.br
+(Default = 4, abbreviation = ret)
+.IP \fBroot=\fIhost\fR
+Change the name of the root server to \fIhost\fP. This
+affects the \fBroot\fP command.
+.br
+(Default = ns.internic.net., abbreviation = ro)
+.IP \fBtimeout=\fInumber\fR
+Change the initial timeout interval
+for waiting for a reply
+to \fInumber\fP seconds.
+Each retry doubles the timeout period.
+.br
+(Default = 5 seconds, abbreviation = ti)
+.IP "\fB[no]vc\fP"
+Always use a virtual circuit when sending requests to the server.
+.br
+(Default = novc, abbreviation = [no]v)
+.IP "\fB[no]ignoretc\fP"
+Ignore packet truncation errors.
+.br
+(Default = noignoretc, abbreviation = [no]ig)
+.RE
+.SH DIAGNOSTICS
+If the lookup request was not successful, an error message is printed.
+Possible errors are:
+.IP "Timed out" 5
+The server did not respond to a request after a certain amount of
+time (changed with \fBset timeout=\fIvalue\fR)
+and a certain number of retries (changed with \fBset retry=\fIvalue\fR).
+.IP "No response from server" 5
+No name server is running on the server machine.
+.IP "No records" 5
+The server does not have resource records of the current query type for the
+host, although the host name is valid.
+The query type is specified with the \fBset querytype\fP command.
+.IP "Non-existent domain" 5
+The host or domain name does not exist.
+.IP "Connection refused" 5
+.ns
+.IP "Network is unreachable" 5
+The connection to the name or finger server could not be made
+at the current time.
+This error commonly occurs with \fBls\fP and \fBfinger\fP requests.
+.IP "Server failure" 5
+The name server found an internal inconsistency in its database
+and could not return a valid answer.
+.IP "Refused" 5
+The name server refused to service the request.
+.IP "Format error" 5
+The name server found that the request packet was not in the proper format.
+It may indicate an error in \fInslookup\fP.
+.sp 1
+.SH FILES
+.ta \w'/usr/share/misc/nslookup.helpXXX'u
+/etc/resolv.conf initial domain name and
+ name server addresses.
+.br
+$HOME/.nslookuprc user's initial options.
+.br
+/usr/share/misc/nslookup.help summary of commands.
+.SH ENVIRONMENT
+.ta \w'HOSTALIASESXXXX'u
+HOSTALIASES file containing host aliases.
+.br
+LOCALDOMAIN overrides default domain.
+.SH SEE ALSO
+resolver(@LIB_NETWORK_EXT@), resolver(@FORMAT_EXT@), @INDOT@named(@SYS_OPS_EXT@),
+.br
+RFC-1034 ``Domain Names \- Concepts and Facilities''
+.br
+RFC-1035 ``Domain Names \- Implementation and Specification''
+.SH AUTHOR
+Andrew Cherenson
diff --git a/contrib/bind/man/resolver.3 b/contrib/bind/man/resolver.3
new file mode 100644
index 0000000..2d71c14
--- /dev/null
+++ b/contrib/bind/man/resolver.3
@@ -0,0 +1,339 @@
+.\" Copyright (c) 1985, 1995 The Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms are permitted provided
+.\" that: (1) source distributions retain this entire copyright notice and
+.\" comment, and (2) distributions including binaries display the following
+.\" acknowledgement: ``This product includes software developed by the
+.\" University of California, Berkeley and its contributors'' in the
+.\" documentation or other materials provided with the distribution and in
+.\" all advertising materials mentioning features or use of this software.
+.\" 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+.\"
+.\" @(#)resolver.3 6.5 (Berkeley) 6/23/90
+.\" $Id: resolver.3,v 8.4 1996/05/09 05:59:10 vixie Exp $
+.\"
+.TH RESOLVER @LIB_NETWORK_EXT_U@ "December 11, 1995
+.UC 4
+.SH NAME
+res_query, res_search, res_mkquery, res_send, res_init, dn_comp, dn_expand \- resolver routines
+.SH SYNOPSIS
+.B #include <sys/types.h>
+.br
+.B #include <netinet/in.h>
+.br
+.B #include <arpa/nameser.h>
+.br
+.B #include <resolv.h>
+.PP
+.B "res_query(dname, class, type, answer, anslen)"
+.br
+.B const char *dname;
+.br
+.B int class, type;
+.br
+.B u_char *answer;
+.br
+.B int anslen;
+.PP
+.B "res_search(dname, class, type, answer, anslen)"
+.br
+.B const char *dname;
+.br
+.B int class, type;
+.br
+.B u_char *answer;
+.br
+.B int anslen;
+.PP
+.B "res_mkquery(op, dname, class, type, data, datalen, newrr, buf, buflen)"
+.br
+.B int op;
+.br
+.B const char *dname;
+.br
+.B int class, type;
+.br
+.B const char *data;
+.br
+.B int datalen;
+.br
+.B struct rrec *newrr;
+.br
+.B u_char *buf;
+.br
+.B int buflen;
+.PP
+.B res_send(msg, msglen, answer, anslen)
+.br
+.B const u_char *msg;
+.br
+.B int msglen;
+.br
+.B u_char *answer;
+.br
+.B int anslen;
+.PP
+.B res_init()
+.PP
+.B dn_comp(exp_dn, comp_dn, length, dnptrs, lastdnptr)
+.br
+.B const char *exp_dn;
+.br
+.B u_char *comp_dn;
+.br
+.B int length;
+.br
+.B u_char **dnptrs, **lastdnptr;
+.PP
+.B dn_expand(msg, eomorig, comp_dn, exp_dn, length)
+.br
+.B const u_char *msg, *eomorig, *comp_dn;
+.br
+.B char *exp_dn;
+.br
+.B int length;
+.PP
+.B herror(const char *s)
+.PP
+.B hstrerror(int err)
+.SH DESCRIPTION
+These routines are used for making, sending and interpreting
+query and reply messages with Internet domain name servers.
+.PP
+Global configuration and state information that is used by the
+resolver routines is kept in the structure
+.IR _res .
+Most of the values have reasonable defaults and can be ignored.
+Options
+stored in
+.I _res.options
+are defined in
+.I resolv.h
+and are as follows.
+Options are stored as a simple bit mask containing the bitwise ``or''
+of the options enabled.
+.IP RES_INIT
+True if the initial name server address and default domain name are
+initialized (i.e.,
+.I res_init
+has been called).
+.IP RES_DEBUG
+Print debugging messages.
+.IP RES_AAONLY
+Accept authoritative answers only.
+With this option,
+.I res_send
+should continue until it finds an authoritative answer or finds an error.
+Currently this is not implemented.
+.IP RES_USEVC
+Use TCP connections for queries instead of UDP datagrams.
+.IP RES_STAYOPEN
+Used with RES_USEVC to keep the TCP connection open between
+queries.
+This is useful only in programs that regularly do many queries.
+UDP should be the normal mode used.
+.IP RES_IGNTC
+Unused currently (ignore truncation errors, i.e., don't retry with TCP).
+.IP RES_RECURSE
+Set the recursion-desired bit in queries.
+This is the default.
+(\c
+.I res_send
+does not do iterative queries and expects the name server
+to handle recursion.)
+.IP RES_DEFNAMES
+If set,
+.I res_search
+will append the default domain name to single-component names
+(those that do not contain a dot).
+This option is enabled by default.
+.IP RES_DNSRCH
+If this option is set,
+.I res_search
+will search for host names in the current domain and in parent domains; see
+.IR hostname (@DESC_EXT@).
+This is used by the standard host lookup routine
+.IR gethostbyname (@LIB_NETWORK_EXT@).
+This option is enabled by default.
+.IP RES_NOALIASES
+This option turns off the user level aliasing feature controlled by
+the HOSTALIASES environment variable. Network daemons should set this option.
+.PP
+The
+.I res_init
+routine
+reads the configuration file (if any; see
+.IR resolver (@FORMAT_EXT@))
+to get the default domain name,
+search list and
+the Internet address of the local name server(s).
+If no server is configured, the host running
+the resolver is tried.
+The current domain name is defined by the hostname
+if not specified in the configuration file;
+it can be overridden by the environment variable LOCALDOMAIN.
+This environment variable may contain several blank-separated
+tokens if you wish to override the
+.I "search list"
+on a per-process basis. This is similar to the
+.I search
+command in the configuration file.
+Another environment variable (``RES_OPTIONS'') can be set to
+override certain internal resolver options which are otherwise
+set by changing fields in the
+.I _res
+structure or are inherited from the configuration file's
+.I options
+command. The syntax of the ``RES_OPTIONS'' environment variable
+is explained in
+.IR resolver (@FORMAT_EXT@).
+Initialization normally occurs on the first call
+to one of the other resolver routines.
+.PP
+The
+.I res_query
+function provides an interface to the server query mechanism.
+It constructs a query, sends it to the local server,
+awaits a response, and makes preliminary checks on the reply.
+The query requests information of the specified
+.I type
+and
+.I class
+for the specified fully-qualified domain name
+.I dname .
+The reply message is left in the
+.I answer
+buffer with length
+.I anslen
+supplied by the caller.
+.PP
+The
+.I res_search
+routine makes a query and awaits a response like
+.IR res_query ,
+but in addition, it implements the default and search rules
+controlled by the RES_DEFNAMES and RES_DNSRCH options.
+It returns the first successful reply.
+.PP
+The remaining routines are lower-level routines used by
+.IR res_query .
+The
+.I res_mkquery
+function
+constructs a standard query message and places it in
+.IR buf .
+It returns the size of the query, or \-1 if the query is
+larger than
+.IR buflen .
+The query type
+.I op
+is usually QUERY, but can be any of the query types defined in
+.IR <arpa/nameser.h> .
+The domain name for the query is given by
+.IR dname .
+.I Newrr
+is currently unused but is intended for making update messages.
+.PP
+The
+.I res_send
+routine
+sends a pre-formatted query and returns an answer.
+It will call
+.I res_init
+if RES_INIT is not set, send the query to the local name server, and
+handle timeouts and retries.
+The length of the reply message is returned, or
+\-1 if there were errors.
+.PP
+The
+.I dn_comp
+function
+compresses the domain name
+.I exp_dn
+and stores it in
+.IR comp_dn .
+The size of the compressed name is returned or \-1 if there were errors.
+The size of the array pointed to by
+.I comp_dn
+is given by
+.IR length .
+The compression uses
+an array of pointers
+.I dnptrs
+to previously-compressed names in the current message.
+The first pointer points to
+to the beginning of the message and the list ends with NULL.
+The limit to the array is specified by
+.IR lastdnptr .
+A side effect of
+.I dn_comp
+is to update the list of pointers for
+labels inserted into the message
+as the name is compressed.
+If
+.I dnptr
+is NULL, names are not compressed.
+If
+.I lastdnptr
+is NULL, the list of labels is not updated.
+.PP
+The
+.I dn_expand
+entry
+expands the compressed domain name
+.I comp_dn
+to a full domain name
+The compressed name is contained in a query or reply message;
+.I msg
+is a pointer to the beginning of the message.
+The uncompressed name is placed in the buffer indicated by
+.I exp_dn
+which is of size
+.IR length .
+The size of compressed name is returned or \-1 if there was an error.
+.PP
+The external variable
+.B h_errno
+is set whenever an error occurs during resolver operation. The following
+definitions are given in
+.BR <netdb.h> :
+.PP
+.nf
+#define NETDB_INTERNAL -1 /* see errno */
+#define NETDB_SUCCESS 0 /* no problem */
+#define HOST_NOT_FOUND 1 /* Authoritative Answer Host not found */
+#define TRY_AGAIN 2 /* Non-Authoritive not found, or SERVFAIL */
+#define NO_RECOVERY 3 /* Nonrecoverable: FORMERR, REFUSED, NOTIMP */
+#define NO_DATA 4 /* Valid name, no data for requested type */
+.ft R
+.ad
+.fi
+.PP
+The
+.B herror
+function writes a message to the diagnostic output consisting of the string
+parameter
+.BR s ,
+the constant string ": ", and a message corresponding to the value of
+.BR h_errno .
+.PP
+The
+.B hstrerror
+function returns a string which is the message text corresponding to the
+value of the
+.B err
+parameter.
+.SH FILES
+/etc/resolv.conf see resolver(@FORMAT_EXT@)
+.SH "SEE ALSO"
+gethostbyname(@LIB_NETWORK_EXT@), @INDOT@named(@SYS_OPS_EXT@), resolver(@FORMAT_EXT@), hostname(@DESC_EXT@),
+.br
+RFC1032, RFC1033, RFC1034, RFC1035, RFC974,
+.br
+SMM:11 Name Server Operations Guide for BIND
diff --git a/contrib/bind/man/resolver.5 b/contrib/bind/man/resolver.5
new file mode 100644
index 0000000..41fcf3c
--- /dev/null
+++ b/contrib/bind/man/resolver.5
@@ -0,0 +1,133 @@
+.\" Copyright (c) 1986 The Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms are permitted
+.\" provided that the above copyright notice and this paragraph are
+.\" duplicated in all such forms and that any documentation,
+.\" advertising materials, and other materials related to such
+.\" distribution and use acknowledge that the software was developed
+.\" by the University of California, Berkeley. The name of the
+.\" University may not be used to endorse or promote products derived
+.\" from this software without specific prior written permission.
+.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+.\" IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+.\" WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+.\"
+.\" @(#)resolver.5 5.9 (Berkeley) 12/14/89
+.\" $Id: resolver.5,v 8.3 1995/12/06 20:34:35 vixie Exp $
+.\"
+.TH RESOLVER @FORMAT_EXT_U@ ""November 11, 1993""
+.UC 4
+.SH NAME
+resolver \- resolver configuration file
+.SH SYNOPSIS
+/etc/resolv.conf
+.SH DESCRIPTION
+.LP
+The
+.I resolver
+is a set of routines in the C library (\c
+.IR resolv (@LIB_NETWORK_EXT@))
+that provide access to the Internet Domain Name System.
+The resolver configuration file contains information that is read
+by the resolver routines the first time they are invoked by a process.
+The file is designed to be human readable and contains a list of
+keywords with values that provide various types of resolver information.
+.LP
+On a normally configured system this file should not be necessary.
+The only name server to be queried will be on the local machine,
+the domain name is determined from the host name,
+and the domain search path is constructed from the domain name.
+.LP
+The different configuration options are:
+.TP
+\fBnameserver\fP
+Internet address (in dot notation) of a name server
+that the resolver should query.
+Up to MAXNS (currently 3) name servers may be listed,
+one per keyword.
+If there are multiple servers,
+the resolver library queries them in the order listed.
+If no \fBnameserver\fP entries are present,
+the default is to use the name server on the local machine.
+(The algorithm used is to try a name server, and if the query times out,
+try the next, until out of name servers,
+then repeat trying all the name servers
+until a maximum number of retries are made).
+.TP
+\fBdomain\fP
+Local domain name.
+Most queries for names within this domain can use short names
+relative to the local domain.
+If no \fBdomain\fP entry is present, the domain is determined
+from the local host name returned by
+\fIgethostname\fP\|(@BSD_SYSCALL_EXT@);
+the domain part is taken to be everything after the first `.'.
+Finally, if the host name does not contain a domain part, the root
+domain is assumed.
+.TP
+\fBsearch\fP
+Search list for host-name lookup.
+The search list is normally determined from the local domain name;
+by default, it contains only the local domain name.
+This may be changed by listing the desired domain search path
+following the \fIsearch\fP keyword with spaces or tabs separating
+the names.
+Most resolver queries will be attempted using each component
+of the search path in turn until a match is found.
+Note that this process may be slow and will generate a lot of network
+traffic if the servers for the listed domains are not local,
+and that queries will time out if no server is available
+for one of the domains.
+.IP
+The search list is currently limited to six domains
+with a total of 256 characters.
+.TP
+\fBsortlist\fP
+Sortlist allows addresses returned by gethostbyname to be sorted.
+A sortlist is specified by IP address netmask pairs. The netmask is
+optional and defaults to the natural netmask of the net. The IP address
+and optional network pairs are separated by slashes. Up to 10 pairs may
+be specified.
+.IP
+e.g. sortlist 130.155.160.0/255.255.240.0 130.155.0.0
+.TP
+\fBoptions\fP
+Options allows certain internal resolver variables to be modified.
+The syntax is
+.IP
+\fBoptions\fP \fIoption\fP \fI...\fP
+.IP
+where \fIoption\fP is one of the following:
+.IP
+\fBdebug\fP \(em sets RES_DEBUG in _res.options.
+.IP
+\fBndots:\fP\fIn\fP \(em sets a threshold for the number of dots which
+must appear in a name given to \fBres_query\fP (see \fIresolver\fP(@LIB_NETWORK_EXT@))
+before an \fIinitial absolute query\fP will be made. The default for
+\fIn\fP is ``1'', meaning that if there are any dots in a name, the name
+will be tried first as an absolute name before any \fIsearch list\fP
+elements are appended to it.
+.LP
+The \fIdomain\fP and \fIsearch\fP keywords are mutually exclusive.
+If more than one instance of these keywords is present,
+the last instance wins.
+.LP
+The \fIsearch\fP keyword of a system's \fIresolv.conf\fP file can be
+overridden on a per-process basis by setting the environment variable
+``\s-1LOCALDOMAIN\s+1'' to a space-separated list of search domains.
+.LP
+The \fIoptions\fP keyword of a system's \fIresolv.conf\fP file can be
+amended on a per-process basis by setting the environment variable
+``\s-1RES_OPTIONS\s+1'' to a space-separated list of resolver options
+as explained above under \fBoptions\fP.
+.LP
+The keyword and value must appear on a single line, and the keyword
+(e.g. \fBnameserver\fP) must start the line. The value follows
+the keyword, separated by white space.
+.SH FILES
+.I /etc/resolv.conf
+.SH SEE ALSO
+gethostbyname(@LIB_NETWORK_EXT@), resolver(@LIB_NETWORK_EXT@), hostname(@DESC_EXT@), @INDOT@named(@SYS_OPS_EXT@)
+.br
+Name Server Operations Guide for BIND
diff --git a/contrib/bind/named/Makefile b/contrib/bind/named/Makefile
new file mode 100644
index 0000000..edd6533
--- /dev/null
+++ b/contrib/bind/named/Makefile
@@ -0,0 +1,196 @@
+#
+# @(#)Makefile.dist 5.4 (Berkeley) 8/15/90
+# $Id: Makefile,v 8.7 1995/12/22 10:20:30 vixie Exp $
+#
+
+## ++Copyright++ 1987, 1988, 1990
+## -
+## Copyright (c) 1987, 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--
+
+## NOTE: customizing this Makefile is almost certainly the wrong thing to do.
+## unless you are a developer and intend to run "make" here a lot of times
+## per day, you should just run "make" from the top-level directory after
+## configuring _that_ Makefile with the right system-dependent values.
+
+VER = LOCAL-`date +%y%m%d.%H%M%S`
+SHELL = /bin/sh
+DESTDIR =
+
+INDOT=
+XFER_INDOT=
+#(sunos)
+#INDOT=in.
+#XFER_INDOT=in.
+
+HOSTNAMECMD = hostname || uname -n
+
+#(these defaults are reasonable for a BSD/OS test environment;
+# for real configuration, edit ../Makefile and run make from there.)
+
+COMPINCL = ../compat/include
+INCL= ../include
+RES= ../res/libresolv.a
+DESTSBIN = ${DESTDIR}/usr/sbin
+DESTEXEC = ${DESTDIR}/usr/libexec
+PIDDIR = /var/run
+CC= cc
+#CC= gcc2 -Wimplicit -Wunused -Wreturn-type
+SHELL= /bin/sh
+CDEBUG= -g
+LIBS=
+COMPLIB= ../compat/lib/lib44bsd.a
+PATH_XFER = ${DESTEXEC}/${XFER_INDOT}named-xfer
+DEFS = -D_PATH_XFER=\"${PATH_XFER}\" -D_PATH_PIDFILE=\"${PIDDIR}/named.pid\"
+INSTALL = install
+PS=ps
+IOT=ABRT
+
+CFLAGS = ${CDEBUG} -I${INCL} -I${COMPINCL} ${DEFS}
+
+HDRS= db_defs.h db_glob.h ns_defs.h ns_glob.h named.h pathnames.h tree.h
+SRCS= db_dump.c db_load.c db_lookup.c db_reload.c db_save.c db_update.c \
+ db_secure.c db_glue.c \
+ ns_forw.c ns_init.c ns_main.c ns_maint.c ns_req.c ns_resp.c \
+ ns_sort.c ns_stats.c ns_validate.c ns_ncache.c \
+ storage.c dmalloc.c tree.c
+OBJS= db_dump.o db_load.o db_lookup.o db_reload.o db_save.o db_update.o \
+ db_secure.o db_glue.o \
+ ns_forw.o ns_init.o ns_main.o ns_maint.o ns_req.o ns_resp.o \
+ ns_sort.o ns_stats.o ns_validate.o ns_ncache.o \
+ storage.o dmalloc.o tree.o
+XFERSRCS= named-xfer.c
+XFEROBJ= named-xfer.o db_glue.o storage.o dmalloc.o version.o
+
+all: named named-xfer named.reload named.restart ndc
+
+named: ${OBJS} ${RES} ${COMPLIB} version.o
+ ${CC} ${CDEBUG} ${LDFLAGS} -o $@ version.o ${OBJS} \
+ ${RES} ${COMPLIB} ${LIBS}
+
+version.o: version.c
+
+version.c: Version.c Makefile ../Makefile ${SRCS} ${HDRS}
+ (u=$${USER-root} d=`pwd` h=`${HOSTNAMECMD}` t=`date`; \
+ sed -e "s|%WHEN%|$${t}|" -e "s|%VERSION%|"${VER}"|" \
+ -e "s|%WHOANDWHERE%|$${u}@$${h}:$${d}|" \
+ < Version.c > version.c)
+
+named.reload: named.reload.sh Makefile
+ sed -e "s|%INDOT%|${INDOT}|" \
+ -e "s|%DESTSBIN%|${DESTSBIN}|" \
+ < named.reload.sh > named.reload
+ chmod +x named.reload
+
+named.restart: named.restart.sh Makefile
+ sed -e "s|%INDOT%|${INDOT}|" \
+ -e "s|%DESTSBIN%|${DESTSBIN}|" \
+ < named.restart.sh > named.restart
+ chmod +x named.restart
+
+ndc: ndc.sh Makefile
+ sed -e "s|%PIDDIR%|${PIDDIR}|" \
+ -e "s|%INDOT%|${INDOT}|" \
+ -e "s|%PS%|${PS}|" \
+ -e "s|%IOTPS%|${IOT}|" \
+ -e "s|%DESTSBIN%|${DESTSBIN}|" \
+ -e "s|%IOT%|${IOT}|" \
+ < ndc.sh > ndc
+ chmod +x ndc
+
+named-xfer: ${XFEROBJ} ${RES} ${COMPLIB}
+ ${CC} ${CDEBUG} ${LDFLAGS} -o $@ ${XFEROBJ} \
+ ${RES} ${COMPLIB} ${LIBS}
+
+centerline_named:
+ #load -I${INCL} -I${COMPINCL} ${CFLAGS} ${SRCS} \
+ version.c ${RES} ${COMPLIB} ${LIBS}
+
+centerline_obj:
+ #load -I${INCL} -I${COMPINCL} ${CFLAGS} ${OBJS} \
+ version.o ${RES} ${COMPLIB} ${LIBS}
+
+centerline_xfer:
+ #load -DXFER ${CFLAGS} ${XFERSRCS} ${RES} ${COMPLIB} ${LIBS}
+
+clean:
+ rm -f ${OBJS} ${XFEROBJ} core named named-xfer version.o version.c
+ rm -f *~ *.BAK *.CKP
+ rm -f tags .depend core named.reload named.restart ndc
+ rm -f *.orig
+
+depend .depend: ${SRCS} ${XFERSRCS}
+ mkdep ${CPPFLAGS} -I${INCL} -I${COMPINCL} ${SRCS} ${XFERSRCS}
+
+install:
+ ${INSTALL} -c -s -o bin -g bin -m 555 \
+ named ${DESTDIR}${DESTSBIN}/${INDOT}named
+ ${INSTALL} -c -s -o bin -g bin -m 555 \
+ named-xfer ${DESTDIR}${PATH_XFER}
+ ${INSTALL} -c -o bin -g bin -m 555 \
+ named.restart ${DESTDIR}${DESTSBIN}/${INDOT}named.restart
+ ${INSTALL} -c -o bin -g bin -m 555 \
+ named.reload ${DESTDIR}${DESTSBIN}/${INDOT}named.reload
+ ${INSTALL} -c -o bin -g bin -m 555 \
+ ndc ${DESTDIR}${DESTSBIN}/${INDOT}ndc
+ @echo "*** Install symlinks if needed ***"
+
+lint: ${SRCS} ${HDRS} ${XFERSRCS}
+ lint -x -Dlint ${CFLAGS} ${SRCS} ${XFERSRCS} 2>&1 \
+ | grep -v 'warning: nested comments not supported'
+
+tags: ${SRCS} ${XFERSRCS} Makefile
+ ctags -t `echo ${SRCS} ${HDRS} ${XFERSRCS}|tr ' ' '\012'|sort -u`
+
+$(SRCS):: $(HDRS)
+
+# DO NOT DELETE THIS LINE -- mkdep uses it.
+# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY.
diff --git a/contrib/bind/named/Makefile.reno b/contrib/bind/named/Makefile.reno
new file mode 100644
index 0000000..2bddd9e
--- /dev/null
+++ b/contrib/bind/named/Makefile.reno
@@ -0,0 +1,83 @@
+#
+# @(#)Makefile 5.8 (Berkeley) 7/28/90
+# $Id: Makefile.reno,v 8.1 1994/12/15 06:24:14 vixie Exp $
+#
+
+## ++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--
+
+### -DALLOW_T_UNSPEC -Dmalloc=rt_malloc -Dfree=rt_free
+### ALLOC=storage.o
+PROG= named
+MAN8= named.0
+CFLAGS= -O -DDEBUG -DSTATS
+LDADD= -lutil
+SRCS= db_dump.c db_glue.c db_load.c db_lookup.c db_reload.c db_save.c \
+ db_update.c ns_forw.c ns_init.c ns_main.c ns_maint.c ns_req.c \
+ ns_resp.c ns_sort.c ns_stats.c
+OBJS+= version.o
+CLEANFILES+=version.c version.o
+SUBDIR= tools xfer
+
+version.c: ${.CURDIR}/Version.c
+ (u=$${USER-root} d=`pwd |sed -e 's|/obj/|/src/|'` \
+ h=`hostname` t=`date`; \
+ sed -e "s|%WHEN%|$${t}|" \
+ -e "s|%WHOANDWHERE%|$${u}@$${h}:$${d}|" \
+ < ${.CURDIR}/Version.c > version.c)
+
+afterinstall:
+ install -c -o ${BINOWN} -g ${BINGRP} -m 555 ${.CURDIR}/named.restart \
+ ${.CURDIR}/named.reload ${DESTDIR}${BINDIR}
+
+.include <bsd.prog.mk>
diff --git a/contrib/bind/named/Version.c b/contrib/bind/named/Version.c
new file mode 100644
index 0000000..60a7ba8
--- /dev/null
+++ b/contrib/bind/named/Version.c
@@ -0,0 +1,88 @@
+/*
+ * @(#)Version.c 4.9 (Berkeley) 7/21/90
+ * $Id: Version.c,v 8.1 1994/12/15 06:24:14 vixie Exp $
+ */
+
+#ifndef lint
+char sccsid[] = "@(#)named %VERSION% %WHEN% %WHOANDWHERE%";
+char rcsid[] = "$Id: Version.c,v 8.1 1994/12/15 06:24:14 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/contrib/bind/named/db_defs.h b/contrib/bind/named/db_defs.h
new file mode 100644
index 0000000..7356818
--- /dev/null
+++ b/contrib/bind/named/db_defs.h
@@ -0,0 +1,183 @@
+/*
+ * from db.h 4.16 (Berkeley) 6/1/90
+ * $Id: db_defs.h,v 8.4 1996/05/17 09:10:46 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 {
+ 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 */
+ char _n_name[sizeof(void*)]; /* Counted str, malloc'ed. */
+};
+#define NAMESIZE(n) (sizeof(struct namebuf) - sizeof(void*) + 1 + n + 1)
+#define NAMELEN(nb) ((nb)._n_name[0])
+#define NAME(nb) ((nb)._n_name + 1)
+
+#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_PRIMING 0x20 /* is this update the result of priming? */
+
+#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
+
+/*
+ * getnum() options
+ */
+#define GETNUM_NONE 0x00 /* placeholder */
+#define GETNUM_SERIAL 0x01 /* treat as serial number */
+#define GETNUM_SCALED 0x02 /* permit "k", "m" suffixes, scale result */
diff --git a/contrib/bind/named/db_dump.c b/contrib/bind/named/db_dump.c
new file mode 100644
index 0000000..421c121
--- /dev/null
+++ b/contrib/bind/named/db_dump.c
@@ -0,0 +1,924 @@
+#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 8.14 1996/08/05 08:31:30 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/types.h>
+#include <sys/param.h>
+#include <sys/stat.h>
+#include <sys/socket.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", ctimel(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_NOTICE, "%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;
+ }
+ }
+
+ 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%lx)\n", (u_long)htp));
+
+ /* metric by which we determine whether a root NS pointer is still */
+ /* valid (will be written out if we do a dump). we also add some */
+ /* time buffer for safety... */
+ (void) gettime(&soon);
+ soon.tv_sec += TIMBUF;
+
+ for (np = htp->h_tab[0]; np != NULL; np = np->n_next) {
+ if (NAME(*np)[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"));
+ syslog(LOG_NOTICE, "dumping nameserver data\n");
+
+ if ((fp = fopen(dumpfile, "w")) == NULL)
+ return;
+ gettime(&tt);
+ fprintf(fp, "; Dumped at %s", ctimel(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);
+ syslog(LOG_NOTICE, "finished dumping nameserver data\n");
+}
+
+#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;
+
+ if (!zp->z_origin)
+ continue;
+
+ fprintf(fp, "; %s (type %d, class %d, source %s)\n",
+ zp->z_origin
+ ? (*zp->z_origin ? zp->z_origin : ".")
+ : "Nil",
+ zp->z_type, zp->z_class,
+ zp->z_source ? zp->z_source : "Nil");
+ fprintf(fp, ";\ttime=%lu, lastupdate=%lu, serial=%u,\n",
+ (u_long)zp->z_time, (u_long)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=%lu, xaddr=[%s], state=%04x, pid=%d\n",
+ (u_long)zp->z_ftime, inet_ntoa(zp->z_xaddr),
+ zp->z_flags, (int)zp->z_xferpid);
+ sprintf(buf, ";\tz_addr[%d]: ", zp->z_addrcnt);
+ pre = buf;
+ for (cnt = 0; cnt < zp->z_addrcnt; cnt++) {
+ fprintf(fp, "%s[%s]", pre, inet_ntoa(zp->z_addr[cnt]));
+ pre = ", ";
+ }
+ if (zp->z_addrcnt)
+ fputc('\n', fp);
+#ifdef BIND_NOTIFY
+ if (zp->z_notifylist) {
+ register struct notify *ap;
+
+ for (ap = zp->z_notifylist; ap; ap = ap->next)
+ fprintf(fp, ";\tNotify [%s] %s",
+ inet_ntoa(ap->addr),
+ ctime(&ap->last));
+ }
+#endif
+ }
+ fprintf(fp, ";; --zone table--\n");
+ return (0);
+}
+
+int
+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 (NAME(*np)[0] == '\0') {
+ if (origin[0] == '\0')
+ fprintf(fp, ".\t");
+ else
+ fprintf(fp, ".%s.\t", origin); /* ??? */
+ } else
+ fprintf(fp, "%s\t", NAME(*np));
+ if (NAMELEN(*np) < (size_t)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 != USE_MINIMUM &&
+ 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);
+ fputs(inet_ntoa(*(struct in_addr *)&n),
+ fp);
+ 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++) != '\0') {
+ fprintf(fp, "\"%.*s\"", (int)n, cp);
+ cp += n;
+ } else
+ fprintf(fp, "\"\"");
+ if ((n = *cp++) != '\0')
+ 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", (u_long)n);
+ GETLONG(n, cp);
+ fprintf(fp, " %lu", (u_long)n);
+ GETLONG(n, cp);
+ fprintf(fp, " %lu", (u_long)n);
+ GETLONG(n, cp);
+ fprintf(fp, " %lu", (u_long)n);
+ GETLONG(n, cp);
+ fprintf(fp, " %lu )", (u_long)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", (u_long)n);
+ fprintf(fp, " %s.", cp);
+ break;
+
+ case T_PX:
+ GETSHORT(n, cp);
+ fprintf(fp, "%lu", (u_long)n);
+ fprintf(fp, " %s.", cp);
+ cp += strlen((char *)cp) + 1;
+ fprintf(fp, " %s.", cp);
+ break;
+
+ case T_TXT:
+ case T_X25:
+ end = (u_char *)dp->d_data + dp->d_size;
+ (void) putc('"', fp);
+ while (cp < end) {
+ if ((n = *cp++) != '\0') {
+ 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_AAAA: {
+ char t[sizeof
+ "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"
+ ];
+
+ (void) fputs(inet_ntop(AF_INET6, dp->d_data,
+ t, sizeof t),
+ fp);
+ break;
+ }
+#ifdef LOC_RR
+ case T_LOC: {
+ char t[256];
+
+ (void) fputs(loc_ntoa(dp->d_data, t), fp);
+ break;
+ }
+#endif /* LOC_RR */
+ 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);
+ fputs(inet_ntoa(*(struct in_addr *)&addr), fp);
+ 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) {
+ TmpBuf = "BAD_MALLOC";
+ }
+ if (btoa(cp, dp->d_size, TmpBuf, TmpSize)
+ == CONV_OVERFLOW) {
+ 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, "%d %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 %d %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/contrib/bind/named/db_func.h b/contrib/bind/named/db_func.h
new file mode 100644
index 0000000..60b7f32
--- /dev/null
+++ b/contrib/bind/named/db_func.h
@@ -0,0 +1,113 @@
+/* db_proc.h - prototypes for functions in db_*.c
+ *
+ * $Id: db_func.h,v 8.9 1996/06/02 08:20:39 vixie Exp $
+ */
+
+/* ++from db_update.c++ */
+extern int db_update __P((char name[],
+ struct databuf *odp,
+ struct databuf *newdp,
+ int flags,
+ struct hashbuf *htp)),
+ findMyZone __P((struct namebuf *np, int class));
+/* --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((const char *, int));
+#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
+extern u_int db_getclev __P((const char *));
+/* --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 *, int)),
+ getnum __P((FILE *, const char *, int)),
+ db_load __P((const char *, const char *,
+ struct zoneinfo *, const char *)),
+ position_on_netlist __P((struct in_addr,
+ struct netinfo *));
+extern struct netinfo *addr_on_netlist __P((struct in_addr,
+ struct netinfo *));
+/* --from db_load.c-- */
+
+/* ++from db_glue.c++ */
+extern const char *sin_ntoa __P((const struct sockaddr_in *));
+extern void panic __P((int, const char *)),
+ buildservicelist __P((void)),
+ buildprotolist __P((void)),
+ gettime __P((struct timeval *)),
+ getname __P((struct namebuf *, char *, int));
+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((const u_char *, int)),
+ nhash __P((const char *)),
+ samedomain __P((const char *, const char *));
+extern char *protocolname __P((int)),
+ *servicename __P((u_int16_t, char *)),
+ *savestr __P((const 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
+extern char * ctimel __P((long));
+extern struct in_addr data_inaddr __P((const u_char *data));
+extern void setsignal __P((int, int, SIG_FN (*)())),
+ resignal __P((int, int, SIG_FN (*)()));
+/* --from db_glue.c-- */
+
+/* ++from db_lookup.c++ */
+extern struct namebuf *nlookup __P((const char *, struct hashbuf **,
+ const char **, int));
+extern struct namebuf *np_parent __P((struct namebuf *));
+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/contrib/bind/named/db_glob.h b/contrib/bind/named/db_glob.h
new file mode 100644
index 0000000..b339b5b
--- /dev/null
+++ b/contrib/bind/named/db_glob.h
@@ -0,0 +1,93 @@
+/*
+ * from db.h 4.16 (Berkeley) 6/1/90
+ * $Id: db_glob.h,v 8.3 1995/12/06 20:34:38 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);
+
+ /* no minimum ttl */
+DECL int min_cache_ttl INIT(0);
+
+ /* 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/contrib/bind/named/db_glue.c b/contrib/bind/named/db_glue.c
new file mode 100644
index 0000000..647ae80
--- /dev/null
+++ b/contrib/bind/named/db_glue.c
@@ -0,0 +1,835 @@
+#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 8.13 1996/06/02 08:20: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/inet.h>
+#include <arpa/nameser.h>
+#include <stdio.h>
+#include <syslog.h>
+#include <ctype.h>
+#include <netdb.h>
+#include <resolv.h>
+#include <errno.h>
+#include <signal.h>
+
+#include "named.h"
+
+struct valuelist {
+ struct valuelist *next, *prev;
+ char *name;
+ char *proto;
+ int port;
+};
+static struct valuelist *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
+
+/*XXX: sin_ntoa() should probably be in libc*/
+const char *
+sin_ntoa(sin)
+ const struct sockaddr_in *sin;
+{
+ static char ret[sizeof "[111.222.333.444].55555"];
+
+ if (!sin)
+ strcpy(ret, "[sin_ntoa(NULL)]");
+ else
+ sprintf(ret, "[%s].%u",
+ inet_ntoa(sin->sin_addr),
+ ntohs(sin->sin_port));
+ return (ret);
+}
+
+/*
+ * XXX: some day we'll make this a varargs function
+ */
+void
+panic(err, msg)
+ int err;
+ const char *msg;
+{
+ if (err == -1)
+ syslog(LOG_CRIT, "%s - ABORT", msg);
+ else
+ syslog(LOG_CRIT, "%s: %s - ABORT", msg, strerror(err));
+ signal(SIGIOT, SIG_DFL); /* no POSIX needed here. */
+ abort();
+}
+
+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));
+ if (!slp)
+ panic(errno, "malloc(servent)");
+ slp->name = savestr(sp->s_name);
+ slp->proto = savestr(sp->s_proto);
+ slp->port = ntohs((u_int16_t)sp->s_port); /* host byt order */
+ 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));
+ if (!slp)
+ panic(errno, "malloc(protoent)");
+ slp->name = savestr(pp->p_name);
+ slp->port = pp->p_proto; /* host byte order */
+ 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); /* host byte order */
+ }
+ 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, /* net byte order */
+ char *proto)
+#else
+static struct servent *
+cgetservbyport(port, proto)
+ u_int16_t port; /* net byte order */
+ char *proto;
+#endif
+{
+ register struct valuelist **list = &servicelist;
+ register struct valuelist *lp = *list;
+ static struct servent serv;
+
+ port = ntohs(port);
+ for (; lp != NULL; lp = lp->next) {
+ if (port != (u_int16_t)lp->port) /* host byte order */
+ 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; /* host byte order */
+{
+ register struct valuelist **list = &protolist;
+ register struct valuelist *lp = *list;
+ static struct protoent prot;
+
+ for (; lp != NULL; lp = lp->next)
+ if (lp->port == proto) { /* host byte order */
+ 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; /* host byte order */
+ 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) /* host byte order */
+#else
+char *
+servicename(port, proto)
+ u_int16_t port; /* host byte order */
+ 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);
+}
+
+u_int
+db_getclev(origin)
+ const char *origin;
+{
+ u_int lev = 0;
+ dprintf(12, (ddt, "db_getclev of \"%s\"", origin));
+ if (origin && *origin)
+ lev++;
+ while (origin && (origin = strchr(origin, '.'))) {
+ origin++;
+ lev++;
+ }
+ dprintf(12, (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;
+
+ do {
+ errno = 0;
+ s = close(fd);
+ } while (s < 0 && errno == EINTR);
+
+ if (s < 0 && errno != EBADF)
+ syslog(LOG_INFO, "close(%d) failed: %m", fd);
+ else
+ dprintf(3, (ddt, "close(%d) succeeded\n", fd));
+ return (s);
+}
+
+#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_INFO, "fclose(%d) failed: %m", fd);
+ 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)
+ const char *str;
+{
+ char *cp = strdup(str);
+
+ if (!cp)
+ panic(errno, "malloc(savestr)");
+ 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(%lx, %lx, %lx) -> %lx\n",
+ (u_long)dp, (u_long)np->n_data, (u_long)pdp, (u_long)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"))
+ ) {
+ syslog(LOG_ERR,
+ "rm_name(%#lx(%s)): non-nil %s pointer\n",
+ (u_long)np, NAME(*np), msg);
+ panic(-1, "rm_name");
+ }
+
+ /* unlink */
+ if (pnp) {
+ pnp->n_next = nnp;
+ } else {
+ *pp = nnp;
+ }
+
+ /* deallocate */
+ 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) {
+ i = NAMELEN(*np);
+ if (i + 1 >= buflen) {
+ *cp = '\0';
+ syslog(LOG_INFO, "domain name too long: %s...\n", buf);
+ strcpy(buf, "Name_Too_Long");
+ return;
+ }
+ if (cp != buf)
+ *cp++ = '.';
+ bcopy(NAME(*np), cp, i);
+ 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)
+ panic(errno, "malloc(saveinv)");
+ ip->i_next = NULL;
+ bzero((char *)ip->i_dname, sizeof(ip->i_dname));
+ return (ip);
+}
+
+/*
+ * Compute hash value from data.
+ */
+int
+dhash(dp, dlen)
+ register const u_char *dp;
+ int dlen;
+{
+ register u_char *cp;
+ register unsigned hval;
+ register int n;
+
+ n = dlen;
+ if (n > 8)
+ n = 8;
+ hval = 0;
+ while (--n >= 0) {
+ hval <<= 1;
+ hval += *dp++;
+ }
+ return (hval % INVHASHSZ);
+}
+#endif /*INVQ*/
+
+/* int
+ * nhash(name)
+ * compute hash for this name and return it; ignore case differences
+ */
+int
+nhash(name)
+ register const char *name;
+{
+ register u_char ch;
+ register unsigned hval;
+
+ hval = 0;
+ while ((ch = (u_char)*name++) != (u_char)'\0') {
+ if (isascii(ch) && isupper(ch))
+ ch = tolower(ch);
+ hval <<= 1;
+ hval += ch;
+ }
+ return (hval % INVHASHSZ);
+}
+
+/*
+** 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);
+}
+
+/*
+ * Since the fields in a "struct timeval" are longs, and the argument to ctime
+ * is a pointer to a time_t (which might not be a long), here's a bridge.
+ */
+char *
+ctimel(l)
+ long l;
+{
+ time_t t = (time_t)l;
+
+ return (ctime(&t));
+}
+
+/*
+ * This is nec'y for systems that croak when deref'ing unaligned pointers.
+ * SPARC is an example. Note that in_addr.s_addr needn't be a 32-bit int,
+ * so we want to avoid bcopy and let the compiler do the casting for us.
+ */
+struct in_addr
+data_inaddr(data)
+ const u_char *data;
+{
+ struct in_addr ret;
+ u_int32_t tmp;
+
+ bcopy((char *)data, (char *)&tmp, INADDRSZ);
+ ret.s_addr = tmp;
+ return (ret);
+}
+
+/* Signal abstraction. */
+
+void
+setsignal(catch, block, handler)
+ int catch, block;
+ SIG_FN (*handler)();
+{
+#ifdef POSIX_SIGNALS
+ /* Modern system - preferred. */
+ struct sigaction sa;
+ memset(&sa, 0, sizeof sa);
+ sa.sa_handler = handler;
+ sigemptyset(&sa.sa_mask);
+ if (block != -1)
+ sigaddset(&sa.sa_mask, block);
+ (void) sigaction(catch, &sa, NULL);
+#else /*POSIX_SIGNALS*/
+#ifdef SYSV
+ /* Ancient system - ugly. */
+ if (block != -1)
+ syslog(LOG_DEBUG, "danger - unable to block signal %d from %d",
+ block, catch);
+ (void) signal(catch, handler);
+#else /*SYSV*/
+ /* BSD<=4.3 system - odd. */
+ struct sigvec sv;
+ bzero(&sv, sizeof sv);
+ sv.sv_handler = handler;
+ sv.sv_mask = sigmask(block);
+ (void) sigvec(catch, &sv, NULL);
+#endif /*SYSV*/
+#endif /*POSIX_SIGNALS*/
+}
+
+void
+resignal(catch, block, handler)
+ int catch, block;
+ SIG_FN (*handler)();
+{
+#if !defined(POSIX_SIGNALS) && defined(SYSV)
+ /* Unreliable signals. Set it back up again. */
+ setsignal(catch, block, handler);
+#endif
+}
diff --git a/contrib/bind/named/db_load.c b/contrib/bind/named/db_load.c
new file mode 100644
index 0000000..dda27c9
--- /dev/null
+++ b/contrib/bind/named/db_load.c
@@ -0,0 +1,1501 @@
+#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 8.22 1996/08/05 08:31:30 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/types.h>
+#include <sys/param.h>
+#include <sys/stat.h>
+#include <sys/socket.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 <resolv.h>
+#include <errno.h>
+
+#include "named.h"
+
+static int gettoken __P((register FILE *, const char *)),
+ getnonblank __P((FILE *, const char *)),
+ getprotocol __P((FILE *, const char *)),
+ getservices __P((int, char *, FILE *, const char *));
+static void makename __P((char *, const char *));
+static int makename_ok __P((char *name, const char *origin,
+ int class,
+ enum transport transport,
+ enum context context,
+ const char *filename, int lineno));
+
+static int empty_token = 0;
+int getnum_error;
+
+/*
+ * 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 M_CLASS_CNT (sizeof(m_class) / sizeof(struct map))
+
+struct map m_type[] = {
+ { "a", T_A },
+ { "ns", T_NS },
+ { "cname", T_CNAME },
+ { "soa", T_SOA },
+ { "mb", T_MB },
+ { "mg", T_MG },
+ { "mr", T_MR },
+ { "null", T_NULL },
+ { "wks", T_WKS },
+ { "ptr", T_PTR },
+ { "hinfo", T_HINFO },
+ { "minfo", T_MINFO },
+ { "mx", T_MX },
+ { "uinfo", T_UINFO },
+ { "txt", T_TXT },
+ { "rp", T_RP },
+ { "afsdb", T_AFSDB },
+ { "x25", T_X25 },
+ { "isdn", T_ISDN },
+ { "rt", T_RT },
+ { "nsap", T_NSAP },
+ { "nsap_ptr", T_NSAP_PTR },
+ { "uid", T_UID },
+ { "gid", T_GID },
+ { "px", T_PX },
+ { "aaaa", T_AAAA },
+#ifdef notdef
+ { "any", T_ANY }, /* any is a QTYPE, not TYPE */
+#endif
+#ifdef LOC_RR
+ { "loc", T_LOC },
+#endif /* LOC_RR */
+#ifdef ALLOW_T_UNSPEC
+ { "unspec", T_UNSPEC },
+#endif /* ALLOW_T_UNSPEC */
+};
+#define M_TYPE_CNT (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 */
+
+#define MAKENAME_OK(N) if (!makename_ok(N, origin, class, \
+ transport, context, \
+ filename, lineno)) { \
+ errs++; \
+ sprintf(buf, "bad name \"%s\"", N); \
+ goto err; \
+ }
+
+/* int
+ * db_load(filename, in_origin, zp, def_domain)
+ * load a database from `filename' into zone `zp'. append `in_origin'
+ * to all nonterminal domain names in the file. `def_domain' is the
+ * default domain for include files or NULL for zone base files.
+ * returns:
+ * -1 = can't open file
+ * 0 = success
+ * >0 = number of errors encountered
+ */
+int
+db_load(filename, in_origin, zp, def_domain)
+ const char *filename, *in_origin;
+ struct zoneinfo *zp;
+ const char *def_domain;
+{
+ static int read_soa, read_ns, rrcount;
+ register char *cp;
+ register struct map *mp;
+ char domain[MAXDNAME];
+ char origin[MAXDNAME];
+ char tmporigin[MAXDNAME];
+ char buf[MAXDATA];
+ char data[MAXDATA];
+ const char *cp1, *op;
+ int c, class, type, dbflags, dataflags, multiline;
+ u_int32_t ttl;
+ struct databuf *dp;
+ FILE *fp;
+ int slineno, i, errs, didinclude;
+ register u_int32_t n;
+ struct stat sb;
+ struct in_addr ina;
+ int escape;
+ enum transport transport;
+ enum context context;
+#ifdef DO_WARN_SERIAL
+ u_int32_t serial;
+#endif
+
+ switch (zp->z_type) {
+ case Z_PRIMARY:
+ case Z_CACHE:
+ transport = primary_trans;
+ break;
+ case Z_SECONDARY:
+ case Z_STUB:
+ transport = secondary_trans;
+ break;
+ default:
+ transport = response_trans; /*guessing*/
+ break;
+ }
+ errs = 0;
+ didinclude = 0;
+ if (!def_domain) {
+ /* This is not the result of a $INCLUDE. */
+ rrcount = 0;
+ read_soa = 0;
+ read_ns = 0;
+ clev = db_getclev(in_origin);
+ }
+
+ dprintf(1, (ddt,"db_load(%s, %s, %d, %s)\n",
+ filename, in_origin, zp - zones,
+ def_domain ? def_domain : "Nil"));
+
+ (void) strcpy(origin, in_origin);
+ if ((fp = fopen(filename, "r")) == NULL) {
+ syslog(LOG_WARNING, "%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;
+#ifdef STUBS
+ } else if (zp->z_type == Z_STUB && clev == 0) {
+ dbflags = DB_NODATA | DB_NOHINTS;
+ dataflags = DB_F_HINT;
+#endif
+ } else {
+ dbflags = DB_NODATA;
+ dataflags = 0;
+ }
+ gettime(&tt);
+ if (fstat(fileno(fp), &sb) < 0) {
+ syslog(LOG_WARNING, "%s: %m", filename);
+ sb.st_mtime = (int)tt.tv_sec;
+ }
+ slineno = lineno;
+ lineno = 1;
+ if (def_domain)
+ strcpy(domain, def_domain);
+ else
+ domain[0] = '\0';
+ class = zp->z_class;
+ zp->z_flags &= ~(Z_INCLUDE|Z_DB_BAD);
+ while ((c = gettoken(fp, filename)) != EOF) {
+ switch (c) {
+ case INCLUDE:
+ if (!getword((char *)buf, sizeof(buf), fp, 0))
+ /* file name*/
+ break;
+ if (!getword(tmporigin, sizeof(tmporigin), fp, 1))
+ strcpy(tmporigin, origin);
+ else {
+ makename(tmporigin, origin);
+ endline(fp);
+ }
+ didinclude = 1;
+ errs += db_load((char *)buf, tmporigin, zp, domain);
+ continue;
+
+ case ORIGIN:
+ (void) strcpy((char *)buf, origin);
+ if (!getword(origin, sizeof(origin), fp, 1))
+ 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, 1))
+ 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';
+ /* FALLTHROUGH */
+ case CURRENT:
+ gotdomain:
+ if (!getword((char *)buf, sizeof(buf), fp, 0)) {
+ if (c == CURRENT)
+ continue;
+ break;
+ }
+ cp = buf;
+ ttl = USE_MINIMUM;
+ if (isdigit(*cp)) {
+ n = 0;
+ do {
+ if (n > (INT_MAX - (*cp - '0')) / 10) {
+ syslog(LOG_INFO,
+ "%s: line %d: number > %lu\n",
+ filename, lineno, (u_long)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, 0))
+ break;
+ }
+ for (mp = m_class; mp < m_class+M_CLASS_CNT; mp++)
+ if (!strcasecmp((char *)buf, mp->token)) {
+ class = mp->val;
+ (void) getword((char *)buf,
+ sizeof(buf), fp, 0);
+ break;
+ }
+ for (mp = m_type; mp < m_type+M_TYPE_CNT; 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_NOTICE, "%s: Line %d: Unknown type: %s.\n",
+ filename, lineno, buf);
+ break;
+ fndtype:
+ context = ns_ownercontext(type, transport);
+ if (!ns_nameok(domain, class, transport, context)) {
+ errs++;
+ syslog(LOG_NOTICE,
+ "%s:%d: owner name error\n",
+ filename, lineno);
+ break;
+ }
+#ifdef ALLOW_T_UNSPEC
+ /* Don't do anything here for T_UNSPEC...
+ * read input separately later
+ */
+ if (type != T_UNSPEC) {
+#endif
+ context = domain_ctx;
+ switch (type) {
+ case T_SOA:
+ case T_MINFO:
+ case T_RP:
+ case T_NS:
+ case T_CNAME:
+ case T_MB:
+ case T_MG:
+ case T_MR:
+ case T_PTR:
+ escape = 1;
+ break;
+ default:
+ escape = 0;
+ }
+ if (!getword((char *)buf, sizeof(buf), fp, escape))
+ 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_INFO,
+ "%s: line %d: %s too long",
+ filename, lineno, (type == T_ISDN) ?
+ "ISDN-address" : "CPU type");
+ 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, 0))
+ i = 0;
+ else {
+ endline(fp);
+ i = strlen((char *)buf);
+ }
+ if (i == 0) {
+ if (type == T_ISDN) {
+ data[n++] = 0;
+ break;
+ }
+ else
+ /* goto err; */
+ /* XXX tolerate for now */
+ data[n++] = 1;
+ data[n++] = '?';
+ syslog(LOG_INFO,
+ "%s: line %d: OS-type missing",
+ filename,
+ empty_token ? (lineno - 1) : lineno);
+ break;
+ }
+ if (i > 255) {
+ syslog(LOG_INFO,
+ "%s:%d: %s too long",
+ filename, lineno, (type == T_ISDN) ?
+ "ISDN-sa" : "OS type");
+ i = 255;
+ }
+ data[n] = i;
+ bcopy(buf, data + n + 1, i);
+ n += i + 1;
+ break;
+
+ case T_SOA:
+ context = hostname_ctx;
+ goto soa_rp_minfo;
+ case T_RP:
+ case T_MINFO:
+ context = mailname_ctx;
+ /* FALLTHROUGH */
+ soa_rp_minfo:
+ (void) strcpy((char *)data, (char *)buf);
+
+ MAKENAME_OK(data);
+ cp = data + strlen((char *)data) + 1;
+ if (!getword((char *)cp,
+ (sizeof data) - (cp - data),
+ fp, 1))
+ goto err;
+ if (type == T_RP)
+ context = domain_ctx;
+ else
+ context = mailname_ctx;
+ MAKENAME_OK(cp);
+ cp += strlen((char *)cp) + 1;
+ if (type != T_SOA) {
+ n = cp - data;
+ break;
+ }
+ if (class != zp->z_class) {
+ errs++;
+ syslog(LOG_INFO,
+ "%s:%d: %s",
+ filename, lineno,
+ "SOA class not same as zone's");
+ }
+ if (strcasecmp(zp->z_origin, domain) != 0) {
+ errs++;
+ syslog(LOG_ERR,
+ "%s: line %d: SOA for \"%s\" not at zone top \"%s\"",
+ filename, lineno, domain,
+ zp->z_origin);
+ }
+ c = getnonblank(fp, filename);
+ if (c == '(') {
+ multiline = 1;
+ } else {
+ multiline = 0;
+ ungetc(c, fp);
+ }
+#ifdef DO_WARN_SERIAL
+ serial = zp->z_serial;
+#endif
+ zp->z_serial = getnum(fp, filename,
+ GETNUM_SERIAL);
+ if (getnum_error)
+ errs++;
+ n = (u_int32_t) zp->z_serial;
+ PUTLONG(n, cp);
+#ifdef DO_WARN_SERIAL
+ if (serial && SEQ_GT(serial, zp->z_serial)) {
+ syslog(LOG_NOTICE,
+ "%s:%d: WARNING: new serial number < old (%lu < %lu)",
+ filename , lineno,
+ zp->z_serial, serial);
+ }
+#endif
+ zp->z_refresh = getnum(fp, filename,
+ GETNUM_NONE);
+ if (getnum_error) {
+ errs++;
+ zp->z_refresh = INIT_REFRESH;
+ }
+ n = (u_int32_t) zp->z_refresh;
+ PUTLONG(n, cp);
+ if (zp->z_type == Z_SECONDARY
+#if defined(STUBS)
+ || zp->z_type == Z_STUB
+#endif
+ ) {
+ ns_refreshtime(zp, MIN(sb.st_mtime,
+ tt.tv_sec));
+ }
+ zp->z_retry = getnum(fp, filename,
+ GETNUM_NONE);
+ if (getnum_error) {
+ errs++;
+ zp->z_retry = INIT_REFRESH;
+ }
+ n = (u_int32_t) zp->z_retry;
+ PUTLONG(n, cp);
+ zp->z_expire = getnum(fp, filename,
+ GETNUM_NONE);
+ if (getnum_error) {
+ errs++;
+ zp->z_expire = INIT_REFRESH;
+ }
+ n = (u_int32_t) zp->z_expire;
+ PUTLONG (n, cp);
+ zp->z_minimum = getnum(fp, filename,
+ GETNUM_NONE);
+ if (getnum_error) {
+ errs++;
+ zp->z_minimum = 120;
+ }
+ n = (u_int32_t) zp->z_minimum;
+ PUTLONG (n, cp);
+ n = cp - data;
+ if (multiline) {
+ if (getnonblank(fp, filename) != ')')
+ goto err;
+ }
+ read_soa++;
+ if (zp->z_expire < zp->z_refresh ) {
+ syslog(LOG_WARNING,
+ "%s: WARNING SOA expire value is less then SOA refresh (%lu < %lu)",
+ filename, zp->z_expire, zp->z_refresh);
+ }
+ endline(fp);
+ break;
+
+ 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:
+ if (strcasecmp(zp->z_origin, domain) == 0)
+ read_ns++;
+ context = hostname_ctx;
+ goto cname_etc;
+ case T_CNAME:
+ case T_MB:
+ case T_MG:
+ case T_MR:
+ context = domain_ctx;
+ goto cname_etc;
+ case T_PTR:
+ context = ns_ptrcontext(domain);
+ cname_etc:
+ (void) strcpy((char *)data, (char *)buf);
+ MAKENAME_OK(data);
+ 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, 1))
+ goto err;
+ (void) strcpy((char *)cp, (char *)buf);
+ context = hostname_ctx;
+ MAKENAME_OK(cp);
+ /* advance pointer to end of data */
+ cp += strlen((char *)cp) +1;
+
+ /* now save length */
+ n = (cp - data);
+ break;
+
+ case T_PX:
+ context = domain_ctx;
+ n = 0;
+ data[0] = '\0';
+ cp = buf;
+ while (isdigit(*cp))
+ n = n * 10 + (*cp++ - '0');
+ /* catch bad values */
+ if ((cp == buf) || (n > 65535))
+ goto err;
+ cp = data;
+ PUTSHORT((u_int16_t)n, cp);
+
+ if (!getword((char *)buf, sizeof(buf), fp, 0))
+ goto err;
+ (void) strcpy((char *)cp, (char *)buf);
+ MAKENAME_OK(cp);
+ /* advance pointer to next field */
+ cp += strlen((char *)cp) +1;
+ if (!getword((char *)buf, sizeof(buf), fp, 0))
+ goto err;
+ (void) strcpy((char *)cp, (char *)buf);
+ MAKENAME_OK(cp);
+ /* advance pointer to end of data */
+ cp += strlen((char *)cp) + 1;
+
+ /* now save length */
+ n = (cp - data);
+ break;
+
+ case T_TXT:
+ case T_X25:
+ 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_INFO,
+ "%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, (u_char *)data,
+ sizeof data);
+ if (n == 0)
+ goto err;
+ endline(fp);
+ break;
+ case T_AAAA:
+ if (inet_pton(AF_INET6, buf, data) <= 0)
+ goto err;
+ n = IN6ADDRSZ;
+ endline(fp);
+ break;
+#ifdef LOC_RR
+ case T_LOC:
+ cp = buf + (n = strlen(buf));
+ *cp = ' ';
+ cp++;
+ while ((i = getc(fp), *cp = i, i != EOF)
+ && *cp != '\n'
+ && (n < MAXDATA)) {
+ cp++; n++;
+ }
+ if (*cp == '\n') /* leave \n for getword */
+ ungetc(*cp, fp);
+ *cp = '\0';
+ /* now process the whole line */
+ n = loc_aton(buf, (u_char *)data);
+ if (n == 0)
+ goto err;
+ endline(fp);
+ break;
+#endif /* LOC_RR */
+#ifdef ALLOW_T_UNSPEC
+ case T_UNSPEC:
+ {
+ 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) {
+ errs++;
+ syslog(LOG_INFO,
+ "Load T_UNSPEC: input buffer overflow");
+ } else {
+ errs++;
+ syslog(LOG_INFO,
+ "Load T_UNSPEC: Data in bad atob format");
+ }
+ }
+ }
+ break;
+#endif /* ALLOW_T_UNSPEC */
+
+ default:
+ goto err;
+ }
+#ifndef PURGE_ZONE
+#ifdef STUBS
+ if (type == T_SOA && zp->z_type == Z_STUB)
+ continue;
+#endif
+#endif
+#ifdef NO_GLUE
+ /*
+ * Ignore data outside the zone.
+ */
+ if (zp->z_type != Z_CACHE &&
+ !samedomain(domain, zp->z_origin))
+ {
+ syslog(LOG_INFO,
+ "%s:%d: data \"%s\" outside zone \"%s\" (ignored)",
+ filename, lineno, domain, zp->z_origin);
+ continue;
+ }
+#endif /*NO_GLUE*/
+ dp = savedata(class, type, (u_int32_t)ttl,
+ (u_char *)data, (int)n);
+ dp->d_zone = zp - zones;
+ dp->d_flags = dataflags;
+ dp->d_cred = DB_C_ZONE;
+ dp->d_clev = clev;
+ if ((c = db_update(domain, dp, dp, dbflags,
+ (dataflags & DB_F_HINT)
+ ? fcachetab
+ : hashtab))
+ != OK) {
+#ifdef DEBUG
+ if (debug && (c != DATAEXISTS))
+ fprintf(ddt, "update failed %s %d\n",
+ domain, type);
+#endif
+ free((char*) dp);
+ } else {
+ rrcount++;
+ }
+ continue;
+
+ case ERROR:
+ break;
+ }
+ err:
+ errs++;
+ syslog(LOG_NOTICE, "%s: line %d: database format error (%s)",
+ filename, empty_token ? (lineno - 1) : lineno, buf);
+ if (!empty_token)
+ endline(fp);
+ }
+ (void) my_fclose(fp);
+ lineno = slineno;
+ if (!def_domain) {
+ if (didinclude) {
+ zp->z_flags |= Z_INCLUDE;
+ zp->z_ftime = 0;
+ } else
+ zp->z_ftime = sb.st_mtime;
+ zp->z_lastupdate = sb.st_mtime;
+ if (zp->z_type != Z_CACHE) {
+ const char *msg = NULL;
+
+ if (read_soa == 0)
+ msg = "no SOA RR found";
+ else if (read_soa != 1)
+ msg = "multiple SOA RRs found";
+ else if (read_ns == 0)
+ msg = "no NS RRs found at zone top";
+ else if (!rrcount)
+ msg = "no relevant RRs found";
+ if (msg != NULL) {
+ errs++;
+ syslog(LOG_WARNING,
+ "Zone \"%s\" (file %s): %s",
+ zp->z_origin, filename, msg);
+ }
+ }
+ }
+#ifdef SECURE_ZONES
+ build_secure_netlist(zp);
+#endif
+ if (!def_domain)
+ syslog(errs ? LOG_WARNING : LOG_INFO,
+ "%s zone \"%s\" %s (serial %lu)",
+ zoneTypeString(zp), zp->z_origin,
+ errs ? "rejected due to errors" : "loaded",
+ (u_long)zp->z_serial);
+ if (errs)
+ zp->z_flags |= Z_DB_BAD;
+#ifdef BIND_NOTIFY
+ /* XXX: this needs to be delayed, both according to the spec, and
+ * because the metadata needed by sysnotify() (and its sysquery())
+ * could be in other zones that we (at startup) havn't loaded yet.
+ */
+ if (!errs && !def_domain &&
+ (zp->z_type == Z_PRIMARY || zp->z_type == Z_SECONDARY))
+ sysnotify(zp->z_origin, zp->z_class, T_SOA);
+#endif
+ return (errs);
+}
+
+static int
+gettoken(fp, src)
+ register FILE *fp;
+ const 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, 0)) {
+ if (!strcasecmp("include", op))
+ return (INCLUDE);
+ if (!strcasecmp("origin", op))
+ return (ORIGIN);
+ }
+ syslog(LOG_NOTICE,
+ "%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, preserve)
+ * get next word, skipping blanks & comments.
+ * '\' '\n' outside of "quotes" is considered a blank.
+ * parameters:
+ * buf - destination
+ * size - of destination
+ * fp - file to read from
+ * preserve - should we preserve \ before \\ and \.?
+ * return value:
+ * 0 = no word; perhaps EOL or EOF
+ * 1 = word was read
+ */
+int
+getword(buf, size, fp, preserve)
+ char *buf;
+ int size;
+ FILE *fp;
+ int preserve;
+{
+ register char *cp = buf;
+ register int c, spaceok;
+
+ empty_token = 0; /* XXX global side effect. */
+ while ((c = getc(fp)) != EOF) {
+ if (c == ';') {
+ /* Comment. Skip to end of line. */
+ while ((c = getc(fp)) != EOF && c != '\n')
+ NULL;
+ c = '\n';
+ }
+ if (c == '\n') {
+ /*
+ * Unescaped newline. It's a terminator unless we're
+ * already midway into a token.
+ */
+ if (cp != buf)
+ ungetc(c, fp);
+ else
+ lineno++;
+ break;
+ }
+ if (c == '"') {
+ /* "Quoted string." Gather the whole string here. */
+ while ((c = getc(fp)) != EOF && c!='"' && c!='\n') {
+ if (c == '\\') {
+ if ((c = getc(fp)) == EOF)
+ c = '\\';
+ if (preserve &&
+ (c == '\\' || c == '.')) {
+ if (cp >= buf+size-1)
+ break;
+ *cp++ = '\\';
+ }
+ if (c == '\n')
+ lineno++;
+ }
+ if (cp >= buf+size-1)
+ break;
+ *cp++ = c;
+ }
+ /*
+ * Newline string terminators are
+ * not token terminators.
+ */
+ if (c == '\n') {
+ lineno++;
+ break;
+ }
+ /* Sample following character, check for terminator. */
+ if ((c = getc(fp)) != EOF)
+ ungetc(c, fp);
+ if (c == EOF || isspace(c)) {
+ *cp = '\0';
+ return (1);
+ }
+ continue;
+ }
+ spaceok = 0;
+ if (c == '\\') {
+ /* Do escape processing. */
+ if ((c = getc(fp)) == EOF)
+ c = '\\';
+ if (preserve && (c == '\\' || c == '.')) {
+ if (cp >= buf+size-1)
+ break;
+ *cp++ = '\\';
+ }
+ if (c == ' ' || c == '\t')
+ spaceok++;
+ }
+ if (isspace(c) && !spaceok) {
+ /* Blank of some kind. Skip run. */
+ while (isspace(c = getc(fp)) && c != '\n')
+ NULL;
+ ungetc(c, fp);
+ /* Blank means terminator if the token is nonempty. */
+ if (cp != buf) /* Trailing whitespace */
+ break;
+ continue; /* Leading whitespace */
+ }
+ 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, opt)
+ FILE *fp;
+ const char *src;
+ int opt;
+{
+ register int c, n;
+ int seendigit = 0;
+ int seendecimal = 0;
+ int m = 0;
+ int allow_dots = 0;
+
+ getnum_error = 0;
+#ifdef DOTTED_SERIAL
+ if (opt & GETNUM_SERIAL)
+ allow_dots++;
+#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 (getnum_error)
+ continue;
+ if (!isdigit(c)) {
+ if (c == ')' && seendigit) {
+ (void) ungetc(c, fp);
+ break;
+ }
+ if (seendigit && (opt & GETNUM_SCALED) &&
+ strchr("KkMmGg", c) != NULL) {
+ switch (c) {
+ case 'K': case 'k':
+ n *= 1024;
+ break;
+ case 'M': case 'm':
+ n *= (1024 * 1024);
+ break;
+ case 'G': case 'g':
+ n *= (1024 * 1024 * 1024);
+ break;
+ }
+ break;
+ }
+ if (seendecimal || c != '.' || !allow_dots) {
+ syslog(LOG_NOTICE, "%s:%d: expected a number",
+ src, lineno);
+ getnum_error = 1;
+ } else {
+ if (!seendigit)
+ n = 1;
+#ifdef SENSIBLE_DOTS
+ n *= 10000;
+#else
+ 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 (getnum_error)
+ return (0);
+ if (m > 9999) {
+ syslog(LOG_INFO,
+ "%s:%d: number after the decimal point exceeds 9999",
+ src, lineno);
+ getnum_error = 1;
+ return (0);
+ }
+ 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;
+ const 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_INFO, "%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;
+ const char *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);
+ }
+ }
+}
+
+static int
+makename_ok(name, origin, class, transport, context, filename, lineno)
+ char *name;
+ const char *origin;
+ int class;
+ enum transport transport;
+ enum context context;
+ const char *filename;
+ int lineno;
+{
+ int ret = 1;
+
+ makename(name, origin);
+ if (!ns_nameok(name, class, transport, context)) {
+ syslog(LOG_INFO, "%s:%d: database naming error\n",
+ filename, lineno);
+ ret = 0;
+ }
+ return (ret);
+}
+
+void
+endline(fp)
+ register FILE *fp;
+{
+ register int c;
+
+ while ((c = getc(fp)) != '\0') {
+ if (c == '\n') {
+ (void) ungetc(c,fp);
+ break;
+ } else if (c == EOF) {
+ break;
+ }
+ }
+}
+
+#define MAXPORT 1024
+#define MAXLEN 24
+
+static int
+getprotocol(fp, src)
+ FILE *fp;
+ const char *src;
+{
+ int k;
+ char b[MAXLEN];
+
+ (void) getword(b, sizeof(b), fp, 0);
+
+ k = protocolnumber(b);
+ if (k == -1)
+ syslog(LOG_INFO, "%s: line %d: unknown protocol: %s.",
+ src, lineno, b);
+ return(k);
+}
+
+static int
+getservices(n, data, fp, src)
+ int n;
+ char *data;
+ FILE *fp;
+ const char *src;
+{
+ 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, 0) || 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_INFO,
+ "%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_INFO,
+ "%s: line %d: port no. (%d) too big\n",
+ src, lineno, k);
+ dprintf(1, (ddt,
+ "%s: line %d: port no. (%d) too big\n",
+ src, lineno, k));
+ }
+ }
+ if (bracket)
+ syslog(LOG_INFO, "%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, **end;
+ char buf[BUFSIZ], *maskp;
+ struct in_addr ina;
+
+ for (end = netlistp; *end; end = &(**end).next)
+ ;
+ ntp = NULL;
+ dprintf(1, (ddt, "get_netlist(%s)", print_tag));
+ while (getword(buf, sizeof(buf), fp, 0)) {
+ if (strlen(buf) == 0)
+ break;
+ if ((maskp = strchr(buf, '&')) != NULL)
+ *maskp++ = '\0';
+ dprintf(1, (ddt," %s", buf));
+ if (!ntp) {
+ ntp = (struct netinfo *)malloc(sizeof(struct netinfo));
+ if (!ntp)
+ panic(errno, "malloc(netinfo)");
+ }
+ if (!inet_aton(buf, &ntp->my_addr)) {
+ syslog(LOG_INFO, "%s contains bogus element (%s)",
+ print_tag, buf);
+ continue;
+ }
+ if (maskp) {
+ if (!inet_aton(maskp, &ina)) {
+ syslog(LOG_INFO,
+ "%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_INFO,
+ "%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%lx addr x%lx mask x%lx",
+ (u_long)ntp, (u_long)ntp->addr,
+ (u_long)ntp->mask);
+ fprintf(ddt, " my_addr x%lx",
+ (u_long)ntp->my_addr.s_addr);
+ fprintf(ddt, " %s", inet_ntoa(ntp->my_addr));
+ fprintf(ddt, " next x%lx\n", (u_long)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/contrib/bind/named/db_lookup.c b/contrib/bind/named/db_lookup.c
new file mode 100644
index 0000000..4582589
--- /dev/null
+++ b/contrib/bind/named/db_lookup.c
@@ -0,0 +1,249 @@
+#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 8.7 1996/08/05 08:31:30 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 <sys/types.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <syslog.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)
+ const char *name;
+ struct hashbuf **htpp;
+ const char **fname;
+ int insert;
+{
+ register struct namebuf *np;
+ register const char *cp;
+ register int c;
+ register unsigned hval;
+ register struct hashbuf *htp;
+ struct namebuf *parent = NULL;
+ int escaped = 0;
+
+ htp = *htpp;
+ hval = 0;
+ *fname = "???";
+ for (cp = name; c = *cp++; ) {
+ if (!escaped && (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 (ns_wildcard(NAME(*np)))
+ *fname = name;
+ return (np);
+ }
+ htp = savehash((struct hashbuf *)NULL);
+ np->n_hash = htp;
+ }
+ *htpp = htp;
+ break;
+ }
+
+ /* rotate left HASHSHIFT */
+ hval = (hval << HASHSHIFT) |
+ (hval>>((sizeof(hval)*8)-HASHSHIFT));
+ hval += (isupper(c) ? tolower(c) : c) & HASHMASK;
+ if (escaped)
+ escaped = 0;
+ else if (c == '\\')
+ escaped = 1;
+ }
+ cp--;
+ /*
+ * 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 &&
+ (NAMELEN(*np) == (cp - name)) &&
+ (strncasecmp(name, NAME(*np), cp - name) == 0)) {
+ *fname = name;
+ 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 (ns_wildcard(NAME(*np)) &&
+ np->n_data && np->n_data->d_zone != 0) {
+ *fname = name;
+ return (np);
+ }
+ }
+ return (parent);
+ }
+ np = savename(name, cp - 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;
+ return (np);
+}
+
+/* struct namebuf *
+ * np_parent(struct namebuf *np)
+ * Find the "parent" namebuf of np.
+ * This is tricky since the parent of "com" is "" and both are stored
+ * in the same hashbuf.
+ * See also:
+ * the AXFR wart description in ns_req.c
+ */
+struct namebuf *
+np_parent(np)
+ struct namebuf *np;
+{
+ struct hashbuf *htp;
+ struct namebuf *np2;
+
+ if (np->n_parent != NULL || NAME(*np)[0] == '\0')
+ return (np->n_parent);
+
+ /* Try to figure out if np is pointing into the cache or hints. */
+ /* Try the cache first. */
+ htp = hashtab;
+ try_again:
+ /* Search the hash chain that np should be part of. */
+ for (np2 = htp->h_tab[np->n_hashval % htp->h_size];
+ np2 != NULL;
+ np2 = np2->n_next) {
+
+ if (np == np2) { /* found it! */
+ /* "" hashes into the first bucket */
+ for (np = htp->h_tab[0]; np ; np=np->n_next) {
+ if (NAME(*np)[0] == '\0')
+ /* found the root namebuf */
+ return (np);
+ }
+ dprintf(1, (ddt,
+ "np_parent(0x%lx) couldn't find root entry\n",
+ (u_long) np));
+ return (NULL); /* XXX shouldn't happen */
+ }
+ }
+ /* Try the hints. */
+ if (htp == hashtab) {
+ htp = fcachetab;
+ goto try_again;
+ }
+ dprintf(1, (ddt, "np_parent(0x%lx) couldn't namebuf\n", (u_long) np));
+ return (NULL); /* XXX shouldn't happen */
+}
+
+/* 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%lx, %d, %d) %d, %d\n",
+ (u_long)dp, class, type, dp->d_class, dp->d_type));
+ if (dp->d_class != class && class != C_ANY)
+ return (0);
+ if (dp->d_type != type && type != T_ANY)
+ return (0);
+ return (1);
+}
diff --git a/contrib/bind/named/db_reload.c b/contrib/bind/named/db_reload.c
new file mode 100644
index 0000000..46fa7fe
--- /dev/null
+++ b/contrib/bind/named/db_reload.c
@@ -0,0 +1,126 @@
+#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 8.2 1996/08/05 08:31:30 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/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/contrib/bind/named/db_save.c b/contrib/bind/named/db_save.c
new file mode 100644
index 0000000..88b31d1
--- /dev/null
+++ b/contrib/bind/named/db_save.c
@@ -0,0 +1,208 @@
+#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 8.4 1996/08/05 08:31:30 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/types.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <syslog.h>
+#include <stdio.h>
+#include <errno.h>
+#include <assert.h>
+
+#include "named.h"
+
+/*
+ * Allocate a name buffer & save name.
+ */
+struct namebuf *
+savename(name, len)
+ const char *name;
+ int len;
+{
+ register struct namebuf *np;
+
+ assert(len >= 0 && len <= (MAXLABEL * 2));
+ np = (struct namebuf *) malloc(NAMESIZE(len));
+ if (np == NULL)
+ panic(errno, "savename: malloc");
+ bzero((char*)np, NAMESIZE(len));
+ NAMELEN(*np) = len;
+ bcopy(name, NAME(*np), len);
+ NAME(*np)[len] = '\0';
+ 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;
+ int bytes = (type == T_NS) ? DATASIZE(size)+INT32SZ : DATASIZE(size);
+
+ dp = (struct databuf *)
+#ifdef DMALLOC
+ dmalloc(file, line, bytes)
+#else
+ malloc(bytes)
+#endif
+ ;
+ if (dp == NULL)
+ panic(errno, "savedata: malloc");
+ bzero((char*)dp, bytes);
+ 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(%#lx) cnt=%d, sz=%d, newsz=%d\n",
+ (u_long)oldhtp, oldhtp->h_cnt, oldhtp->h_size, newsize));
+ htp->h_cnt = oldhtp->h_cnt;
+ for (n = 0; n < oldhtp->h_size; n++) {
+ for (np = oldhtp->h_tab[n]; np != NULL; np = nnp) {
+ 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/contrib/bind/named/db_secure.c b/contrib/bind/named/db_secure.c
new file mode 100644
index 0000000..0ec8353
--- /dev/null
+++ b/contrib/bind/named/db_secure.c
@@ -0,0 +1,153 @@
+#ifndef LINT
+static char rcsid[] = "$Id: db_secure.c,v 8.6 1996/05/17 09:10:46 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 <errno.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;
+ const char *fname;
+ char *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(NAME(*snp), 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, zp->z_class, 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)
+ panic(errno, "malloc(netinfo)");
+ }
+ if (!inet_aton(buf, &ntp->my_addr)) {
+ syslog(LOG_INFO,
+ "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_INFO,
+ "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)) {
+ syslog(LOG_INFO,
+ "build_secure_netlist (%s): addr (%s) is not in mask (%#lx)",
+ zp->z_origin,
+ inet_ntoa(ntp->my_addr),
+ (u_long)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)) {
+ syslog(LOG_INFO,
+ "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%lx addr x%lx mask x%lx",
+ (u_long)ntp, (u_long)ntp->addr,
+ (u_long)ntp->mask);
+ fprintf(ddt, " my_addr %#lx",
+ (u_long)ntp->my_addr.s_addr);
+ fprintf(ddt, " %s", inet_ntoa(ntp->my_addr));
+ fprintf(ddt, " next x%lx\n", (u_long)ntp->next);
+ }
+ }
+#endif
+ return (errs);
+}
+#endif /*SECURE_ZONES*/
diff --git a/contrib/bind/named/db_update.c b/contrib/bind/named/db_update.c
new file mode 100644
index 0000000..c706c66
--- /dev/null
+++ b/contrib/bind/named/db_update.c
@@ -0,0 +1,737 @@
+#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 8.12 1996/08/05 08:31:30 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/types.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+#include <resolv.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_class == C_HS) &&
+ 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, int class)
+ * 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_parent(np)) {
+ 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);
+}
+
+
+#ifdef NO_GLUE
+#define ISVALIDGLUE(xdp) ((xdp)->d_type == T_NS || (xdp)->d_type == T_A \
+ || (xdp)->d_type == T_AAAA)
+#else
+#define ISVALIDGLUE(xdp) (1)
+#endif /*NO_GLUE*/
+
+
+/* int
+ * db_update(name, odp, newdp, flags, htp)
+ * update data base node at `name'. `flags' controls the action.
+ * 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;
+ const char *fname;
+
+ dprintf(3, (ddt, "db_update(%s, 0x%lx, 0x%lx, 0%o, 0x%lx)%s\n",
+ name, (u_long)odp, (u_long)newdp, flags, (u_long)htp,
+ (odp && (odp->d_flags&DB_F_HINT)) ? " hint":"" ));
+ np = nlookup(name, &htp, &fname, newdp != NULL);
+ if (np == NULL || fname != name)
+ return (NONAME);
+
+ /* don't let nonauthoritative updates write in authority zones */
+ if (newdp && ((zn = findMyZone(np, newdp->d_class)) != DB_Z_CACHE) &&
+#ifdef STUBS
+ (zones[zn].z_type != Z_STUB) &&
+#endif
+ (flags & DB_NOTAUTH)) {
+ int foundRR = 0;
+
+ /*
+ * Don't generate the warning if 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)
+ dprintf(5, (ddt,
+ "[%s].%d update? to auth zone \"%s\" (%s)",
+ inet_ntoa(from_addr.sin_addr),
+ ntohs(from_addr.sin_port),
+ zones[zn].z_origin,
+ name));
+ return (AUTH);
+ }
+
+ if (newdp && zn && !(flags & DB_NOTAUTH)) {
+ if (db_getclev(zones[zn].z_origin) > newdp->d_clev) {
+ dprintf(5,(ddt, "attempted update child zone %s, %s\n",
+ zones[zn].z_origin, name));
+ return(AUTH);
+ }
+ }
+
+ /* some special checks for root NS' A RR's */
+ isHintNS = isRefByNS(name, fcachetab);
+#ifdef DEPRECATED
+ if (newdp && isHintNS && newdp->d_type == T_A) {
+ /* 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;
+ }
+ }
+#endif
+
+ /* Reflect certain updates in hint cache also... */
+ /* Don't stick data we are authoritative for in hints. */
+ if (!(flags & DB_NOHINTS) &&
+ (flags & DB_PRIMING) &&
+ (odp != NULL) &&
+ (htp != fcachetab) &&
+ (odp->d_zone <= 0) &&
+ !(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 %lx freed\n",
+ (u_long)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_INFO,
+ "%s has CNAME and other data (illegal)\n",
+ name);
+ goto skip;
+ }
+ if (!newdp || newdp->d_class != dp->d_class)
+ goto skip;
+
+ /* 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 0 /* caught by findMyZone() now. */
+ /* 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);
+#endif
+
+ /* if the new data is authoritative but
+ * but isn't as credible, reject it.
+ */
+ if (newdp->d_cred == DB_C_ZONE &&
+ dp->d_cred == DB_C_ZONE) {
+ /* Both records are from a zone file.
+ * If their credibility levels differ,
+ * we're dealing with a zone cut. The
+ * record with lower clev is from the
+ * upper zone's file and is therefore
+ * glue.
+ */
+ if (newdp->d_clev < dp->d_clev) {
+ if (!ISVALIDGLUE(newdp)) {
+ syslog(LOG_INFO,
+ "domain %s %s record in zone %s should be in zone %s, ignored",
+ name, p_type(newdp->d_type),
+ zones[newdp->d_zone].z_origin,
+ zones[dp->d_zone].z_origin);
+ }
+ return (AUTH);
+ }
+ if (newdp->d_clev > dp->d_clev) {
+ if (!ISVALIDGLUE(dp)) {
+ syslog(LOG_INFO,
+ "domain %s %s record in zone %s should be in zone %s, deleted",
+ name, p_type(dp->d_type),
+ zones[dp->d_zone].z_origin,
+ zones[newdp->d_zone].z_origin);
+ }
+ goto delete;
+ }
+ }
+#ifdef NCACHE
+ /* process NXDOMAIN */
+ /* policy */
+ 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) {
+ /* better credibility.
+ * 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 &&
+ dp->d_cred == DB_C_ZONE ) {
+ /* Both records are from a zone file.
+ * If their credibility levels differ,
+ * we're dealing with a zone cut. The
+ * record with lower clev is from the
+ * upper zone's file and is therefore
+ * glue.
+ */
+
+ /* XXX - Tricky situation here is you
+ * have 2 zones a.b.c and sub.a.b.c
+ * being served by the same server.
+ * named will send NS records for
+ * sub.a.b.c during zone transfer of
+ * a.b.c zone. If we're secondary for
+ * both zones, and we reload zone
+ * a.b.c, we'll get the NS records
+ * (and possibly A records to go with
+ * them?) for sub.a.b.c as part of the
+ * a.b.c zone transfer. But we've
+ * already got a more credible record
+ * from the sub.a.b.c zone. So we want
+ * to ignore the new record, but we
+ * shouldn't syslog because there's
+ * nothing the user can do to prevent
+ * the situation. Perhaps we should
+ * only complain when we are primary?
+ */
+
+ if (newdp->d_clev < dp->d_clev) {
+ if (!ISVALIDGLUE(newdp)) {
+ syslog(LOG_INFO,
+ "domain %s %s record in zone %s should be in zone %s, ignored",
+ name, p_type(newdp->d_type),
+ zones[newdp->d_zone].z_origin,
+ zones[dp->d_zone].z_origin);
+ }
+ return (AUTH);
+ }
+ if (newdp->d_clev > dp->d_clev) {
+ if (!ISVALIDGLUE(dp)) {
+ syslog(LOG_INFO,
+ "domain %s %s record in zone %s should be in zone %s, deleted",
+ name, p_type(dp->d_type),
+ zones[dp->d_zone].z_origin,
+ zones[newdp->d_zone].z_origin);
+ }
+ goto delete;
+ }
+ }
+
+ /* credibility is the same.
+ * let it aggregate in the normal way.
+ */
+#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,
+ INT32SZ + sizeof(u_char)))
+ 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 %ld +%ld\n",
+ (u_long)dp->d_ttl,
+ (u_long)
+ (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 %lx\n",
+ (newdp->d_flags&DB_F_HINT) ? " hint":"", (u_long)newdp));
+#ifdef INVQ
+ if (!(newdp->d_flags & DB_F_HINT))
+ addinv(np, newdp); /* modify inverse query tables */
+#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, len2;
+
+ 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:
+ case T_AAAA:
+ case T_LOC:
+#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;
+ len2 = *cp2;
+ if (len != len2)
+ return (1);
+ if (strncasecmp((char *)++cp1, (char *)++cp2, len))
+ return (1);
+ cp1 += len;
+ cp2 += len;
+ len = *cp1;
+ len2 = *cp2;
+ if (len != len2)
+ return (1);
+ return (strncasecmp((char *)++cp1, (char *)++cp2, len));
+
+ case T_SOA:
+ 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_PX:
+ cp1 = dp1->d_data;
+ cp2 = dp2->d_data;
+ if (*cp1++ != *cp2++ || *cp1++ != *cp2++) /* cmp prio */
+ return (1);
+ if (strcasecmp((char *)cp1, (char *)cp2))
+ return (1);
+ cp1 += strlen((char *)cp1) + 1;
+ cp2 += strlen((char *)cp2) + 1;
+ return (strcasecmp((char *)cp1, (char *)cp2));
+
+ case T_TXT:
+ case T_X25:
+ if (dp1->d_size != dp2->d_size)
+ return (1);
+ return (bcmp(dp1->d_data, dp2->d_data, dp1->d_size));
+
+ default:
+ return (1);
+ }
+}
diff --git a/contrib/bind/named/dmalloc.c b/contrib/bind/named/dmalloc.c
new file mode 100644
index 0000000..03593e2
--- /dev/null
+++ b/contrib/bind/named/dmalloc.c
@@ -0,0 +1,315 @@
+/* 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 8.3 1996/05/17 09:10:46 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);
+ if (!d)
+ return (NULL);
+ 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);
+ if (ptr)
+ 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/contrib/bind/named/dmalloc.h b/contrib/bind/named/dmalloc.h
new file mode 100644
index 0000000..9d0b44a
--- /dev/null
+++ b/contrib/bind/named/dmalloc.h
@@ -0,0 +1,68 @@
+/* dmalloc - debugging layer on top of malloc
+ * vix 22mar92 [written]
+ *
+ * $Id: dmalloc.h,v 8.1 1994/12/15 06:24:14 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/contrib/bind/named/named-xfer.c b/contrib/bind/named/named-xfer.c
new file mode 100644
index 0000000..b71ebfb
--- /dev/null
+++ b/contrib/bind/named/named-xfer.c
@@ -0,0 +1,1644 @@
+/*
+ * 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 8.15 1996/08/05 08:31:30 vixie Exp $";
+#endif /* not lint */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/file.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+#if defined(__osf__)
+# include <sys/mbuf.h>
+# include <net/route.h>
+#endif
+#if defined(_AIX)
+# include <sys/time.h>
+# define TIME_H_INCLUDED
+#endif
+#include <net/if.h>
+#include <netdb.h>
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+
+#include <errno.h>
+#include <resolv.h>
+#include <stdio.h>
+#include <syslog.h>
+#if !defined(SVR4) || !defined(sun)
+# include <math.h>
+#endif
+#include <ctype.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,
+ curclass,
+ domain_len; /* strlen(domain) */
+
+static FILE *fp = NULL,
+ *dbfp = NULL;
+
+static char *ProgName;
+
+static void usage __P((const char *));
+static int getzone __P((struct zoneinfo *, u_int32_t, int)),
+ print_output __P((u_char *, int, u_char *)),
+ netread __P((int, char *, int, int));
+static SIG_FN read_alarm __P(());
+static const char *soa_zinfo __P((struct zoneinfo *, u_char *, u_char*));
+
+extern char *optarg;
+extern int optind, getopt();
+
+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);
+ if (!ddtfile)
+ panic(errno, "malloc(ddtfile)");
+#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);
+ if (!tmpname)
+ panic(errno, "malloc(tmpname)");
+#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 {
+#ifdef HAVE_SETVBUF
+ 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, (u_long)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++) {
+ 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);
+ 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 0.0.0.0 (%s) for %s",
+ tm, zp->z_origin);
+ 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_init();
+ _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, nscnt, soacnt, error = 0;
+ u_int cnt;
+ u_char *cp, *nmp, *eom, *tmp ;
+ u_char *buf = NULL;
+ u_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 qdcount, ancount, aucount, class, type;
+ const char *badsoa_msg = "Nil";
+
+#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
+ bzero((char *)&sv, sizeof sv);
+ sv.sa_handler = (SIG_FN (*)()) read_alarm;
+ /* SA_ONSTACK isn't recommended for strict POSIX code */
+ /* is it absolutely necessary? */
+ /* sv.sa_flags = SA_ONSTACK; */
+ sigfillset(&sv.sa_mask);
+ (void) sigaction(SIGALRM, &sv, &osv);
+#else
+ bzero((char *)&sv, sizeof sv);
+ sv.sv_handler = read_alarm;
+ sv.sv_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
+ curclass = zp->z_class;
+#else
+ curclass = C_IN;
+#endif
+ error = 0;
+ if (buf == NULL) {
+ if ((buf = (u_char *)malloc(2 * PACKETSZ)) == NULL) {
+ syslog(LOG_INFO, "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_INFO, "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) {
+ if (!quiet)
+ syslog(LOG_INFO,
+ "connect(%s) for zone %s failed: %m",
+ inet_ntoa(sin.sin_addr), zp->z_origin);
+ error++;
+ (void) my_close(s);
+ continue;
+ }
+#ifndef GEN_AXFR
+ tryagain:
+#endif
+ n = res_mkquery(QUERY, zp->z_origin, curclass,
+ T_SOA, NULL, 0, NULL, buf, bufsize);
+ if (n < 0) {
+ if (!quiet)
+ syslog(LOG_INFO,
+ "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_INFO, "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_INFO,
+ "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_nquery(buf, len, ddt);
+ }
+#endif
+ hp = (HEADER *) buf;
+ qdcount = ntohs(hp->qdcount);
+ ancount = ntohs(hp->ancount);
+ aucount = ntohs(hp->nscount);
+
+ /*
+ * close socket if any of these apply:
+ * 1) rcode != NOERROR
+ * 2) not an authority response
+ * 3) not an answer to our question
+ * 4) both the number of answers and authority count < 1)
+ */
+ if (hp->rcode != NOERROR || !hp->aa || qdcount != 1 ||
+ (ancount < 1 && aucount < 1)) {
+#ifndef GEN_AXFR
+ if (curclass == C_IN) {
+ dprintf(1, (ddt, "SOA failed, trying C_HS\n"));
+ curclass = C_HS;
+ goto tryagain;
+ }
+#endif
+ syslog(LOG_NOTICE,
+ "[%s] %s for %s, SOA query got rcode %d, aa %d, ancount %d, aucount %d",
+ inet_ntoa(sin.sin_addr),
+ (hp->aa
+ ? (qdcount==1 ?"no SOA found" :"bad response")
+ : "not authoritative"),
+ zp->z_origin[0] != '\0' ? zp->z_origin : ".",
+ hp->rcode, hp->aa, ancount, aucount);
+ error++;
+ (void) my_close(s);
+ continue;
+ }
+ zp_start = *zp;
+ if ((int)len < HFIXEDSZ + QFIXEDSZ) {
+ badsoa_msg = "too short";
+ badsoa:
+ syslog(LOG_INFO,
+ "malformed SOA from [%s], zone %s: %s",
+ inet_ntoa(sin.sin_addr), zp->z_origin,
+ badsoa_msg);
+ error++;
+ (void) my_close(s);
+ continue;
+ }
+ /*
+ * Step through response.
+ */
+ tmp = buf + HFIXEDSZ;
+ eom = buf + len;
+ /* Query Section. */
+ n = dn_expand(buf, eom, tmp, name2, sizeof name2);
+ if (n < 0) {
+ badsoa_msg = "qname error";
+ goto badsoa;
+ }
+ tmp += n;
+ GETSHORT(type, tmp);
+ GETSHORT(class, tmp);
+ if (class != curclass || type != T_SOA ||
+ strcasecmp(zp->z_origin, name2) != 0) {
+ syslog(LOG_INFO,
+ "wrong query in resp from [%s], zone %s: [%s %s %s]\n",
+ inet_ntoa(sin.sin_addr), zp->z_origin,
+ name2, p_class(class), p_type(type));
+ error++;
+ (void) my_close(s);
+ continue;
+ }
+ /* ... Answer Section. */
+ n = dn_expand(buf, eom, tmp, name2, sizeof name2);
+ if (n < 0) {
+ badsoa_msg = "aname error";
+ goto badsoa;
+ }
+ tmp += n;
+ if (strcasecmp(zp->z_origin, name2) != 0) {
+ syslog(LOG_INFO,
+ "wrong answer in resp from [%s], zone %s: [%s %s %s]\n",
+ inet_ntoa(sin.sin_addr), zp->z_origin,
+ name2, p_class(class), p_type(type));
+ error++;
+ (void) my_close(s);
+ continue;
+ }
+ badsoa_msg = soa_zinfo(&zp_start, tmp, eom);
+ if (badsoa_msg)
+ goto badsoa;
+ if (SEQ_GT(zp_start.z_serial, serial_no) || !serial_no) {
+ const char *l, *nl;
+ dprintf(1, (ddt, "need update, serial %lu\n",
+ (u_long)zp_start.z_serial));
+ hp = (HEADER *) buf;
+ soacnt = 0;
+ nscnt = 0;
+ gettime(&tt);
+ for (l = Version; l; l = nl) {
+ size_t len;
+ if ((nl = strchr(l, '\n')) != NULL) {
+ len = nl - l;
+ nl = nl + 1;
+ } else {
+ len = strlen(l);
+ nl = NULL;
+ }
+ while (isspace((unsigned char) *l))
+ l++;
+ if (*l)
+ fprintf(dbfp, "; BIND version %.*s\n",
+ (int)len, l);
+ }
+ fprintf(dbfp, "; zone '%s' last serial %lu\n",
+ domain, (u_long)serial_no);
+ fprintf(dbfp, "; from %s at %s",
+ inet_ntoa(sin.sin_addr),
+ ctimel(tt.tv_sec));
+ for (;;) {
+ if ((soacnt == 0) || (zp->z_type == Z_STUB)) {
+ int type;
+#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,
+ curclass, type,
+ NULL, 0,
+ NULL, buf, bufsize);
+ if (n < 0) {
+ if (!quiet) {
+#ifdef STUBS
+ if (zp->z_type == Z_STUB)
+ syslog(LOG_INFO,
+ (type == T_SOA)
+ ? "zone %s: res_mkquery T_SOA failed"
+ : "zone %s: res_mkquery T_NS failed",
+ zp->z_origin);
+ else
+#endif
+ syslog(LOG_INFO,
+ "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_INFO,
+ "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_nquery(buf, len, ddt);
+ }
+ if (fp)
+ fp_nquery(buf, len, fp);
+#endif
+ if (len < HFIXEDSZ) {
+ badrec:
+ error++;
+ syslog(LOG_INFO,
+ "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_INFO,
+ "print_output: short answer (%d, %d), zone %s",
+ cp - buf, n, zp->z_origin);
+ error++;
+ break;
+ }
+
+ } else {
+#endif /*STUBS*/
+ ancount = ntohs(hp->ancount);
+ for (cnt = 0; cnt < ancount; cnt++) {
+ n = print_output(buf, bufsize, cp);
+ cp += n;
+ }
+ if (cp != eom) {
+ syslog(LOG_INFO,
+ "print_output: short answer (%d, %d), zone %s",
+ cp - buf, eom - buf,
+ zp->z_origin);
+ error++;
+ break;
+ }
+#ifdef STUBS
+ }
+#endif
+ GETSHORT(n, tmp);
+ if (n == T_SOA) {
+ if (soacnt == 0) {
+ soacnt++;
+ if (dn_expand(buf, buf+PACKETSZ, nmp,
+ name, sizeof name) < 0) {
+ badsoa_msg = "soa name error";
+ goto badsoa;
+ }
+ if (strcasecmp(name, zp->z_origin)!=0){
+ syslog(LOG_INFO,
+ "wrong zone name in AXFR (wanted \"%s\", got \"%s\")",
+ zp->z_origin, name);
+ badsoa_msg = "wrong soa name";
+ goto badsoa;
+ }
+ if (eom - tmp
+ <= 2 * INT16SZ + INT32SZ) {
+ badsoa_msg = "soa header";
+ goto badsoa;
+ }
+ tmp += 2 * INT16SZ + INT32SZ;
+ if ((n = dn_skipname(tmp, eom)) < 0) {
+ badsoa_msg = "soa mname";
+ goto badsoa;
+ }
+ tmp += n;
+ if ((n = dn_skipname(tmp, eom)) < 0) {
+ badsoa_msg = "soa hname";
+ goto badsoa;
+ }
+ tmp += n;
+ if (eom - tmp <= INT32SZ) {
+ badsoa_msg = "soa dlen";
+ goto badsoa;
+ }
+ GETLONG(serial, tmp);
+ dprintf(3, (ddt,
+ "first SOA for %s, serial %lu\n",
+ name, (u_long)serial));
+ continue;
+ }
+ if (dn_expand(buf, buf+PACKETSZ, nmp,
+ name2, sizeof name2) == -1) {
+ badsoa_msg = "soa name error#2";
+ goto badsoa;
+ }
+ if (strcasecmp((char *)name,
+ (char *)name2) != 0) {
+ syslog(LOG_INFO,
+ "got extra SOA for \"%s\" in zone \"%s\"",
+ name2, name);
+ continue;
+ }
+ tmp -= INT16SZ; /* Put TYPE back. */
+ badsoa_msg = soa_zinfo(&zp_finish, tmp, eom);
+ if (badsoa_msg)
+ goto badsoa;
+ dprintf(2, (ddt,
+ "SOA, serial %lu\n",
+ (u_long)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_INFO,
+ "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(NETREAD_BROKEN)
+ 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_INFO, setitimerStr);
+ return (-1);
+ }
+ errno = 0;
+ n = recv(fd, buf, len, 0);
+ if (n == 0 && errno == 0) {
+#if defined(NETREAD_BROKEN)
+ if (++retries < 42) /* doug adams */
+ continue;
+#endif
+ syslog(LOG_INFO, "premature EOF, fetching \"%s\"",
+ domain);
+ return (-1);
+ }
+ if (n < 0) {
+ if (errno == 0) {
+#if defined(NETREAD_BROKEN)
+ if (++retries < 42) /* doug adams */
+ continue;
+#endif
+ syslog(LOG_INFO,
+ "recv(len=%d): n=%d && !errno",
+ len, n);
+ return (-1);
+ }
+ if (errno == EINTR) {
+ if (!read_interrupted) {
+ /* It wasn't a timeout; ignore it. */
+ continue;
+ }
+ errno = ETIMEDOUT;
+ }
+ syslog(LOG_INFO, "recv(len=%d): %m", len);
+ return (-1);
+ }
+ buf += n;
+ len -= n;
+ }
+ if (setitimer(ITIMER_REAL, &zeroival, NULL) < 0) {
+ syslog(LOG_INFO, setitimerStr);
+ return (-1);
+ }
+ return (0);
+}
+
+static const char *
+soa_zinfo(zp, cp, eom)
+ register struct zoneinfo *zp;
+ register u_char *cp;
+ u_char *eom;
+{
+ register int n;
+ int type, class;
+ u_long ttl;
+
+ /* Are type, class, and ttl OK? */
+ if (eom - cp < 3 * INT16SZ + INT32SZ)
+ return ("zinfo too short");
+ GETSHORT(type, cp);
+ GETSHORT(class, cp);
+ GETLONG(ttl, cp);
+ cp += INT16SZ; /* dlen */
+ if (type != T_SOA || class != curclass)
+ return ("zinfo wrong typ/cla/ttl");
+ /* Skip master name and contact name, we can't validate them. */
+ if ((n = dn_skipname(cp, eom)) == -1)
+ return ("zinfo mname");
+ cp += n;
+ if ((n = dn_skipname(cp, eom)) == -1)
+ return ("zinfo hname");
+ cp += n;
+ /* Grab the data fields. */
+ if (eom - cp < 5 * INT32SZ)
+ return ("zinfo dlen");
+ GETLONG(zp->z_serial, cp);
+ GETLONG(zp->z_refresh, cp);
+ GETLONG(zp->z_retry, cp);
+ GETLONG(zp->z_expire, cp);
+ GETLONG(zp->z_minimum, cp);
+ return (NULL);
+}
+
+/*
+ * 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 = "";
+
+ 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_LOC:
+ case T_NSAP:
+ case T_AAAA:
+ 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;
+
+ case T_PX:
+ /* grab preference */
+ bcopy((char *)cp, data, INT16SZ);
+ cp1 = (u_char *)data + INT16SZ;
+ cp += INT16SZ;
+
+ /* get MAP822 name */
+ n = dn_expand(msg, msg + msglen, cp,
+ (char *)cp1, sizeof data - INT16SZ);
+ if (n < 0)
+ return (-1);
+ cp += n;
+ cp1 += (n = (strlen((char *) cp1) + 1));
+ n1 = sizeof data - n;
+
+ /* get MAPX400 name */
+ n = dn_expand(msg, msg + msglen, cp, (char *)cp1, n1);
+ if (n < 0)
+ return (-1);
+ cp += n;
+ cp1 += strlen((char *) cp1) + 1;
+ n = cp1 - (u_char *)data;
+ cp1 = (u_char *)data;
+ break;
+
+ default:
+ syslog(LOG_INFO, "\"%s %s %s\" - unknown type (%d)",
+ dname, p_class(class), p_type(type), type);
+ hp->rcode = NOTIMP;
+ return (-1);
+ }
+ if (n > MAXDATA) {
+ dprintf(1, (ddt,
+ "update type %d: %d bytes is too much data\n",
+ type, n));
+ hp->rcode = 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) < (size_t)8)
+ tab = 1;
+ } else {
+ (void) fprintf(dbfp, "%s\t", ignore);
+ tab = 1;
+ }
+
+ if (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);
+ fputs(inet_ntoa(*(struct in_addr *) &n), dbfp);
+ 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;
+ for (i = 0; i < 2; i++) {
+ if (i != 0)
+ (void) putc(' ', dbfp);
+ n = *cp++;
+ cp1 = cp + n;
+ if (cp1 > cp2)
+ cp1 = cp2;
+ (void) putc('"', dbfp);
+ j = 0;
+ while (cp < cp1) {
+ if (*cp == '\0') {
+ cp = cp1;
+ break;
+ }
+ if (strchr("\n\"\\", *cp))
+ (void) putc('\\', dbfp);
+ (void) putc(*cp++, dbfp);
+ j++;
+ }
+ if (j == 0 && (type != T_ISDN || i == 0))
+ (void) putc('?', dbfp);
+ (void) putc('"', dbfp);
+ }
+ (void) putc('\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, (u_long)n);
+ GETLONG(n, cp);
+ (void) fprintf(dbfp, " %lu", (u_long)n);
+ GETLONG(n, cp);
+ (void) fprintf(dbfp, " %lu", (u_long)n);
+ GETLONG(n, cp);
+ (void) fprintf(dbfp, " %lu", (u_long)n);
+ GETLONG(n, cp);
+ (void) fprintf(dbfp, " %lu )\n", (u_long)n);
+ break;
+
+ case T_MX:
+ case T_AFSDB:
+ case T_RT:
+ GETSHORT(n, cp);
+ (void) fprintf(dbfp, "%lu", (u_long)n);
+ (void) fprintf(dbfp, " %s.\n", cp);
+ break;
+
+ case T_PX:
+ GETSHORT(n, cp);
+ (void) fprintf(dbfp, "%lu", (u_long)n);
+ (void) fprintf(dbfp, " %s.", cp);
+ cp += strlen((char *) cp) + 1;
+ (void) fprintf(dbfp, " %s.\n", cp);
+ break;
+
+ 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 (strchr("\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_AAAA: {
+ char t[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"];
+
+ fprintf(dbfp, "%s\n", inet_ntop(AF_INET6, cp, t, sizeof t));
+ break;
+ }
+ case T_UINFO:
+ (void) fprintf(dbfp, "\"%s\"\n", cp);
+ break;
+
+#ifdef LOC_RR
+ case T_LOC:
+ (void) fprintf(dbfp, "%s\n", loc_ntoa(cp, NULL));
+ break;
+#endif /* LOC_RR */
+
+ case T_UID:
+ case T_GID:
+ if (n == INT32SZ) {
+ GETLONG(n, cp);
+ (void) fprintf(dbfp, "%lu\n", (u_long)n);
+ }
+ break;
+
+ case T_WKS:
+ GETLONG(addr, cp);
+ addr = htonl(addr);
+ fputs(inet_ntoa(*(struct in_addr *) &addr), dbfp);
+ fputc(' ', dbfp);
+ 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 */
diff --git a/contrib/bind/named/named.h b/contrib/bind/named/named.h
new file mode 100644
index 0000000..0575a5c
--- /dev/null
+++ b/contrib/bind/named/named.h
@@ -0,0 +1,19 @@
+/* named.h - include the local definitions in the right order
+ * vix 28aug93 [original]
+ *
+ * $Id: named.h,v 8.1 1994/12/15 06:24:14 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/contrib/bind/named/named.reload.sh b/contrib/bind/named/named.reload.sh
new file mode 100644
index 0000000..0b6495a
--- /dev/null
+++ b/contrib/bind/named/named.reload.sh
@@ -0,0 +1,7 @@
+#!/bin/sh -
+#
+# from named.reload 5.2 (Berkeley) 6/27/89
+# $Id: named.reload.sh,v 8.1 1994/12/15 06:24:14 vixie Exp $
+#
+
+exec %DESTSBIN%/%INDOT%ndc reload
diff --git a/contrib/bind/named/named.restart.sh b/contrib/bind/named/named.restart.sh
new file mode 100644
index 0000000..4d073e6
--- /dev/null
+++ b/contrib/bind/named/named.restart.sh
@@ -0,0 +1,7 @@
+#!/bin/sh -
+#
+# from named.restart 5.4 (Berkeley) 6/27/89
+# $Id: named.restart.sh,v 8.1 1994/12/15 06:24:14 vixie Exp $
+#
+
+exec %DESTSBIN%/%INDOT%ndc restart
diff --git a/contrib/bind/named/ndc.sh b/contrib/bind/named/ndc.sh
new file mode 100644
index 0000000..883dabc
--- /dev/null
+++ b/contrib/bind/named/ndc.sh
@@ -0,0 +1,83 @@
+#!/bin/sh
+
+USAGE='echo \
+ "usage: $0 \
+ (status|dumpdb|reload|stats|trace|notrace|querylog|start|stop|restart) \
+ ... \
+ "; exit 1'
+
+PATH=%DESTSBIN%:/bin:/usr/bin:/usr/ucb:$PATH
+PIDFILE=%PIDDIR%/named.pid
+
+if [ -f $PIDFILE ]
+then
+ PID=`cat $PIDFILE`
+ PS=`%PS% $PID | tail -1 | grep $PID`
+ RUNNING=1
+ [ `echo $PS | wc -w` -ne 0 ] || {
+ PS="named (pid $PID?) not running"
+ RUNNING=0
+ }
+else
+ PS="named (no pid file) not running"
+ RUNNING=0
+fi
+
+for ARG
+do
+ case $ARG in
+ start|stop|restart)
+ ;;
+ *)
+ [ $RUNNING -eq 0 ] && {
+ echo $PS
+ exit 1
+ }
+ esac
+
+ case $ARG in
+ status) echo "$PS";;
+ dumpdb) kill -INT $PID && echo Dumping Database;;
+ reload) kill -HUP $PID && echo Reloading Database;;
+ stats) kill -%IOT% $PID && echo Dumping Statistics;;
+ trace) kill -USR1 $PID && echo Trace Level Incremented;;
+ notrace) kill -USR2 $PID && echo Tracing Cleared;;
+ querylog|qrylog) kill -WINCH $PID && echo Query Logging Toggled;;
+ start)
+ [ $RUNNING -eq 1 ] && {
+ echo "$0: start: named (pid $PID) already running"
+ continue
+ }
+ rm -f $PIDFILE
+ %INDOT%named && {
+ sleep 5
+ echo Name Server Started
+ }
+ ;;
+ stop)
+ [ $RUNNING -eq 0 ] && {
+ echo "$0: stop: named not running"
+ continue
+ }
+ kill $PID && {
+ sleep 5
+ rm -f $PIDFILE
+ echo Name Server Stopped
+ }
+ ;;
+ restart)
+ [ $RUNNING -eq 1 ] && {
+ kill $PID && sleep 5
+ }
+ rm -f $PIDFILE
+ %INDOT%named && {
+ sleep 5
+ echo Name Server Restarted
+ }
+ ;;
+ *) eval "$USAGE";;
+ esac
+done
+test -z "$ARG" && eval "$USAGE"
+
+exit 0
diff --git a/contrib/bind/named/ns_defs.h b/contrib/bind/named/ns_defs.h
new file mode 100644
index 0000000..6bd10e5
--- /dev/null
+++ b/contrib/bind/named/ns_defs.h
@@ -0,0 +1,397 @@
+/*
+ * from ns.h 4.33 (Berkeley) 8/23/90
+ * $Id: ns_defs.h,v 8.6 1996/05/17 09:10: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 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_PER_NS 2 /* max # of xfers per peer nameserver */
+#define XFER_BUFSIZE (16*1024) /* arbitrary but bigger than most MTU's */
+
+#define ALPHA 0.7 /* How much to preserve of old response time */
+#define BETA 1.2 /* How much to penalize response time on failure */
+#define GAMMA 0.98 /* How much to decay unused response times */
+
+#define USE_MINIMUM 0xffffffff
+
+ /* sequence-space arithmetic */
+#define SEQ_GT(a,b) ((int32_t)((a)-(b)) > 0)
+
+ /* cheap garbage collection */
+#define FREE_ONCE(p) { if (p) { free(p); p = NULL; } }
+
+/* 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
+#ifdef BIND_NOTIFY
+ /* XXX - this will have to move to the name when we do !SOA notify */
+ struct notify *z_notifylist; /* list of servers we should notify */
+#endif
+};
+
+#ifdef BIND_NOTIFY
+struct notify {
+ struct in_addr addr; /* of server */
+ time_t last; /* when they asked */
+ struct notify *next;
+ /* XXX - this will need a type field when we do !SOA notify */
+};
+#endif
+
+ /* zone types (z_type) */
+#define Z_NIL 0 /* zone slot not in use */
+#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 */
+#define Z_XFER_ABORTED 0x2000 /* zone transfer has been aborted */
+#define Z_XFER_GONE 0x4000 /* zone transfer process is gone */
+
+ /* 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) */
+#if defined(LAME_DELEGATION) || defined(VALIDATE)
+ char q_domain[MAXDNAME]; /* domain for servers we are querying */
+#endif
+#ifdef BIND_NOTIFY
+ int q_notifyzone; /* zone which needs a sysnotify()
+ * when the reply to this comes in.
+ */
+#endif
+};
+
+ /* q_flags bits (8 bits) */
+#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 { nssRcvdR, /* sent us an answer */
+ nssRcvdNXD, /* sent us a negative response */
+ nssRcvdFwdR, /* sent us a response we had to fwd */
+ nssRcvdDupR, /* sent us an extra answer */
+ nssRcvdFail, /* sent us a SERVFAIL */
+ nssRcvdFErr, /* sent us a FORMERR */
+ nssRcvdErr, /* sent us some other error */
+ 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 */
+ nssSentDupQ, /* sent them a retry */
+ nssSendtoErr, /* error in sendto */
+#ifdef XSTATS
+ nssRcvdQ, /* sent us a query */
+ nssRcvdIQ, /* sent us an inverse query */
+ nssRcvdFwdQ, /* sent us a query we had to fwd */
+ nssRcvdDupQ, /* sent us a retry */
+ nssRcvdTCP, /* sent us a query using TCP */
+ nssSentFwdR, /* fwdd a response to them */
+ nssSentFail, /* sent them a SERVFAIL */
+ nssSentFErr, /* sent them a FORMERR */
+ nssSentNaAns, /* sent them a non autoritative answer */
+ nssSentNXD, /* sent them a negative response */
+#endif
+ 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) (ddt && (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/contrib/bind/named/ns_forw.c b/contrib/bind/named/ns_forw.c
new file mode 100644
index 0000000..362bf8b
--- /dev/null
+++ b/contrib/bind/named/ns_forw.c
@@ -0,0 +1,1094 @@
+#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 8.14 1996/08/05 08:31:30 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/types.h>
+#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 = nsqhead; qp != QINFO_NULL; qp = qp->q_link) {
+ if (qp->q_id == id &&
+ bcmp((char *)&qp->q_from, fp, sizeof(qp->q_from)) == 0 &&
+ ((qp->q_cmsglen == 0 && qp->q_msglen == msglen &&
+ 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)));
+#ifdef XSTATS
+ nameserIncr(fp->sin_addr, nssRcvdDupQ);
+#endif
+ return (FW_DUP);
+ }
+ }
+
+ qp = qnew();
+#if defined(LAME_DELEGATION) || defined(VALIDATE)
+ 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 && !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(nsid_next());
+ hp->ancount = htons(0);
+ hp->nscount = htons(0);
+ hp->arcount = htons(0);
+ if ((qp->q_msg = (u_char *)malloc((unsigned)msglen)) == NULL) {
+ syslog(LOG_NOTICE, "forw: malloc: %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,
+ (int)(qp->q_time - tt.tv_sec)));
+#ifdef DEBUG
+ if (debug >= 10)
+ fp_nquery(msg, msglen, ddt);
+#endif
+ if (sendto(ds, (char *)msg, msglen, 0, (struct sockaddr *)nsa,
+ sizeof(struct sockaddr_in)) < 0) {
+ if (!haveComplained((char*)nsa->sin_addr.s_addr, sendtoStr))
+ syslog(LOG_INFO, "ns_forw: sendto([%s].%d): %m",
+ inet_ntoa(nsa->sin_addr), ntohs(nsa->sin_port));
+ nameserIncr(nsa->sin_addr, nssSendtoErr);
+ }
+#ifdef XSTATS
+ nameserIncr(fp->sin_addr, nssRcvdFwdQ);
+#endif
+ 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)
+ const char *tag1, *tag2;
+{
+ struct complaint {
+ const 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));
+ if (cur) {
+ cur->tag1 = tag1;
+ cur->tag2 = tag2;
+ cur->expire = tt.tv_sec + INIT_REFRESH; /* "10:00" */
+ 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.
+ */
+static void
+nslookupComplain(sysloginfo, queryname, complaint, dname, a_rr, nsdp)
+ const char *sysloginfo, *queryname, *complaint, *dname;
+ const struct databuf *a_rr, *nsdp;
+{
+#ifdef STATS
+ char nsbuf[20];
+ char abuf[20];
+#endif
+ char *a, *ns;
+ const char *a_type;
+ int print_a;
+
+ dprintf(2, (ddt, "NS '%s' %s\n", dname, complaint));
+ if (sysloginfo && queryname && !haveComplained(queryname, complaint))
+ {
+ char buf[999];
+
+ a = ns = (char *)NULL;
+ print_a = (a_rr->d_type == T_A);
+ a_type = p_type(a_rr->d_type);
+#ifdef NCACHE
+ if (a_rr->d_rcode) {
+ print_a = 0;
+ switch(a_rr->d_rcode) {
+ case NXDOMAIN:
+ a_type = "NXDOMAIN";
+ break;
+ case NOERROR_NODATA:
+ a_type = "NODATA";
+ break;
+ }
+ }
+#endif
+#ifdef STATS
+ if (nsdp) {
+ if (nsdp->d_ns) {
+ strcpy(nsbuf, inet_ntoa(nsdp->d_ns->addr));
+ ns = nsbuf;
+ } else {
+ ns = zones[nsdp->d_zone].z_origin;
+ }
+ }
+ if (a_rr->d_ns) {
+ strcpy(abuf, inet_ntoa(a_rr->d_ns->addr));
+ a = abuf;
+ } else {
+ a = zones[a_rr->d_zone].z_origin;
+ }
+#endif
+ /* syslog only takes 5 params */
+ if ( a != NULL || ns != NULL)
+ sprintf(buf, "%s: query(%s) %s (%s:%s) learnt (%s=%s:NS=%s)",
+ sysloginfo, queryname,
+ complaint, dname,
+ print_a ?
+ inet_ntoa(data_inaddr(a_rr->d_data)) : "",
+ a_type,
+ a ? a : "<Not Available>",
+ ns ? ns : "<Not Available>" );
+ else
+ sprintf(buf, "%s: query(%s) %s (%s:%s)",
+ sysloginfo, queryname,
+ complaint, dname,
+ print_a ?
+ inet_ntoa(data_inaddr(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;
+ const char *syslogdname;
+ const 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;
+ const char *fname;
+ int oldn, naddr, class, found_arr, potential_ns;
+ time_t curtime;
+
+ dprintf(3, (ddt, "nslookup(nsp=0x%lx, qp=0x%lx, \"%s\")\n",
+ (u_long)nsp, (u_long)qp, syslogdname));
+
+ potential_ns = 0;
+ 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 (%#lx)\n",
+ dname, class, nsdp->d_type,
+ (u_long)nsdp->d_flags));
+
+ /* don't put in servers we have tried */
+ for (i = 0; i < qp->q_nusedns; i++) {
+ 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) {
+ dprintf(3, (ddt, "%s: not found %s %lx\n",
+ dname, fname, (u_long)np));
+ found_arr = 0;
+ goto need_sysquery;
+ }
+ if (fname != dname) {
+ if (findMyZone(np, class) == DB_Z_CACHE) {
+ /*
+ * lifted from findMyZone()
+ * We really need to know if the NS
+ * is the bottom of one of our zones
+ * to see if we've got missing glue
+ */
+ for (; np; np = np_parent(np))
+ for (dp = np->n_data; dp; dp=dp->d_next)
+ if (match(dp, class, T_NS)) {
+#ifdef NCACHE
+ if (dp->d_rcode)
+ break;
+#endif
+ if (dp->d_zone) {
+ static char *complaint =
+ "Glue A RR missing";
+ nslookupComplain(sysloginfo,
+ syslogdname,
+ complaint,
+ dname, dp,
+ nsdp);
+ goto skipserver;
+ } else {
+ found_arr = 0;
+ goto need_sysquery;
+ }
+ }
+ /* shouldn't happen, but ... */
+ found_arr = 0;
+ goto need_sysquery;
+ } else {
+ static char *complaint =
+ "Authoritative A RR missing";
+ nslookupComplain(sysloginfo, syslogdname,
+ complaint, dname, dp, nsdp);
+ 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) {
+ static char *complaint = "NS points to CNAME";
+#ifdef NCACHE
+ if (dp->d_rcode)
+ continue;
+#endif
+ nslookupComplain(sysloginfo, syslogdname,
+ complaint, dname, dp, nsdp);
+ goto skipserver;
+ }
+ if (dp->d_type != T_A || dp->d_class != class)
+ continue;
+#ifdef NCACHE
+ if (dp->d_rcode) {
+ static char *complaint =
+ "A RR negative cache entry";
+ nslookupComplain(sysloginfo, syslogdname,
+ complaint, dname, dp, nsdp);
+ goto skipserver;
+ }
+#endif
+ if (data_inaddr(dp->d_data).s_addr == INADDR_ANY) {
+ static char *complaint = "Bogus (0.0.0.0) A RR";
+ nslookupComplain(sysloginfo, syslogdname,
+ complaint, dname, dp, nsdp);
+ continue;
+ }
+#ifdef INADDR_LOOPBACK
+ if (ntohl(data_inaddr(dp->d_data).s_addr) ==
+ INADDR_LOOPBACK) {
+ static char *complaint = "Bogus LOOPBACK A RR";
+ nslookupComplain(sysloginfo, syslogdname,
+ complaint, dname, dp, nsdp);
+ continue;
+ }
+#endif
+#ifdef INADDR_BROADCAST
+ if (ntohl(data_inaddr(dp->d_data).s_addr) ==
+ INADDR_BROADCAST) {
+ static char *complaint = "Bogus BROADCAST A RR";
+ nslookupComplain(sysloginfo, syslogdname,
+ complaint, dname, dp, nsdp);
+ continue;
+ }
+#endif
+#ifdef IN_MULTICAST
+ if (IN_MULTICAST(ntohl(data_inaddr(dp->d_data).s_addr))) {
+ static char *complaint = "Bogus MULTICAST A RR";
+ nslookupComplain(sysloginfo, syslogdname,
+ complaint, dname, dp, nsdp);
+ continue;
+ }
+#endif
+ /*
+ * Don't use records that may become invalid to
+ * reference later when we do the rtt computation.
+ * Never delete our safety-belt information!
+ */
+ if ((dp->d_zone == 0) &&
+#ifdef DATUMREFCNT
+ (dp->d_ttl < curtime) &&
+#else
+ (dp->d_ttl < (curtime+900)) &&
+#endif
+ !(dp->d_flags & DB_F_HINT) )
+ {
+ dprintf(3, (ddt,
+ "nslookup: stale entry '%s'\n",
+ NAME(*np)));
+ /* Cache invalidate the NS RR's */
+#ifndef DATUMREFCNT
+ if (dp->d_ttl < curtime)
+#endif
+ {
+ delete_all(np, class, T_A);
+ n = oldn;
+ found_arr = 0;
+ goto need_sysquery;
+ }
+ }
+#ifdef VALIDATE
+ /* anant@isi.edu validation procedure, maintains a
+ * table of server names-addresses used recently
+ */
+ store_name_addr(dname, data_inaddr(dp->d_data),
+ syslogdname, sysloginfo);
+#endif /*VALIDATE*/
+
+ found_arr++;
+ nsa = data_inaddr(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)
+ *
+ * try to limp along instead of denying service
+ * gdonl mar96
+ */
+ if (aIsUs(nsa)) {
+ static char *complaint = "contains our address";
+ nslookupComplain(sysloginfo, syslogdname,
+ complaint, dname, dp, nsdp);
+ continue;
+ }
+ /*
+ * 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)
+ *
+ * try to limp along instead of denying service
+ * gdonl mar96
+ */
+ 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, nsdp);
+ continue;
+ }
+#ifdef BOGUSNS
+ /*
+ * 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;
+#endif
+
+ n++;
+ if (n >= NSMAX)
+ goto out;
+ skipaddr:
+ NULL;
+ }
+ dprintf(8, (ddt, "nslookup: %d ns addrs\n", n));
+ need_sysquery:
+ if (found_arr == 0) {
+ potential_ns++;
+ if (!(qp->q_flags & Q_SYSTEM))
+ (void) sysquery(dname, class, T_A, NULL, 0,
+ QUERY);
+ }
+ skipserver:
+ NULL;
+ }
+out:
+ dprintf(3, (ddt, "nslookup: %d ns addrs total\n", n));
+ qp->q_naddr = n;
+ if (n == 0 && potential_ns == 0 && !fwdtab) {
+ static char *complaint = "No possible A RRs";
+ if (sysloginfo && syslogdname &&
+ !haveComplained(syslogdname, complaint))
+ {
+ syslog(LOG_INFO, "%s: query(%s) %s",
+ sysloginfo, syslogdname, complaint);
+ }
+ return(-1);
+ }
+#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%lx, %ld sec)\n",
+ (u_long)qp, (long)t);
+ if (qp->q_time)
+ fprintf(ddt,
+ "WARNING: schedretry(%#lx, %ld) q_time already %ld\n",
+ (u_long)qp, (long)t, (long)qp->q_time);
+ }
+#endif
+ t += (u_long) tt.tv_sec;
+ 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(%#lx, %d)\n", (u_long)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%lx) id=%d\n", (u_long)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%lx): expired @ %lu (%d secs before now (%lu))\n",
+ (u_long)qp, (u_long)qp->q_expire,
+ (int)(tt.tv_sec - qp->q_expire),
+ (u_long)tt.tv_sec));
+ if (qp->q_stream) /* return failure code on stream */
+ goto fail;
+ qremove(qp);
+ 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 = (NoRecurse == 0);
+ hp->rd = 1;
+ hp->rcode = SERVFAIL;
+#ifdef DEBUG
+ if (debug >= 10)
+ fp_nquery(qp->q_msg, n, ddt);
+#endif
+ if (send_msg((u_char *)hp, n, qp)) {
+ dprintf(1, (ddt, "gave up retry(x%lx) nsid=%d id=%d\n",
+ (u_long)qp, ntohs(qp->q_nsid), ntohs(qp->q_id)));
+ }
+#ifdef XSTATS
+ nameserIncr(qp->q_from.sin_addr, nssSentFail);
+#endif
+ 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_nquery(qp->q_msg, qp->q_msglen, ddt);
+#endif
+ /* NOSTRICT */
+ if (sendto(ds, (char*)qp->q_msg, qp->q_msglen, 0,
+ (struct sockaddr *)nsa,
+ sizeof(struct sockaddr_in)) < 0) {
+ dprintf(3, (ddt, "error resending msg errno=%d\n", errno));
+ }
+ 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 (nsqhead)
+ qremove(nsqhead);
+ nsqhead = QINFO_NULL;
+}
+
+void
+qremove(qp)
+ register struct qinfo *qp;
+{
+ dprintf(3, (ddt, "qremove(x%lx)\n", (u_long)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 = nsqhead; 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;
+
+ qp = (struct qinfo *)
+#ifdef DMALLOC
+ dcalloc(file, line, 1, sizeof(struct qinfo));
+#else
+ calloc(1, sizeof(struct qinfo));
+#endif
+ if (qp == NULL) {
+ dprintf(5, (ddt, "qnew: calloc error\n"));
+ syslog(LOG_ERR, "forw: %m");
+ exit(12);
+ }
+ dprintf(5, (ddt, "qnew(x%lx)\n", (u_long)qp));
+#ifdef BIND_NOTIFY
+ qp->q_notifyzone = DB_Z_CACHE;
+#endif
+ qp->q_link = nsqhead;
+ nsqhead = qp;
+ return (qp);
+}
+
+void
+qfree(qp)
+ struct qinfo *qp;
+{
+ register struct qinfo *np;
+ register struct databuf *dp;
+#ifdef DATUMREFCNT
+ int i;
+#endif
+
+ dprintf(3, (ddt, "Qfree(x%lx)\n", (u_long)qp));
+ if (qp->q_next)
+ dprintf(1, (ddt, "WARNING: qfree of linked ptr x%lx\n",
+ (u_long)qp));
+ if (qp->q_msg)
+ free(qp->q_msg);
+ if (qp->q_cmsg)
+ 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( nsqhead == qp ) {
+ nsqhead = qp->q_link;
+ } else {
+ for( np=nsqhead; np->q_link != QINFO_NULL; np = np->q_link ) {
+ if( np->q_link != qp ) continue;
+ np->q_link = qp->q_link; /* dequeue */
+ break;
+ }
+ }
+ free((char *)qp);
+}
diff --git a/contrib/bind/named/ns_func.h b/contrib/bind/named/ns_func.h
new file mode 100644
index 0000000..204aee2
--- /dev/null
+++ b/contrib/bind/named/ns_func.h
@@ -0,0 +1,166 @@
+/* ns_func.h - declarations for ns_*.c's externally visible functions
+ *
+ * $Id: ns_func.h,v 8.9 1996/05/20 15:10:01 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((const char *, int, int,
+ struct in_addr *, int, int));
+extern struct notify *findNotifyPeer __P((const struct zoneinfo *,
+ struct in_addr));
+extern void sysnotify __P((const char *, int, int));
+extern int doupdate __P((u_char *, int, u_char *, int,
+ struct databuf **, int, u_int)),
+ send_msg __P((u_char *, int, struct qinfo *)),
+ findns __P((struct namebuf **, int,
+ 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, int *));
+/* --from ns_resp.c-- */
+
+/* ++from ns_req.c++ */
+extern void ns_req __P((u_char *, int, int,
+ struct qstream *,
+ struct sockaddr_in *,
+ int)),
+ free_addinfo __P((void)),
+ free_nsp __P((struct databuf **));
+extern int stale __P((struct databuf *)),
+ make_rr __P((const char *, struct databuf *,
+ u_char *, int, int)),
+ doaddinfo __P((HEADER *, u_char *, int)),
+ doaddauth __P((HEADER *, u_char *, int,
+ struct namebuf *,
+ struct databuf *));
+#ifdef BIND_NOTIFY
+extern int findZonePri __P((const struct zoneinfo *,
+ const struct sockaddr_in *));
+#endif
+/* --from ns_req.c-- */
+
+/* ++from ns_forw.c++ */
+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((const char *, const char *)),
+ nslookup __P((struct databuf *nsp[],
+ struct qinfo *qp,
+ const char *syslogdname,
+ const char *sysloginfo)),
+ qcomp __P((struct qserv *, struct qserv *));
+extern struct qdatagram *aIsUs __P((struct in_addr));
+extern void 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)),
+ nsid_init __P((void));
+extern u_int16_t nsid_next __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
+#ifdef PURGE_ZONE
+ purge_zone __P((const char *, struct hashbuf *, int)),
+#endif
+ loadxfer __P((void)),
+ qserial_query __P((struct zoneinfo *)),
+ qserial_answer __P((struct qinfo *, u_int32_t));
+extern void holdsigchld __P((void));
+extern void releasesigchld __P((void));
+extern SIG_FN reapchild __P(());
+extern void endxfer __P((void));
+extern const char * zoneTypeString __P((const struct zoneinfo *));
+#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_refreshtime __P((struct zoneinfo *, time_t)),
+ ns_retrytime __P((struct zoneinfo *, time_t)),
+ ns_init __P((char *));
+extern enum context ns_ptrcontext __P((const char *owner));
+extern enum context ns_ownercontext __P((int type, enum transport));
+extern int ns_nameok __P((const char *name, int class,
+ enum transport, enum context));
+extern int ns_wildcard __P((const char *name));
+/* --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));
+#ifdef XSTATS
+extern void ns_logstats __P((void));
+#endif
+extern void qtypeIncr __P((int qtype));
+extern struct nameser *nameserFind __P((struct in_addr addr, int flags));
+#define NS_F_INSERT 0x0001
+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 *, char *, struct sockaddr_in *,
+ int, int, char *, int, int)),
+#else
+ validate __P((char *, char *, struct sockaddr_in *,
+ int, int, char *, int)),
+#endif
+ dovalidate __P((u_char *, int, u_char *, int, int,
+ char *, struct sockaddr_in *, int *)),
+ update_msg __P((u_char *, int *, int Vlist[], int));
+extern void store_name_addr __P((const char *, struct in_addr,
+ const char *, const char *));
+/* --from ns_validate.c-- */
diff --git a/contrib/bind/named/ns_glob.h b/contrib/bind/named/ns_glob.h
new file mode 100644
index 0000000..46abaf7
--- /dev/null
+++ b/contrib/bind/named/ns_glob.h
@@ -0,0 +1,291 @@
+/*
+ * from ns.h 4.33 (Berkeley) 8/23/90
+ * $Id: ns_glob.h,v 8.9 1996/05/20 15:10:01 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 *nsqhead INIT(QINFO_NULL);
+
+ /* list of forwarding hosts */
+DECL struct fwdinfo *fwdtab INIT(NULL);
+
+ /* 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);
+
+#ifdef CLEANCACHE
+ /* What's the minimum interval between cache cleanings? */
+DECL int cache_interval INIT(60*60);
+#endif
+
+#ifdef XSTATS
+ /* What's the minimum interval between stats output? */
+DECL int stats_interval INIT(60*60);
+#endif
+
+ /* need to process finished zone transfers */
+DECL int needendxfer INIT(0);
+
+ /* 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 XSTATS
+ /* need to exit
+ * set by shutdown signal handler
+ * (onintr)
+ */
+DECL int needToExit INIT(0);
+#endif /* XSTATS */
+
+#ifdef QRYLOG
+ /* is query logging turned on? */
+DECL int qrylog INIT(0);
+#endif /*QRYLOG*/
+
+ /* should this server not recurse? */
+DECL int NoRecurse INIT(0);
+
+ /* should this server never fetch glue? */
+DECL int NoFetchGlue 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;
+
+ /* 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 const char *statsfile INIT(STATSFILE);
+#else
+DECL const char *statsfile INIT(_PATH_STATS);
+#endif
+
+DECL const char sendtoStr[] INIT("sendto");
+
+ /* defined in version.c, can't use DECL/INIT */
+extern char Version[];
+
+ /* max value of xfers_running */
+DECL int max_xfers_running INIT(MAX_XFERS_RUNNING);
+
+ /* max number of transfers to any given name server */
+DECL int max_xfers_per_ns INIT(MAX_XFERS_PER_NS);
+
+#ifndef INVQ
+ /* should IQUERY be answered bogusly rather than with NOTIMPL? */
+DECL int fake_iquery INIT(0);
+#endif
+
+enum context { domain_ctx, owner_ctx, mailname_ctx, hostname_ctx };
+DECL const char *context_strings[]
+#ifdef MAIN_PROGRAM
+ = { "domain", "owner", "mail", "host", NULL }
+#endif
+;
+
+enum transport { primary_trans, secondary_trans, response_trans, num_trans };
+DECL const char *transport_strings[]
+#ifdef MAIN_PROGRAM
+ = { "primary", "secondary", "response", NULL }
+#endif
+;
+
+enum severity { ignore, warn, fail };
+DECL const char *severity_strings[]
+#ifdef MAIN_PROGRAM
+ = { "ignore", "warn", "fail", NULL }
+#endif
+;
diff --git a/contrib/bind/named/ns_init.c b/contrib/bind/named/ns_init.c
new file mode 100644
index 0000000..3ca8180
--- /dev/null
+++ b/contrib/bind/named/ns_init.c
@@ -0,0 +1,1110 @@
+#if !defined(lint) && !defined(SABER)
+static char sccsid[] = "@(#)ns_init.c 4.38 (Berkeley) 3/21/91";
+static char rcsid[] = "$Id: ns_init.c,v 8.17 1996/08/05 08:31:30 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/types.h>
+#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 <resolv.h>
+#include <stdio.h>
+#include <errno.h>
+#include <ctype.h>
+
+#include "named.h"
+
+#undef nsaddr
+
+enum limit { Datasize };
+
+static void zoneinit __P((struct zoneinfo *)),
+ get_forwarders __P((FILE *)),
+ boot_read __P((const char *filename, int includefile)),
+#ifdef DEBUG
+ content_zone __P((int)),
+#endif
+ free_forwarders __P((void)),
+ ns_limit __P((const char *name, int value)),
+ ns_checknames __P((const char *names,
+ const char *severity)),
+ ns_rlimit __P((const char *name, enum limit limit,
+ long value)),
+ ns_option __P((const char *name));
+
+static struct zoneinfo *find_zone __P((char *, int, int));
+
+static enum severity checkname_severity[num_trans];
+
+/*
+ * Set new refresh time for zone. Use a random number in the last half of
+ * the refresh limit; we want it to be substantially correct while still
+ * preventing slave synchronization.
+ */
+void
+ns_refreshtime(zp, timebase)
+ struct zoneinfo *zp;
+ time_t timebase;
+{
+ u_long refresh = (zp->z_refresh > 0) ? zp->z_refresh : INIT_REFRESH;
+ time_t half = (refresh + 1) / 2;
+
+ zp->z_time = timebase + half + (rand() % half);
+}
+
+/*
+ * Set new retry time for zone.
+ */
+void
+ns_retrytime(zp, timebase)
+ struct zoneinfo *zp;
+ time_t timebase;
+{
+ zp->z_time = timebase + zp->z_retry;
+}
+
+/*
+ * Read boot file for configuration info.
+ */
+void
+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);
+
+ memset(checkname_severity, '\0', sizeof checkname_severity);
+ checkname_severity[primary_trans] = fail;
+ checkname_severity[secondary_trans] = warn;
+ checkname_severity[response_trans] = ignore;
+
+ 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;
+ zones[0].z_origin = "";
+ } 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, 0);
+
+ /* 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(filename, includefile)
+ const char *filename;
+ int includefile;
+{
+ 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 *flag;
+#endif
+ int slineno; /* Saved global line number. */
+ int i;
+
+ if ((fp = fopen(filename, "r")) == NULL) {
+ syslog(LOG_ERR, "%s: %m", filename);
+ if (includefile)
+ return;
+ exit(1);
+ }
+
+ slineno = lineno;
+ lineno = 1;
+
+ while (!feof(fp) && !ferror(fp)) {
+ /* read named.boot keyword and process args */
+ if (!getword(buf, sizeof(buf), fp, 0)) {
+ /*
+ * This is a blank line, a commented line, or the
+ * '\n' of the previous line.
+ */
+ continue;
+ }
+ if (strcasecmp(buf, "directory") == 0) {
+ (void) getword(buf, sizeof(buf), fp, 0);
+ 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, filename, GETNUM_NONE);
+ continue;
+ } else if (strcasecmp(buf, "limit") == 0) {
+ (void) getword(buf, sizeof(buf), fp, 0);
+ ns_limit(buf, getnum(fp, filename, GETNUM_SCALED));
+ continue;
+ } else if (strcasecmp(buf, "options") == 0) {
+ while (getword(buf, sizeof(buf), fp, 0))
+ ns_option(buf);
+ continue;
+ } else if (strcasecmp(buf, "check-names") == 0) {
+ (void) getword(buf, sizeof(buf), fp, 0);
+ (void) getword(obuf, sizeof(obuf), fp, 0);
+ ns_checknames(buf, obuf);
+ continue;
+ } else if (strcasecmp(buf, "forwarders") == 0) {
+ get_forwarders(fp);
+ continue;
+ } else if (strcasecmp(buf, "slave") == 0) {
+ forward_only++;
+ 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, 1))
+ localdomain = savestr(buf);
+ continue;
+#endif
+ } else if (strcasecmp(buf, "include") == 0) {
+ if (getword(buf, sizeof(buf), fp, 0))
+ boot_read(buf, 1);
+ 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);
+
+ if (class != C_IN) {
+ syslog(LOG_NOTICE,
+ "cache directive with non-IN class is not supported (yet)");
+ endline(fp);
+ continue;
+ }
+ }
+#endif
+ } else if (strncasecmp(buf, "primary", 7) == 0) {
+ type = Z_PRIMARY;
+ 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_NOTICE,
+ "%s: line %d: unknown directive '%s'\n",
+ filename, lineno, buf);
+ endline(fp);
+ continue;
+ }
+
+ /*
+ * read zone origin
+ */
+ if (!getword(obuf, sizeof(obuf), fp, 1)) {
+ syslog(LOG_NOTICE, "%s: line %d: missing origin\n",
+ filename, lineno);
+ continue;
+ }
+ i = strlen(obuf);
+ if ((obuf[i-1] == '.') && (i != 1))
+ syslog(LOG_INFO,
+ "%s: line %d: zone \"%s\" has trailing dot\n",
+ filename, 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, 0)) {
+ syslog(LOG_NOTICE, "%s: line %d: missing %s\n",
+ filename, 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];
+ 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) {
+ syslog(LOG_NOTICE,
+ "no memory for more zones");
+ 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, 0)) {
+#ifdef notyet
+ zp->z_refresh = atoi(buf);
+ if (zp->z_refresh <= 0) {
+ syslog(LOG_NOTICE,
+ "%s: line %d: bad refresh time '%s', ignored\n",
+ filename, lineno, buf);
+ zp->z_refresh = 0;
+ } else if (cache_file == NULL)
+ cache_file = source;
+#else
+ syslog(LOG_NOTICE,
+ "%s: line %d: cache refresh ignored\n",
+ filename, 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, NULL);
+ break;
+
+ case Z_PRIMARY:
+ source = savestr(buf);
+#ifdef ALLOW_UPDATES
+ if (getword(buf, sizeof(buf), fp, 0)) {
+ endline(fp);
+ flag = buf;
+ while (flag) {
+ char *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_NOTICE,
+ "%s: line %d: bad flag '%s'\n",
+ filename, 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;
+#ifdef PURGE_ZONE
+ purge_zone(zp->z_origin, hashtab, zp->z_class);
+#endif
+ dprintf(1, (ddt, "reloading zone\n"));
+ if (!db_load(zp->z_source, zp->z_origin, zp, NULL))
+ 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, 0));
+ 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%ld.%d", _PATH_TMPDIR,
+ (long)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 (!(zp->z_flags & (Z_QSERIAL|Z_XFER_RUNNING))
+ && reloading) {
+ zp->z_time = tt.tv_sec;
+ needmaint = 1;
+ }
+ }
+#endif /* FORCED_RELOAD */
+ break;
+
+ }
+ if ((zp->z_flags & Z_FOUND) && /* already found? */
+ (zp - zones) != DB_Z_CACHE) /* cache never sets Z_FOUND */
+ syslog(LOG_NOTICE,
+ "Zone \"%s\" declared more than once",
+ zp->z_origin);
+ zp->z_flags |= Z_FOUND;
+ dprintf(1, (ddt, "zone[%d] type %d: '%s'",
+ zp-zones, type,
+ *(zp->z_origin) == '\0' ? "." : zp->z_origin));
+ if (zp->z_refresh && zp->z_time == 0)
+ ns_refreshtime(zp, tt.tv_sec);
+ if (zp->z_time <= tt.tv_sec)
+ needmaint = 1;
+ dprintf(1, (ddt, " z_time %lu, z_refresh %lu\n",
+ (u_long)zp->z_time, (u_long)zp->z_refresh));
+ }
+ (void) my_fclose(fp);
+ lineno = slineno;
+}
+
+static void
+zoneinit(zp)
+ register struct zoneinfo *zp;
+{
+ struct stat sb;
+ int result;
+
+ /*
+ * 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;
+ result = stat(zp->z_source, &sb);
+#ifdef PURGE_ZONE
+ if (result != -1)
+ purge_zone(zp->z_origin, hashtab, zp->z_class);
+#endif
+ if (result == -1 || db_load(zp->z_source, zp->z_origin, zp, NULL)) {
+ /*
+ * Set zone to be refreshed immediately.
+ */
+ zp->z_refresh = INIT_REFRESH;
+ zp->z_retry = INIT_REFRESH;
+ if (!(zp->z_flags & (Z_QSERIAL|Z_XFER_RUNNING))) {
+ 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++) {
+ if (zones[zoneNum].z_type == Z_NIL)
+ continue;
+ 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 multiple 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, 0)) {
+ if (strlen(buf) == 0)
+ break;
+ dprintf(1, (ddt," %s",buf));
+ if (!ftp) {
+ ftp = (struct fwdinfo *)malloc(sizeof(struct fwdinfo));
+ if (!ftp)
+ panic(errno, "malloc(fwdinfo)");
+ }
+ if (inet_aton(buf, &ftp->fwdaddr.sin_addr)) {
+ ftp->fwdaddr.sin_port = ns_port;
+ ftp->fwdaddr.sin_family = AF_INET;
+ } else {
+ syslog(LOG_NOTICE, "'%s' (ignored, NOT dotted quad)",
+ buf);
+ continue;
+ }
+#ifdef FWD_LOOP
+ if (aIsUs(ftp->fwdaddr.sin_addr)) {
+ syslog(LOG_NOTICE,
+ "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%lx [%s] next x%lx\n",
+ (u_long)ftp,
+ inet_ntoa(ftp->fwdaddr.sin_addr),
+ (u_long)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
+
+static void
+ns_limit(name, value)
+ const char *name;
+ int value;
+{
+ if (!strcasecmp(name, "transfers-in")) {
+ max_xfers_running = value;
+ } else if (!strcasecmp(name, "transfers-per-ns")) {
+ max_xfers_per_ns = value;
+ } else if (!strcasecmp(name, "datasize")) {
+ ns_rlimit("datasize", Datasize, value);
+ } else {
+ syslog(LOG_ERR,
+ "error: unrecognized limit in bootfile: \"%s\"",
+ name);
+ exit(1);
+ }
+}
+
+static int
+select_string(strings, string)
+ const char *strings[];
+ const char *string;
+{
+ int i;
+
+ for (i = 0; strings[i] != NULL; i++)
+ if (!strcasecmp(strings[i], string))
+ return (i);
+ return (-1);
+}
+
+static void
+ns_checknames(transport_str, severity_str)
+ const char *transport_str;
+ const char *severity_str;
+{
+ enum transport transport;
+ enum severity severity;
+ int i;
+
+ if ((i = select_string(transport_strings, transport_str)) == -1) {
+ syslog(LOG_ERR,
+ "error: unrecognized transport type in bootfile: \"%s\"",
+ transport_str);
+ exit(1);
+ }
+ transport = (enum transport) i;
+
+ if ((i = select_string(severity_strings, severity_str)) == -1) {
+ syslog(LOG_ERR,
+ "error: unrecognized severity type in bootfile: \"%s\"",
+ severity_str);
+ exit(1);
+ }
+ severity = (enum severity) i;
+
+ checkname_severity[transport] = severity;
+ syslog(LOG_INFO, "check-names %s %s", transport_str, severity_str);
+}
+
+enum context
+ns_ptrcontext(owner)
+ const char *owner;
+{
+ if (samedomain(owner, "in-addr.arpa") || samedomain(owner, "ip6.int"))
+ return (hostname_ctx);
+ return (domain_ctx);
+}
+
+enum context
+ns_ownercontext(type, transport)
+ int type;
+ enum transport transport;
+{
+ enum context context;
+
+ switch (type) {
+ case T_A:
+ case T_WKS:
+ case T_MX:
+ switch (transport) {
+ case primary_trans:
+ case secondary_trans:
+ context = owner_ctx;
+ break;
+ case response_trans:
+ context = hostname_ctx;
+ break;
+ default:
+ abort();
+ }
+ break;
+ case T_MB:
+ case T_MG:
+ context = mailname_ctx;
+ default:
+ context = domain_ctx;
+ break;
+ }
+ return (context);
+}
+
+int
+ns_nameok(name, class, transport, context)
+ const char *name;
+ int class;
+ enum transport transport;
+ enum context context;
+{
+ int ok = 1;
+ enum severity severity = checkname_severity[transport];
+
+ if (severity == ignore)
+ return (1);
+ switch (context) {
+ case domain_ctx:
+ ok = (class != C_IN) || res_dnok(name);
+ break;
+ case owner_ctx:
+ ok = (class != C_IN) || res_ownok(name);
+ break;
+ case mailname_ctx:
+ ok = res_mailok(name);
+ break;
+ case hostname_ctx:
+ ok = res_hnok(name);
+ break;
+ default:
+ abort();
+ }
+ if (!ok) {
+ syslog((transport == response_trans) ? LOG_INFO : LOG_NOTICE,
+ "%s name \"%s %s\" (%s) is invalid - %s",
+ context_strings[context],
+ name, p_class(class),
+ transport_strings[transport],
+ (severity == fail) ? "rejecting" : "proceeding anyway");
+ if (severity == warn)
+ ok = 1;
+ }
+ return (ok);
+}
+
+int
+ns_wildcard(name)
+ const char *name;
+{
+ if (*name != '*')
+ return (0);
+ return (*++name == '\0');
+}
+
+static void
+ns_rlimit(name, limit, value)
+ const char *name;
+ enum limit limit;
+ long value;
+{
+#ifndef HAVE_GETRUSAGE
+# ifdef LINT
+ name; limit; value;
+# endif
+ syslog(LOG_WARNING, "warning: unimplemented limit in bootfile: \"%s\"",
+ name);
+#else
+ struct rlimit limits;
+ int rlimit;
+
+ switch (limit) {
+ case Datasize:
+ rlimit = RLIMIT_DATA;
+ break;
+ default:
+ abort();
+ }
+ if (getrlimit(rlimit, &limits) < 0) {
+ syslog(LOG_WARNING, "getrlimit(%s): %m", name);
+ return;
+ }
+ limits.rlim_cur = limits.rlim_max = value;
+ if (setrlimit(rlimit, &limits) < 0) {
+ syslog(LOG_WARNING, "setrlimit(%s, %ld): %m", name, value);
+ return;
+ }
+#endif
+}
+
+static void
+ns_option(name)
+ const char *name;
+{
+ if (!strcasecmp(name, "no-recursion")) {
+ NoRecurse = 1;
+ } else if (!strcasecmp(name, "no-fetch-glue")) {
+ NoFetchGlue = 1;
+#ifdef QRYLOG
+ } else if (!strcasecmp(name, "query-log")) {
+ qrylog = 1;
+#endif
+ } else if (!strcasecmp(name, "forward-only")) {
+ forward_only = 1;
+#ifndef INVQ
+ } else if (!strcasecmp(name, "fake-iquery")) {
+ fake_iquery = 1;
+#endif
+ } else {
+ syslog(LOG_ERR,
+ "error: unrecognized option in bootfile: \"%s\"",
+ name);
+ exit(1);
+ }
+}
diff --git a/contrib/bind/named/ns_main.c b/contrib/bind/named/ns_main.c
new file mode 100644
index 0000000..bac7d5a
--- /dev/null
+++ b/contrib/bind/named/ns_main.c
@@ -0,0 +1,1669 @@
+#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 8.17 1996/08/05 08:31:30 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) 1995 Internet Software Consortium\n\
+ All rights reserved.\n";
+#endif /* not lint */
+
+/*
+ * Internet Name server (see RCF1035 & others).
+ */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/file.h>
+#include <sys/stat.h>
+#if !defined(SYSV) && defined(XXX)
+#include <sys/wait.h>
+#endif /* !SYSV */
+#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>
+#if defined(__osf__)
+# include <sys/mbuf.h>
+# include <net/route.h>
+#endif
+#if defined(_AIX)
+# include <sys/time.h>
+# define TIME_H_INCLUDED
+#endif
+#include <net/if.h>
+#include <arpa/nameser.h>
+#include <arpa/inet.h>
+#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,
+ /* TCP send window size */
+ sbufsize = 16 * 1024;
+
+static struct sockaddr_in nsaddr;
+static u_int16_t local_ns_port, /* our service port */
+ nsid_state;
+static fd_set mask; /* open descriptors */
+static char **Argv = NULL;
+static char *LastArg = NULL; /* end of argv */
+
+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 rfd, size, len;
+ time_t lasttime, maxctime;
+ u_char buf[BUFSIZ];
+#ifdef POSIX_SIGNALS
+ struct sigaction sact;
+#else
+#ifndef SYSV
+ struct sigvec vec;
+#endif
+#endif
+#ifdef NeXT
+ int old_sigmask;
+#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);
+
+ /* BSD has a better random number generator but it's not clear
+ * that we need it here.
+ */
+ gettime(&tt);
+ srand(((unsigned)getpid()) + (unsigned)tt.tv_usec);
+
+ /*
+ ** Save start and extent of argv for ns_setproctitle().
+ */
+
+ 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, "w");
+ if (fp != NULL) {
+ (void) fgets(oldpid, sizeof(oldpid), fp);
+ (void) rewind(fp);
+ fprintf(fp, "%ld\n", (long)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;
+ nsid_init();
+
+ /*
+ ** 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_NOTICE, "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_NOTICE,
+ "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);
+ }
+ /* Retry opening the socket a few times */
+ my_close(vs);
+ sleep(3);
+ }
+ 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.
+ */
+ setsignal(SIGINT, -1, setdumpflg);
+ setsignal(SIGQUIT, -1, setchkptflg);
+ setsignal(SIGIOT, -1, setstatsflg);
+ setsignal(SIGUSR1, -1, setIncrDbgFlg);
+ setsignal(SIGUSR2, -1, setNoDbgFlg);
+
+#if defined(SIGWINCH) && defined(QRYLOG)
+ setsignal(SIGWINCH, -1, setQrylogFlg);
+#endif
+
+ /*
+ * Get list of local addresses and set up datagram sockets.
+ */
+ FD_ZERO(&mask);
+ FD_SET(vs, &mask);
+ 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;
+
+ setsignal(SIGALRM, SIGCHLD, maint_alarm);
+ setsignal(SIGCHLD, SIGALRM, reapchild);
+ setsignal(SIGPIPE, -1, (SIG_FN (*)())SIG_IGN);
+ setsignal(SIGHUP, -1, onhup);
+
+#if defined(SIGXFSZ)
+ /* Wierd DEC Hesiodism, harmless. */
+ setsignal(SIGXFSZ, -1, onhup);
+#endif
+
+#ifdef SIGSYS
+ setsignal(SIGSYS, -1, 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 */
+ setsignal(SIGTERM, -1, onintr);
+#endif
+
+#ifdef XSTATS
+ /* Catch SIGTERM so we can write stats before exiting. */
+ setsignal(SIGTERM, -1, 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);
+#if defined(SYSV) || defined(hpux)
+ 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, "%ld\n", (long)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_NOTICE, "Return from getdtablesize() > FD_SETSIZE");
+ }
+#ifdef NeXT
+ old_sigmask = sigblock(sigmask(SIGCHLD));
+#endif
+ 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 */
+#ifdef XSTATS
+ if (needToExit) {
+ ns_logstats();
+ exit(0);
+ }
+#endif /* XSTATS */
+ if (needreload) {
+ needreload = 0;
+ db_reload();
+ }
+ if (needStatsDump) {
+ needStatsDump = 0;
+ ns_stats();
+ }
+ if (needendxfer) {
+ holdsigchld();
+ needendxfer = 0; /* should be safe even if not held */
+ endxfer(); /* releases SIGCHLD */
+ }
+ releasesigchld();
+ 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;
+#ifdef NeXT
+ sigsetmask(old_sigmask); /* Let queued signals run. */
+#endif
+ n = select(nfds, &tmpmask, (fd_set *)NULL, (fd_set *)NULL, tp);
+#ifdef NeXT
+ old_sigmask = sigblock(sigmask(SIGCHLD));
+#endif
+ if (n < 0 && 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 < 42; udpcnt++) { /*XXX*/
+ int from_len = sizeof(from_addr);
+
+ if ((n = recvfrom(dqp->dq_dfd, (char *)buf,
+ MIN(PACKETSZ, sizeof buf), 0,
+ (struct sockaddr *)&from_addr, &from_len)) < 0)
+ {
+#if defined(SPURIOUS_ECONNREFUSED)
+ if ((n < 0) && (errno == ECONNREFUSED))
+ break;
+#endif
+ if ((n < 0) && (errno == PORT_WOULDBLK))
+ break;
+ syslog(LOG_INFO, "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,
+ ctimel(tt.tv_sec)));
+#ifdef DEBUG
+ if (debug >= 10)
+ fp_nquery(buf, n, 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)) {
+ int 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_INFO, "accept: %m");
+ continue;
+ }
+ if ((n = fcntl(rfd, F_GETFL, 0)) < 0) {
+ syslog(LOG_INFO, "fcntl(rfd, F_GETFL): %m");
+ (void) my_close(rfd);
+ continue;
+ }
+ if (fcntl(rfd, F_SETFL, n|PORT_NONBLOCK) != 0) {
+ syslog(LOG_INFO, "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_INFO,
+ "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_INFO,
+ "rcvd IP_OPTIONS from [%s].%d (ignored)",
+ inet_ntoa(from_addr.sin_addr),
+ ntohs(from_addr.sin_port));
+ }
+ if (setsockopt(rfd, IPPROTO_IP, IP_OPTIONS,
+ NULL, 0) < 0) {
+ syslog(LOG_INFO,
+ "setsockopt(!IP_OPTIONS): %m");
+ (void) my_close(rfd);
+ continue;
+ }
+ }
+#endif
+ if (setsockopt(rfd, SOL_SOCKET, SO_SNDBUF,
+ (char*)&sbufsize, sizeof(sbufsize)) < 0){
+ syslog(LOG_INFO,
+ "setsockopt(rfd, SO_SNDBUF, %d): %m",
+ sbufsize);
+ (void) my_close(rfd);
+ continue;
+ }
+ if (setsockopt(rfd, SOL_SOCKET, SO_KEEPALIVE,
+ (char *)&on, sizeof(on)) < 0) {
+ syslog(LOG_INFO,
+ "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%lx\n",
+ (u_long)streamq));
+ for (sp = streamq; sp != QSTREAM_NULL; sp = nextsp) {
+ nextsp = sp->s_next;
+ if (!FD_ISSET(sp->s_rfd, &tmpmask))
+ continue;
+ dprintf(5, (ddt,
+ "sp x%lx rfd %d size %d time %d next x%lx\n",
+ (u_long)sp, sp->s_rfd, sp->s_size,
+ sp->s_time, (u_long)sp->s_next));
+ dprintf(5, (ddt,
+ "\tbufsize %d buf x%lx bufp x%lx\n",
+ sp->s_bufsize,
+ (u_long)sp->s_buf, (u_long)sp->s_bufp));
+ if (sp->s_size < 0) {
+ size = INT16SZ
+ - (sp->s_bufp - (u_char *)&sp->s_tempsize);
+ 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 = ntohs(sp->s_tempsize);
+ if (sp->s_bufsize == 0) {
+ if (!(sp->s_buf = (u_char *)
+ malloc(rbufsize))
+ ) {
+ 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 = (NoRecurse == 0);
+ 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) {
+#ifdef XSTATS
+ nameserIncr(sp->s_from.sin_addr, nssRcvdTCP);
+#endif
+ 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[32768], *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) && !defined(M_UNIX)
+#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_NOTICE, "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));
+ if (!ntp)
+ panic(errno, "malloc(netinfo)");
+ }
+ ntp->my_addr = ((struct sockaddr_in *)
+ &ifreq.ifr_addr)->sin_addr;
+#ifdef SIOCGIFNETMASK
+ if (ioctl(vs, SIOCGIFNETMASK, (char *)&ifreq) < 0) {
+ syslog(LOG_NOTICE, "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_NOTICE, "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",
+ (u_long)netloop.my_addr.s_addr));
+ }
+ continue;
+ } else if ((ifreq.ifr_flags & IFF_POINTOPOINT)) {
+ if (ioctl(vs, SIOCGIFDSTADDR, (char *)&ifreq) < 0) {
+ syslog(LOG_NOTICE, "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); /* With apologies to The Who. */
+
+ /*
+ * Create separate qdatagram structure for socket
+ * wildcard address.
+ */
+ if (first) {
+ if (!(dqp = (struct qdatagram *)calloc(1, sizeof(*dqp))))
+ panic(errno, "malloc(qdatagram)");
+ 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)
+ panic(errno, "malloc(netinfo)");
+ 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",
+ (u_long)ntp->addr, (u_long)ntp->mask);
+ fprintf(ddt, " my_addr x%lx", ntp->my_addr.s_addr);
+ fprintf(ddt, " %s\n", inet_ntoa(ntp->my_addr));
+ }
+}
+#endif
+
+static void
+opensocket(dqp)
+ register struct qdatagram *dqp;
+{
+ int m, n;
+ 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_NOTICE, "setsockopt(dqp->dq_dfd, reuseaddr): %m");
+ /* XXX press on regardless, this is not too serious. */
+ }
+#ifdef SO_RCVBUF
+ m = sizeof(n);
+ if ((getsockopt(dqp->dq_dfd, SOL_SOCKET, SO_RCVBUF, (char*)&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_NOTICE, "fcntl(dfd, F_GETFL): %m");
+ /* XXX press on regardless, but this really is a problem. */
+ } else if (fcntl(dqp->dq_dfd, F_SETFL, n|PORT_NONBLOCK) != 0) {
+ syslog(LOG_NOTICE, "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_NOTICE, "bind(dfd=%d, [%s].%d): %m",
+ dqp->dq_dfd, inet_ntoa(nsaddr.sin_addr),
+ ntohs(nsaddr.sin_port));
+#if !defined(sun)
+ syslog(LOG_ERR, "exiting");
+ exit(1);
+#endif
+ }
+ FD_SET(dqp->dq_dfd, &mask);
+}
+
+/*
+** 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;
+
+ resignal(SIGHUP, -1, onhup);
+ 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;
+
+ resignal(SIGALRM, SIGCHLD, maint_alarm);
+ 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()
+{
+ int save_errno = errno;
+
+ resignal(SIGTERM, -1, onintr);
+ needToExit = 1;
+ errno = save_errno;
+}
+#endif /* ALLOW_UPDATES */
+
+#ifdef XSTATS
+/*
+ * Signal handler to write log information
+ */
+static SIG_FN
+onintr()
+{
+ int save_errno = errno;
+
+ resignal(SIGTERM, -1, onintr);
+ needToExit = 1; /* XXX variable reuse */
+ errno = save_errno;
+}
+#endif /* XSTATS */
+
+/*
+ * Signal handler to schedule a data base dump. Do this instead of dumping the
+ * data base immediately, to avoid seeing it in a possibly inconsistent state
+ * (due to updates), and to avoid long disk I/O delays at signal-handler
+ * level
+ */
+static SIG_FN
+setdumpflg()
+{
+ int save_errno = errno;
+
+ resignal(SIGINT, -1, setdumpflg);
+ 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_NOTICE, "can't open debug file %s: %m",
+ debugfile);
+ debug = 0;
+ } else {
+#if defined(HAVE_SETVBUF)
+ setvbuf(ddt, NULL, _IOLBF, BUFSIZ);
+#else
+ setlinebuf(ddt);
+#endif
+ if ((n = fcntl(fileno(ddt), F_GETFL, 0)) < 0) {
+ syslog(LOG_INFO,
+ "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;
+
+ resignal(SIGUSR1, -1, setIncrDbgFlg);
+#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;
+
+ resignal(SIGUSR2, -1, setNoDbgFlg);
+ setdebug(0);
+ errno = save_errno;
+}
+
+#if defined(QRYLOG) && defined(SIGWINCH)
+/*
+** Set flag for query logging
+*/
+static SIG_FN
+setQrylogFlg()
+{
+ int save_errno = errno;
+
+ resignal(SIGWINCH, -1, setQrylogFlg);
+ 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;
+
+ resignal(SIGIOT, -1, setstatsflg);
+ needStatsDump = 1;
+ errno = save_errno;
+}
+
+static SIG_FN
+setchkptflg()
+{
+ int save_errno = errno;
+
+ resignal(SIGQUIT, -1, setchkptflg);
+ 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;
+
+ resignal(SIGSYS, -1, sigprof);
+ 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%lx)\n", (u_long)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(%#lx, %d) rfcnt=%d\n",
+ (u_long)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 from this generation (except 0.0.0.0)
+ * will be deleted, and syslog() will be called.
+ * known bugs:
+ * the above text is impenetrable.
+ * side effects:
+ * global list `datagramq' is modified.
+ */
+void
+dqflush(gen)
+ register time_t gen;
+{
+ register struct qdatagram *this, *prev, *next;
+
+ prev = NULL;
+ for (this = datagramq; this != NULL; this = next) {
+ next = this->dq_next;
+ if (gen != (time_t)0) {
+ if (this->dq_addr.s_addr == INADDR_ANY ||
+ this->dq_gen == gen) {
+ prev = this;
+ continue;
+ }
+ syslog(LOG_NOTICE, "interface [%s] missing; deleting",
+ inet_ntoa(this->dq_addr));
+ }
+ FD_CLR(this->dq_dfd, &mask);
+ my_close(this->dq_dfd);
+ free(this);
+ if (prev == NULL)
+ datagramq = next;
+ else
+ prev->dq_next = next;
+ }
+}
+
+/* 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));
+}
+
+/*
+ * These are here in case we ever want to get more clever, like perhaps
+ * using a bitmap to keep track of outstanding queries and a random
+ * allocation scheme to make it a little harder to predict them. Note
+ * that the resolver will need the same protection so the cleverness
+ * should be put there rather than here; this is just an interface layer.
+ */
+
+void
+nsid_init()
+{
+ nsid_state = res_randomid();
+}
+
+u_int16_t
+nsid_next()
+{
+ if (nsid_state == 65535)
+ nsid_state = 0;
+ else
+ nsid_state++;
+ return (nsid_state);
+}
+
+#if defined(BSD43_BSD43_NFS)
+/* junk needed for old Sun NFS licensees */
+#undef dn_skipname
+extern char *dn_skipname();
+char *(*hack_skipname)() = dn_skipname;
+#endif
diff --git a/contrib/bind/named/ns_maint.c b/contrib/bind/named/ns_maint.c
new file mode 100644
index 0000000..631210b
--- /dev/null
+++ b/contrib/bind/named/ns_maint.c
@@ -0,0 +1,1100 @@
+#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 8.16 1996/08/05 08:31:30 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 *)),
+ tryxfer __P((void));
+
+#define qserial_qfull() (qserials_running == MAXQSERIAL)
+
+#ifdef CLEANCACHE
+static time_t cache_time;
+#endif
+#ifdef XSTATS
+static time_t stats_time;
+#endif
+/*
+ * Invoked at regular intervals by signal interrupt; refresh all secondary
+ * zones from primary name server and remove old cache entries. Also,
+ * 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", ctimel(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();
+ ns_refreshtime(zp, tt.tv_sec);
+ break;
+
+ case Z_SECONDARY:
+#ifdef STUBS
+ case Z_STUB:
+#endif
+ if (zp->z_serial != 0 &&
+ ((zp->z_lastupdate + zp->z_expire) <
+ tt.tv_sec)
+ ) {
+ zp->z_serial = 0;
+ }
+ if (zp->z_flags &
+ (Z_NEED_RELOAD|Z_NEED_XFER|Z_QSERIAL)) {
+ ns_refreshtime(zp, tt.tv_sec);
+ break;
+ }
+ if (zp->z_flags & Z_XFER_RUNNING) {
+ abortxfer(zp);
+ 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);
+ ns_refreshtime(zp, tt.tv_sec);
+ }
+ break;
+#endif /* ALLOW_UPDATES */
+ }
+ gettime(&tt);
+ }
+ }
+#ifdef CLEANCACHE
+ if ((cache_time + cache_interval) <= tt.tv_sec) {
+ if (cache_time && (!NoRecurse || !NoFetchGlue))
+ remove_zone(hashtab, 0, 0);
+ cache_time = tt.tv_sec;
+ }
+#endif
+#ifdef XSTATS
+ if (stats_time + stats_interval <= tt.tv_sec) {
+ if (stats_time)
+ ns_logstats();
+ stats_time = tt.tv_sec;
+ }
+#endif
+ if (!needmaint)
+ sched_maint();
+ 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 + cache_interval;
+#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 %lu sec\n",
+ (u_long)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;
+ ns_refreshtime(zp, tt.tv_sec);
+ /*
+ * 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? */
+}
+
+/*
+ * Query for the serial number of a zone, so that
+ * we can check to see if we need to transfer it.
+ */
+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, QUERY);
+ if (!qp) {
+ syslog(LOG_INFO, "qserial_query(%s): sysquery FAILED",
+ zp->z_origin);
+ return; /* XXX - this is bad, we should do something */
+ }
+ qp->q_flags |= Q_ZSERIAL;
+ qp->q_zquery = zp;
+ zp->z_flags |= Z_QSERIAL;
+ ns_refreshtime(zp, tt.tv_sec);
+ 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, (u_long)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, (u_long)serial,
+ inet_ntoa(from_addr.sin_addr),
+ (u_long)zp->z_serial);
+ }
+ } else {
+ dprintf(1, (ddt, "qserial_answer: zone serial is still OK\n"));
+ markUpToDate(zp);
+ }
+ if (was_qfull)
+ needmaint = 1;
+}
+
+/*
+ * Hold and release SIGCHLD
+ */
+#ifdef POSIX_SIGNALS
+static sigset_t sset;
+#else
+#ifndef SYSV
+static int omask;
+#endif
+#endif /* POSIX_SIGNALS */
+
+void holdsigchld()
+{
+#ifdef POSIX_SIGNALS
+ sigemptyset(&sset);
+ sigaddset(&sset,SIGCHLD);
+ sigprocmask(SIG_BLOCK,&sset,NULL);
+#else /* POSIX_SIGNALS */
+#ifndef SYSV
+ omask = sigblock(sigmask(SIGCHLD));
+#else /* SYSV */
+ /* XXX - out of luck? */
+#endif /* SYSV */
+#endif /* POSIX_SIGNALS */
+}
+
+void releasesigchld()
+{
+#ifdef POSIX_SIGNALS
+ sigprocmask(SIG_UNBLOCK,&sset,NULL);
+#else
+#ifndef SYSV
+ (void) sigsetmask(omask);
+#endif
+#endif /* POSIX_SIGNALS */
+}
+
+ /* State of all running zone transfers */
+static struct {
+ pid_t xfer_pid;
+ int xfer_state; /* see below */
+#ifdef sequent
+ union wait xfer_status;
+#else
+ int xfer_status;
+#endif
+} xferstatus[MAX_XFERS_RUNNING];
+#define XFER_IDLE 0
+#define XFER_RUNNING 1
+#define XFER_DONE 2
+
+/*
+ * 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, i;
+ 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++] = _PATH_XFER;
+ argv[argc++] = "-z";
+ argv[argc++] = zp->z_origin;
+ argv[argc++] = "-f";
+ argv[argc++] = zp->z_source;
+ argv[argc++] = "-s";
+ sprintf(serial_str, "%lu", (u_long)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_NOTICE,
+ "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
+ if (debug) {
+ for (i = 0; i < argc; i++)
+ fprintf(ddt, " %s", argv[i]);
+ fprintf(ddt, "\n");
+ }
+#endif /* DEBUG */
+
+ gettime(&tt);
+ holdsigchld();
+ for (i = 0; i < MAX_XFERS_RUNNING; i++) {
+ if (xferstatus[i].xfer_pid == 0) {
+ xferstatus[i].xfer_state = XFER_RUNNING;
+ break;
+ }
+ }
+ if ((pid = vfork()) == -1) {
+ syslog(LOG_ERR, "xfer vfork: %m");
+ releasesigchld();
+ 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. */
+ xferstatus[i].xfer_pid = pid; /* XXX - small race condition here if we
+ * can't hold signals */
+ 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;
+ releasesigchld();
+}
+
+const char *
+zoneTypeString(zp)
+ const struct zoneinfo *zp;
+{
+ static char ret[sizeof "(4294967296?)"]; /* 2^32 */
+
+ switch (zp->z_type) {
+ case Z_PRIMARY: return ("primary");
+ case Z_SECONDARY: return ("secondary");
+#ifdef STUBS
+ case Z_STUB: return ("stub");
+#endif
+ case Z_CACHE: return ("cache");
+ default:
+ sprintf(ret, "(%lu?)", (u_long)zp->z_type);
+ return (ret);
+ }
+}
+
+#ifdef DEBUG
+void
+printzoneinfo(zonenum)
+ int zonenum;
+{
+ struct timeval tt;
+ struct zoneinfo *zp = &zones[zonenum];
+
+ if (!debug)
+ return;
+
+ if (!zp->z_origin)
+ return;
+
+ fprintf(ddt, "printzoneinfo(%d):\n", zonenum);
+
+ gettime(&tt);
+ fprintf(ddt, "origin ='%s'", zp->z_origin[0] ? zp->z_origin : ".");
+#ifdef GEN_AXFR
+ fprintf(ddt, ", class = %d", zp->z_class);
+#endif
+ fprintf(ddt, ", type = %s", zoneTypeString(zp));
+ if (zp->z_source)
+ fprintf(ddt,", source = %s\n", zp->z_source);
+ fprintf(ddt, "z_refresh = %lu", (u_long)zp->z_refresh);
+ fprintf(ddt, ", retry = %lu", (u_long)zp->z_retry);
+ fprintf(ddt, ", expire = %lu", (u_long)zp->z_expire);
+ fprintf(ddt, ", minimum = %lu", (u_long)zp->z_minimum);
+ fprintf(ddt, ", serial = %lu\n", (u_long)zp->z_serial);
+ fprintf(ddt, "z_time = %lu", (u_long)zp->z_time);
+ if (zp->z_time) {
+ fprintf(ddt, ", now time : %lu sec", (u_long)tt.tv_sec);
+ fprintf(ddt, ", time left: %lu sec",
+ (u_long)(zp->z_time - tt.tv_sec));
+ }
+ fprintf(ddt, "; flags %lx\n", (u_long)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; NULL) {
+ if (dp->d_zone == zone
+#ifdef CLEANCACHE
+ && (all || stale(dp))
+#endif
+ ) {
+ dp = rm_datum(dp, np, pdp);
+ } else {
+ pdp = dp;
+ dp = dp->d_next;
+ }
+ } /*for(pdp)*/
+
+ if (np->n_hash) {
+ /* call recursively to remove subdomains. */
+ remove_zone(np->n_hash, zone
+#ifdef CLEANCACHE
+ , all
+#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;
+ }
+ } /*for(pnp)*/
+ } /*for(npp)*/
+}
+
+#ifdef PURGE_ZONE
+static void purge_z_2 __P((struct hashbuf *, int));
+static bottom_of_zone __P((struct databuf *, int));
+
+void
+purge_zone(dname, htp, class)
+ const char *dname;
+ register struct hashbuf *htp;
+ int class;
+{
+ const char *fname;
+ struct databuf *dp, *pdp;
+ struct namebuf *np;
+ struct hashbuf *phtp = htp;
+
+ dprintf(1, (ddt, "purge_zone(%s,%d)\n", dname, class));
+ if ((np = nlookup(dname, &phtp, &fname, 0)) && dname == fname &&
+ !ns_wildcard(NAME(*np))) {
+ for (pdp = NULL, dp = np->n_data; dp != NULL; ) {
+ if (dp->d_class == class)
+ dp = rm_datum(dp, np, pdp);
+ else {
+ pdp = dp;
+ dp = dp->d_next;
+ }
+ }
+
+ if (np->n_hash) {
+ purge_z_2(np->n_hash, class);
+ if (np->n_hash->h_cnt == 0) {
+ free((char*)np->n_hash);
+ np->n_hash = NULL;
+ }
+ }
+
+ /* remove entry from cache, if required */
+ if ((np->n_hash == NULL) && (np->n_data == NULL)) {
+ struct namebuf **npp, **nppend;
+ struct namebuf *npn, *pnp, *nnp;
+
+ dprintf(3,(ddt, "purge_zone: cleaning cache\n"));
+
+ /* walk parent hashtable looking for ourself */
+ if (np->n_parent)
+ phtp = np->n_parent->n_hash;
+ else
+ phtp = htp; /* top / root zone */
+
+ if (phtp) {
+ nppend = phtp->h_tab + phtp->h_size;
+ for (npp = phtp->h_tab; npp < nppend; npp++) {
+ for (pnp = NULL, nnp = *npp;
+ nnp != NULL;
+ nnp = npn) {
+ if (nnp == np) {
+ dprintf(3, (ddt,
+ "purge_zone: found our selves\n"
+ ));
+ npn = rm_name(nnp,npp,pnp);
+ phtp->h_cnt--;
+ } else {
+ npn = nnp->n_next;
+ pnp = nnp;
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+static void
+purge_z_2(htp, class)
+ register struct hashbuf *htp;
+ register int class;
+{
+ register struct databuf *dp, *pdp;
+ register struct namebuf *np, *pnp, *npn;
+ struct namebuf **npp, **nppend;
+
+ nppend = htp->h_tab + htp->h_size;
+ for (npp = htp->h_tab; npp < nppend; npp++) {
+ for (pnp = NULL, np = *npp; np != NULL; np = npn) {
+ if (!bottom_of_zone(np->n_data, class)) {
+ for (pdp = NULL, dp = np->n_data; dp != NULL; ) {
+ if (dp->d_class == class)
+ dp = rm_datum(dp, np, pdp);
+ else {
+ pdp = dp;
+ dp = dp->d_next;
+ }
+ }
+ if (np->n_hash) {
+ /* call recursively to rm subdomains */
+ purge_z_2(np->n_hash, class);
+
+ /* if now empty, free it */
+ if (np->n_hash->h_cnt == 0) {
+ free((char*)np->n_hash);
+ np->n_hash = NULL;
+ }
+ }
+ }
+
+ if ((np->n_hash == NULL) && (np->n_data == NULL)) {
+ npn = rm_name(np, npp, pnp);
+ htp->h_cnt--;
+ } else {
+ npn = np->n_next;
+ pnp = np;
+ }
+ }
+ }
+}
+
+static int
+bottom_of_zone(dp, class)
+ struct databuf *dp;
+ int class;
+{
+ for ( ; dp ; dp = dp->d_next) {
+ if (dp->d_class != class)
+ continue;
+ if (dp->d_zone == 0)
+ continue;
+#ifdef NCACHE
+ if (dp->d_rcode) /* this should not occur */
+ continue;
+#endif
+ if (dp->d_type == T_SOA)
+ return (1);
+ }
+ dprintf(3, (ddt, "bottom_of_zone() == 0\n"));
+ return (0);
+}
+#endif
+
+/*
+ * Handle XFER limit for a nameserver.
+ */
+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;
+{
+ if (zp->z_flags & (Z_XFER_GONE|Z_XFER_ABORTED)) {
+ int i;
+
+ for (i = 0; i < MAX_XFERS_RUNNING; i++) {
+ if (xferstatus[i].xfer_pid == zp->z_xferpid) {
+ xferstatus[i].xfer_pid = 0;
+ xferstatus[i].xfer_state = XFER_IDLE;
+ break;
+ }
+ }
+
+ if (zp->z_flags & Z_XFER_GONE)
+ syslog(LOG_WARNING,
+ "zone transfer timeout for \"%s\"; pid %lu missing",
+ zp->z_origin, (u_long)zp->z_xferpid);
+ else if (kill(zp->z_xferpid, SIGKILL) == -1)
+ syslog(LOG_WARNING,
+ "zone transfer timeout for \"%s\"; kill pid %lu: %m",
+ zp->z_origin, (u_long)zp->z_xferpid);
+ else
+ syslog(LOG_WARNING,
+"zone transfer timeout for \"%s\"; second kill\
+pid %lu - forgetting, processes may accumulate",
+ zp->z_origin, (u_long)zp->z_xferpid);
+
+ zp->z_xferpid = 0;
+ xfers_running--;
+ (void)nxfers(zp, -1);
+ zp->z_flags &= ~(Z_XFER_RUNNING|Z_XFER_ABORTED|Z_XFER_GONE);
+ } else if (kill(zp->z_xferpid, SIGKILL) == -1) {
+ if (errno == ESRCH)
+ /* No warning on first time, it may have just exited */
+ zp->z_flags |= Z_XFER_GONE;
+ else {
+ syslog(LOG_WARNING,
+ "zone transfer timeout for \"%s\"; pid %lu kill failed %m",
+ zp->z_origin, (u_long)zp->z_xferpid);
+ zp->z_flags |= Z_XFER_ABORTED;
+ }
+ } else {
+ syslog(LOG_NOTICE,
+ "zone transfer timeout for \"%s\"; pid %lu killed",
+ zp->z_origin, (u_long)zp->z_xferpid);
+ zp->z_flags |= Z_XFER_ABORTED;
+ }
+}
+
+/*
+ * SIGCHLD signal handler: process exit of xfer's.
+ * (Note: also called when outgoing transfer completes.)
+ */
+SIG_FN
+reapchild()
+{
+ int pid, i, save_errno;
+#if defined(sequent)
+ union wait status;
+#else
+ int status;
+#endif /* sequent */
+
+#if defined(MUST_REARM_SIGS)
+ (void)signal(SIGCLD, (SIG_FN (*)()) reapchild);
+#endif
+ save_errno = errno;
+ gettime(&tt);
+#if defined(USE_WAITPID)
+ while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
+#else /* USE_WAITPID */
+ {
+ pid = wait(&status);
+#endif /* USE_WAITPID */
+ for (i = 0; i < MAX_XFERS_RUNNING; i++) {
+ if (xferstatus[i].xfer_pid == pid) {
+ xferstatus[i].xfer_status = status;
+ xferstatus[i].xfer_state = XFER_DONE;
+ needendxfer++;
+ break;
+ }
+ }
+ }
+ errno = save_errno;
+}
+
+/*
+ * Finish processing of of finished xfers
+ */
+void
+endxfer()
+{
+ register struct zoneinfo *zp;
+ int exitstatus, pid, i;
+#if defined(sequent)
+ union wait status;
+#else
+ int status;
+#endif /* sequent */
+
+ gettime(&tt);
+
+ for (i = 0; i < MAX_XFERS_RUNNING; i++) {
+ if (xferstatus[i].xfer_state != XFER_DONE)
+ continue;
+ pid = xferstatus[i].xfer_pid;
+ status = xferstatus[i].xfer_status;
+ exitstatus = WIFEXITED(status) ?WEXITSTATUS(status) :0;
+
+ for (zp = zones; zp < &zones[nzones]; zp++) {
+ if (zp->z_xferpid != pid)
+ continue;
+ xfers_running--;
+ (void) nxfers(zp, -1);
+ zp->z_xferpid = 0;
+ zp->z_flags &=
+ ~(Z_XFER_RUNNING|Z_XFER_ABORTED|Z_XFER_GONE);
+ 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));
+ }
+ ns_retrytime(zp, tt.tv_sec);
+ } else {
+ switch (exitstatus) {
+ case XFER_UPTODATE:
+ markUpToDate(zp);
+ break;
+
+ case XFER_SUCCESS:
+ /* XXX should incorporate loadxfer() */
+ zp->z_flags |= Z_NEED_RELOAD;
+ zp->z_flags &= ~Z_SYSLOGGED;
+ needzoneload++;
+ break;
+
+ case XFER_TIMEOUT:
+ if (!(zp->z_flags & Z_SYSLOGGED)) {
+ zp->z_flags |= Z_SYSLOGGED;
+ syslog(LOG_NOTICE,
+ "zoneref: Masters for secondary zone \"%s\" unreachable",
+ zp->z_origin);
+ }
+ ns_retrytime(zp, tt.tv_sec);
+ break;
+
+ default:
+ if (!(zp->z_flags & Z_SYSLOGGED)) {
+ zp->z_flags |= Z_SYSLOGGED;
+ syslog(LOG_NOTICE,
+ "named-xfer for \"%s\" exited %d",
+ zp->z_origin,
+ exitstatus);
+ }
+ /* FALLTHROUGH */
+ case XFER_FAIL:
+ zp->z_flags |= Z_SYSLOGGED;
+ ns_retrytime(zp, tt.tv_sec);
+ break;
+ }
+ break;
+ }
+ }
+ xferstatus[i].xfer_state = XFER_IDLE;
+ xferstatus[i].xfer_pid = 0;
+ }
+ releasesigchld();
+ tryxfer();
+}
+
+/*
+ * Try to start some xfers - new "fair scheduler" by Bob Heiney @DEC (1995)
+ */
+static void
+tryxfer() {
+ static struct zoneinfo *zp = NULL;
+ static struct zoneinfo *lastzones = NULL;
+ static int lastnzones = 0;
+ struct zoneinfo *startzp, *stopzp;
+
+ /* initialize, and watch out for changes in zones! */
+ if (lastzones != zones) {
+ if (lastzones != NULL)
+ syslog(LOG_INFO, "zones changed: %p != %p",
+ lastzones, zones);
+ lastzones = zones;
+ zp = zones;
+ }
+
+ /* did zones shrink? */
+ if (lastnzones > nzones) {
+ syslog(LOG_INFO, "zones shrunk");
+ zp = zones;
+ }
+ lastnzones = nzones;
+
+ if (zp == zones)
+ stopzp = &zones[nzones-1];
+ else
+ stopzp = zp - 1;
+
+ dprintf(3, (ddt, "tryxfer start zp=%p stopzp=%p def=%d running=%d\n",
+ zp, stopzp, xfers_deferred, xfers_running));
+
+ startzp = zp;
+ for (;;) {
+ int xfers;
+
+ if (!xfers_deferred || xfers_running >= max_xfers_running)
+ break;
+
+ if ((xfers = nxfers(zp, 0)) != -1 &&
+ xfers < max_xfers_per_ns &&
+ (zp->z_flags & Z_NEED_XFER)) {
+ nxfers(zp, 1);
+ xfers_deferred--;
+ startxfer(zp);
+ }
+
+ if (zp == stopzp) {
+ dprintf(3, (ddt, "tryxfer stop mark\n"));
+ zp = startzp;
+ break;
+ }
+
+ zp++;
+ /* wrap around? */
+ if (zp == &zones[nzones])
+ zp = zones;
+ }
+ dprintf(3, (ddt, "tryxfer stop zp=%p\n", zp));
+
+ if (!needmaint)
+ sched_maint();
+}
+
+/*
+ * 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);
+ remove_zone(hashtab, zp - zones
+#ifdef CLEANCACHE
+ , 1
+#endif
+ );
+#ifdef PURGE_ZONE
+ purge_zone(zp->z_origin, hashtab, zp->z_class);
+#endif
+ if (!db_load(zp->z_source, zp->z_origin, zp, NULL))
+ zp->z_flags |= Z_AUTH;
+ if (zp->z_flags & Z_TMP_FILE)
+ (void) unlink(zp->z_source);
+ }
+ }
+ 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/contrib/bind/named/ns_ncache.c b/contrib/bind/named/ns_ncache.c
new file mode 100644
index 0000000..eb8faaf
--- /dev/null
+++ b/contrib/bind/named/ns_ncache.c
@@ -0,0 +1,154 @@
+/**************************************************************************
+ * ns_ncache.c
+ * author: anant kumar
+ * last modification: March 17, 1993
+ *
+ * implements negative caching
+ */
+
+#include <sys/types.h>
+#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, 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: [%s %s %s] rcode:%d ttl:%ld\n",
+ dname, p_type(type), p_class(class),
+ dp->d_rcode, (long)(dp->d_ttl-tt.tv_sec)));
+ return;
+}
+
+#endif /*NCACHE*/
diff --git a/contrib/bind/named/ns_req.c b/contrib/bind/named/ns_req.c
new file mode 100644
index 0000000..c485f59
--- /dev/null
+++ b/contrib/bind/named/ns_req.c
@@ -0,0 +1,2179 @@
+#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 8.20 1996/08/05 08:31:30 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/types.h>
+#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 */
+ char *a_rname; /* referred by */
+ u_int16_t a_rtype; /* referred by */
+ u_int16_t a_class; /* class for address */
+};
+
+enum req_action { Finish, Refuse, Return };
+
+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));
+
+static enum req_action req_iquery __P((HEADER *hp, u_char **cpp, u_char *eom,
+ int *buflenp, u_char *msg,
+ struct sockaddr_in *from));
+
+#ifdef BIND_NOTIFY
+static enum req_action req_notify __P((HEADER *hp, u_char **cpp, u_char *eom,
+ u_char *msg,struct sockaddr_in *from));
+#endif
+
+static void fwritemsg __P((FILE *, u_char *, int)),
+#ifdef DEBUG
+ printSOAdata __P((struct databuf)),
+#endif
+ doaxfr __P((struct namebuf *, FILE *,
+ struct namebuf *, int)),
+ startxfr __P((struct qstream *, struct namebuf *,
+ u_char *, int, int, const char *));
+
+#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((const char *, const char *,
+ u_int16_t, 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;
+#ifdef DEBUG
+ const char *sortmsgtxt;
+#endif
+ enum req_action action;
+ int n;
+
+#ifdef DEBUG
+ if (debug > 3) {
+ fprintf(ddt, "ns_req(from=%s)\n", sin_ntoa(from));
+ fp_nquery(msg, msglen, 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;
+ }
+
+ /* it's not a response so these bits have no business
+ * being set. will later simplify work if we can
+ * safely assume these are always 0 when a query
+ * comes in.
+ */
+ hp->aa = hp->ra = 0;
+
+ hp->rcode = NOERROR;
+ cp = msg + HFIXEDSZ;
+ eom = msg + msglen;
+ buflen -= HFIXEDSZ;
+
+ 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;
+
+ case IQUERY:
+ action = req_iquery(hp, &cp, eom, &buflen, msg, from);
+ break;
+
+#ifdef BIND_NOTIFY
+ case NS_NOTIFY_OP:
+ action = req_notify(hp, &cp, eom, msg, from);
+ break;
+#endif
+
+#ifdef ALLOW_UPDATES
+#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;
+ }
+
+ case ZONEREF:
+ dprintf(1, (ddt, "Refresh Zone\n"));
+ /*FALLTHROUGH*/
+#endif /* ALLOW_UPDATES */
+
+ default:
+ dprintf(1, (ddt, "ns_req: Opcode %d not implemented\n",
+ hp->opcode));
+ /* XXX - should syslog, limited by haveComplained */
+ hp->qdcount = htons(0);
+ hp->ancount = htons(0);
+ hp->nscount = htons(0);
+ hp->arcount = htons(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:
+ panic(-1, "ns_req: bad action variable");
+ /*NOTREACHED*/
+ }
+
+ /*
+ * apply final polish
+ */
+ hp->qr = 1; /* set Response flag */
+ hp->ra = (NoRecurse == 0);
+
+ n = doaddinfo(hp, cp, buflen);
+ cp += n;
+ buflen -= n;
+
+#ifdef DEBUG
+#ifdef SORT_RESPONSE
+ sortmsgtxt = local(from) == NULL ? "Remote" : "Local";
+#else /*SORT*/
+ sortmsgtxt = "(not sorting)";
+#endif /*SORT*/
+ dprintf(1, (ddt, "ns_req: answer -> %s fd=%d id=%d size=%d %s\n",
+ sin_ntoa(from), (qsp == QSTREAM_NULL) ? dfd : qsp->s_rfd,
+ ntohs(hp->id), cp - msg, sortmsgtxt));
+ if (debug >= 10)
+ fp_nquery(msg, cp - msg, ddt);
+#endif /*DEBUG*/
+ if (qsp == QSTREAM_NULL) {
+ if (sendto(dfd, (char*)msg, cp - msg, 0,
+ (struct sockaddr *)from,
+ sizeof(*from)) < 0) {
+ if (!haveComplained((char*)from->sin_addr.s_addr,
+ sendtoStr))
+ syslog(LOG_INFO,
+ "ns_req: sendto(%s): %m",
+ sin_ntoa(from));
+ nameserIncr(from->sin_addr, nssSendtoErr);
+ }
+ nameserIncr(from->sin_addr, nssSentAns);
+#ifdef XSTATS
+ if (hp->rcode == NXDOMAIN)
+ nameserIncr(from->sin_addr, nssSentNXD);
+ if (!hp->aa)
+ nameserIncr(from->sin_addr, nssSentNaAns);
+#endif
+ } else {
+ (void) writemsg(qsp->s_rfd, msg, cp - msg);
+ sq_done(qsp);
+ }
+
+ if (needs_prime_cache) {
+ prime_cache(); /* Now is a safe time */
+ }
+}
+
+#ifdef BIND_NOTIFY
+int
+findZonePri(zp, from)
+ register const struct zoneinfo *zp;
+ const struct sockaddr_in *from;
+{
+ register u_int32_t from_addr = from->sin_addr.s_addr;
+ register int i;
+
+ for (i = 0; (u_int)i < zp->z_addrcnt; i++)
+ if (zp->z_addr[i].s_addr == from_addr)
+ return (i);
+ return (-1);
+}
+
+static enum req_action
+req_notify(hp, cpp, eom, msg, from)
+ HEADER *hp;
+ u_char **cpp, *eom, *msg;
+ struct sockaddr_in *from;
+{
+ int n, type, class, zn;
+ char dnbuf[MAXDNAME];
+ struct namebuf *np;
+ const char *fname;
+ struct hashbuf *htp = hashtab; /* lookup relative to root */
+
+ /* valid notify's have one question and zero answers */
+ if ((ntohs(hp->qdcount) != 1)
+ || ntohs(hp->ancount) != 0
+ || ntohs(hp->nscount) != 0
+ || ntohs(hp->arcount) != 0) {
+ dprintf(1, (ddt, "FORMERR Notify header counts wrong\n"));
+ hp->qdcount = htons(0);
+ hp->ancount = htons(0);
+ hp->nscount = htons(0);
+ hp->arcount = htons(0);
+ hp->rcode = FORMERR;
+ return (Finish);
+ }
+
+ n = dn_expand(msg, eom, *cpp, dnbuf, sizeof dnbuf);
+ if (n < 0) {
+ dprintf(1, (ddt, "FORMERR Query expand name failed\n"));
+ hp->rcode = FORMERR;
+ return (Finish);
+ }
+ *cpp += n;
+ GETSHORT(type, *cpp);
+ GETSHORT(class, *cpp);
+ syslog(LOG_INFO, "rcvd NOTIFY(%s %s %s)",
+ dnbuf, p_class(class), p_type(type));
+ /* XXX - when answers are allowed, we'll need to do compression
+ * correctly here, and we will need to check for packet underflow.
+ */
+ np = nlookup(dnbuf, &htp, &fname, 0);
+ if (!np) {
+ syslog(LOG_INFO, "rcvd NOTIFY for \"%s\", name not in cache",
+ dnbuf);
+ hp->rcode = SERVFAIL;
+ return (Finish);
+ }
+ zn = findMyZone(np, class);
+ if (zn == DB_Z_CACHE || zones[zn].z_type != Z_SECONDARY) {
+ /* this can come if a user did an AXFR of some zone somewhere
+ * and that zone's server now wants to tell us that the SOA
+ * has changed. AXFR's always come from nonpriv ports so it
+ * isn't possible to know whether it was the server or just
+ * "dig". this condition can be avoided by using secure zones
+ * since that way only real secondaries can AXFR from you.
+ */
+ syslog(LOG_INFO,
+ "NOTIFY for non-secondary name (%s), from %s",
+ dnbuf, sin_ntoa(from));
+ goto refuse;
+ }
+ if (findZonePri(&zones[zn], from) == -1) {
+ syslog(LOG_INFO,
+ "NOTIFY from non-master server (zone %s), from %s",
+ zones[zn].z_origin, sin_ntoa(from));
+ goto refuse;
+ }
+ switch (type) {
+ case T_SOA:
+ if (strcasecmp(dnbuf, zones[zn].z_origin) != 0) {
+ syslog(LOG_INFO,
+ "NOTIFY(SOA) for non-origin (%s), from %s",
+ dnbuf, sin_ntoa(from));
+ goto refuse;
+ }
+ if (zones[zn].z_flags &
+ (Z_NEED_RELOAD|Z_NEED_XFER|Z_QSERIAL|Z_XFER_RUNNING)) {
+ syslog(LOG_INFO,
+ "NOTIFY(SOA) for zone already xferring (%s)",
+ dnbuf);
+ goto noerror;
+ }
+ zones[zn].z_time = tt.tv_sec;
+ qserial_query(&zones[zn]);
+ /* XXX: qserial_query() can fail due to queue full condition;
+ * we should detect that case here and do something.
+ */
+ break;
+ default:
+ /* unimplemented, but it's not a protocol error, just
+ * something to be ignored.
+ */
+ break;
+ }
+ noerror:
+ hp->rcode = NOERROR;
+ return (Finish);
+ refuse:
+ hp->rcode = REFUSED;
+ return (Finish);
+}
+#endif /*BIND_NOTIFY*/
+
+static enum req_action
+req_query(hp, cpp, eom, qsp, buflenp, msglenp, msg, dfd, from)
+ HEADER *hp;
+ 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;
+ const char *fname;
+ struct hashbuf *htp;
+ struct databuf *nsp[NSMAX];
+ struct namebuf *np, *anp;
+ struct qinfo *qp;
+ struct netinfo *lp;
+#ifdef SECURE_ZONES
+ struct zoneinfo *zp;
+#endif
+ struct databuf *dp;
+
+#ifdef XSTATS
+ nameserIncr(from->sin_addr, nssRcvdQ);
+#endif
+
+#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)
+ || ntohs(hp->ancount) != 0
+ || ntohs(hp->nscount) != 0
+ || ntohs(hp->arcount) != 0) {
+ dprintf(1, (ddt, "FORMERR Query header counts wrong\n"));
+ hp->qdcount = htons(0);
+ hp->ancount = htons(0);
+ hp->nscount = htons(0);
+ hp->arcount = htons(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 for \"%s\"",
+ sin_ntoa(from), *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 for %s",
+ sin_ntoa(from), *dnbuf ? dnbuf : ".");
+ return (Refuse);
+ }
+ }
+#endif /*XFRNETS*/
+ dnptrs[0] = NULL; /* don't compress names */
+ hp->rd = 0; /* recursion not possible */
+ syslog(LOG_INFO, "approved AXFR from %s for \"%s\"",
+ sin_ntoa(from), *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 class=%d\n",
+ dname, ntohs(hp->id), type, class));
+ htp = hashtab; /* lookup relative to root */
+ if ((anp = np = nlookup(dname, &htp, &fname, 0)) == NULL)
+ fname = "";
+ dprintf(1, (ddt, "req: %s '%s' as '%s' (cname=%d)\n",
+ np == NULL ? "missed" : "found",
+ 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
+ /* (gdmr) Make sure the class is correct. If we have the same name
+ * with more than one class then we can't refuse a request for one
+ * class just because another class is blocked. We *really* ought
+ * to look for the correct type too, but since everything in a
+ * particular class of zone has the same secure_zone attribute it
+ * doesn't really matter which type we use! Alternatively, this lot
+ * could all be moved to after the finddata(), by which time only
+ * the correct class/type combinations will be left.
+ */
+ dp = np->n_data;
+ while (dp && (dp->d_class != class))
+ dp = dp->d_next;
+ if (dp) {
+ zp = &zones[dp->d_zone];
+ if (zp->secure_nets
+ && !addr_on_netlist(from->sin_addr, zp->secure_nets)) {
+ syslog(LOG_NOTICE, "Unauthorized request %s from %s",
+ dname, sin_ntoa(from));
+ dprintf(1, (ddt, "req: refuse %s from %s class %d (%d)\n",
+ dname, sin_ntoa(from), class, zp->z_class));
+ return (Refuse);
+ }
+ }
+#endif
+ foundname++;
+ answers = *cpp;
+ count = *cpp - msg;
+
+#ifdef NCACHE
+ /* Look for NXDOMAIN record with appropriate class
+ * if found return immediately
+ */
+ for (dp = np->n_data; dp ; dp = dp->d_next) {
+ if (!stale(dp) && (dp->d_rcode == NXDOMAIN) &&
+ (dp->d_class == class)) {
+#ifdef RETURNSOA
+ n = finddata(np, class, T_SOA, hp, &dname,
+ buflenp, &count);
+ if (n != 0 ) {
+ if (hp->rcode == NOERROR_NODATA) {
+ /* this should not occur */
+ hp->rcode = NOERROR;
+ return (Finish);
+ }
+ *cpp += n;
+ *buflenp -= n;
+ *msglenp += n;
+ hp->nscount = htons((u_int16_t)count);
+ }
+#endif
+ hp->rcode = NXDOMAIN;
+ hp->aa = 1;
+ return (Finish);
+ }
+ }
+
+ /* 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 = htons(ntohs(hp->ancount) + (u_int16_t)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));
+
+#ifdef SORT_RESPONSE
+ if ((lp = local(from)) != NULL)
+ sort_response(answers, count, lp, *cpp);
+#endif
+#ifdef BIND_NOTIFY
+ if (type == T_SOA &&
+ from->sin_port == ns_port &&
+ np->n_data) {
+ int zn = np->n_data->d_zone;
+
+ if (zn != DB_Z_CACHE) {
+ struct notify *ap;
+
+ /* Old? */
+ ap = findNotifyPeer(&zones[zn], from->sin_addr);
+ /* New? */
+ if (!ap && (ap = (struct notify *)malloc(sizeof *ap))) {
+ ap->addr = from->sin_addr;
+ ap->next = zones[zn].z_notifylist;
+ zones[zn].z_notifylist = ap;
+ }
+ /* Old or New? */
+ if (ap)
+ ap->last = tt.tv_sec;
+ }
+ }
+#endif /*BIND_NOTIFY*/
+ if (type == T_AXFR) {
+ startxfr(qsp, np, msg, *cpp - msg, class, dname);
+ return (Return);
+ }
+
+#ifdef notdef
+ /*
+ * If we found an authoritative answer, we're done.
+ */
+ if (hp->aa)
+ return (Finish);
+#endif
+
+fetchns:
+ /*
+ * If we're already out of room in the response, we're done.
+ */
+ if (hp->tc)
+ return (Finish);
+
+ /*
+ * 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:
+ /* We are authoritative for this np. */
+ 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 (ntohs(hp->ancount) != 0) {
+ /* don't add NS records for NOERROR NODATA
+ as some servers can get confused */
+#ifdef DATUMREFCNT
+ free_nsp(nsp);
+#endif
+ switch (findns(&np, class, nsp, &count, 1)) {
+ case NXDOMAIN:
+ case SERVFAIL:
+ break;
+ default:
+ if (np &&
+ (type != T_NS || np != anp)
+ ) {
+ n = add_data(np, nsp, *cpp,
+ *buflenp, &count);
+ 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:
+ /* We're authoritative but the zone isn't loaded. */
+ 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) {
+ /*
+ * If the qtype was NS, and the np of the authority is
+ * the same as the np of the data, we don't need to add
+ * another copy of the answer here in the authority
+ * section.
+ */
+ if (!founddata || type != T_NS || anp != np) {
+ n = add_data(np, nsp, *cpp, *buflenp, &count);
+ 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
+ /* Our caller will handle the Additional section. */
+ 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) {
+ syslog(LOG_INFO, "ns_req: Out Of Memory");
+ hp->rcode = SERVFAIL;
+#ifdef DATUMREFCNT
+ free_nsp(nsp);
+#endif
+ return (Finish);
+ }
+ id = hp->id;
+ omsglen = *msglenp;
+ bcopy(msg, omsg, omsglen);
+ n = res_mkquery(QUERY, dname, class, type,
+ NULL, 0, NULL, msg,
+ *msglenp + *buflenp);
+ if (n < 0) {
+ syslog(LOG_INFO, "res_mkquery(%s) failed", dname);
+ hp->rcode = SERVFAIL;
+#ifdef DATUMREFCNT
+ free_nsp(nsp);
+#endif
+ return (Finish);
+ }
+ *msglenp = n;
+ }
+ n = ns_forw(nsp, msg, *msglenp, from, qsp, dfd, &qp, dname, np);
+ if (n != FW_OK && cname)
+ 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 (NAME(*np)[0] == '\0') {
+ syslog(LOG_NOTICE,
+ "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
+ for (dp = np->n_data; dp ; dp = dp->d_next)
+ if (dp->d_zone && match(dp, class, T_NS))
+ break;
+ if (dp) {
+ /*
+ * we know the child zone exists but are
+ * missing glue.
+ *
+ * nslookup has called sysquery() to get the
+ * missing glue.
+ *
+ * for UDP, drop the response and let the
+ * client retry. for TCP, we should probably
+ * (XXX) hold open the TCP connection for a
+ * while in case the sysquery() comes back
+ * soon. meanwhile we SERVFAIL.
+ */
+ if (qsp)
+ goto do_servfail;
+ break;
+ }
+ np = np_parent(np);
+ }
+ goto fetchns; /* Try again. */
+ case FW_SERVFAIL:
+ do_servfail:
+ hp->rcode = SERVFAIL;
+#ifdef DATUMREFCNT
+ free_nsp(nsp);
+#endif
+ return (Finish);
+ }
+#ifdef DATUMREFCNT
+ free_nsp(nsp);
+#endif
+ return (Return);
+}
+
+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;
+{
+ int dlen, alen, n, type, class, count;
+ char dnbuf[MAXDNAME], anbuf[PACKETSZ], *data, *fname;
+
+#ifdef XSTATS
+ nameserIncr(from->sin_addr, nssRcvdIQ);
+#endif
+
+ if (ntohs(hp->ancount) != 1
+ || ntohs(hp->qdcount) != 0
+ || ntohs(hp->nscount) != 0
+ || ntohs(hp->arcount) != 0) {
+ dprintf(1, (ddt, "FORMERR IQuery header counts wrong\n"));
+ hp->qdcount = htons(0);
+ hp->ancount = htons(0);
+ hp->nscount = htons(0);
+ hp->arcount = htons(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:
+#ifndef INVQ
+ if (!fake_iquery)
+ return (Refuse);
+#endif
+#ifdef INVQ
+ case T_UID:
+ case T_GID:
+#endif
+ 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;
+
+#ifdef QRYLOG
+ if (qrylog) {
+ syslog(LOG_INFO, "XX /%s/%s/-%s",
+ inet_ntoa(from->sin_addr),
+ inet_ntoa(data_inaddr((u_char *)data)),
+ p_type(type));
+ }
+#endif /*QRYLOG*/
+
+#ifdef INVQ
+ {
+ register struct invbuf *ip;
+
+ for (ip = invtab[dhash((u_char *)data, dlen)];
+ ip != NULL;
+ ip = ip->i_next) {
+ int i;
+
+ for (i = 0; i < INVBLKSZ; i++) {
+ struct namebuf *np;
+ struct databuf *dp;
+
+ if ((np = ip->i_dname[i]) == NULL)
+ break;
+ dprintf(5, (ddt, "dname = %d\n", NAME(*np)));
+ 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++;
+ }
+ }
+ }
+ }
+#else /*INVQ*/
+ /*
+ * We can only get here if we are compiled without INVQ (the default)
+ * and the type is T_A and the option "fake-iquery" is on in the boot
+ * file.
+ *
+ * What we do here is send back a bogus response of "[dottedquad]".
+ * A better strategy would be to turn this into a PTR query, but that
+ * would legitimize inverse queries in a way they do not deserve.
+ */
+ sprintf(dnbuf, "[%s]", inet_ntoa(data_inaddr((u_char *)data)));
+ *buflenp -= QFIXEDSZ;
+ n = dn_comp(dnbuf, *cpp, *buflenp, NULL, NULL);
+ if (n < 0) {
+ hp->tc = 1;
+ return (Finish);
+ }
+ *cpp += n;
+ PUTSHORT((u_int16_t)type, *cpp);
+ PUTSHORT((u_int16_t)class, *cpp);
+ *buflenp -= n;
+ count++;
+#endif /*INVQ*/
+ dprintf(1, (ddt, "req: IQuery %d records\n", count));
+ hp->qdcount = htons((u_int16_t)count);
+ if (alen > *buflenp) {
+ hp->tc = 1;
+ return (Finish);
+ }
+ bcopy(anbuf, *cpp, alen);
+ *cpp += alen;
+ return (Finish);
+}
+
+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) {
+ syslog(LOG_ERR, "fwritemsg: %m");
+ _exit(1);
+ }
+}
+
+/*
+ * 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);
+
+#ifdef STUBS
+ case Z_STUB:
+ /* root stub zones have DB_F_HINT set */
+ if (dp->d_flags & DB_F_HINT)
+ return (0);
+ /* FALLTROUGH */
+#endif
+ case Z_SECONDARY:
+ /*
+ * Check to see whether a secondary zone
+ * has expired; if so clear authority flag
+ * 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_NOTICE,
+ "secondary zone \"%s\" expired",
+ zp->z_origin);
+ }
+ zp->z_flags &= ~Z_AUTH;
+ return (1);
+ }
+ if (zp->z_lastupdate > tt.tv_sec) {
+ if (!haveComplained(zp->z_origin, (char*)stale)) {
+ syslog(LOG_NOTICE,
+ "secondary zone \"%s\" time warp",
+ zp->z_origin);
+ }
+ zp->z_flags &= ~Z_AUTH;
+ return (1);
+ }
+ return (0);
+
+ case Z_CACHE:
+ if (dp->d_flags & DB_F_HINT || dp->d_ttl >= tt.tv_sec)
+ return (0);
+ dprintf(3, (ddt, "stale: ttl %d %ld (x%lx)\n",
+ dp->d_ttl, (long)(dp->d_ttl - tt.tv_sec),
+ (u_long)dp->d_flags));
+ return (1);
+
+ default:
+ /* FALLTHROUGH */ ;
+
+ }
+ panic(-1, "stale: impossible condition");
+ /* 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)
+ const 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 u_int32_t ttl;
+ u_char **edp = dnptrs + sizeof dnptrs / sizeof dnptrs[0];
+
+ dprintf(5, (ddt, "make_rr(%s, %lx, %lx, %d, %d) %d zone %d ttl %lu\n",
+ name, (u_long)dp, (u_long)buf,
+ buflen, doadd, dp->d_size, dp->d_zone, (u_long)dp->d_ttl));
+
+#ifdef NCACHE
+ if (dp->d_rcode
+#ifdef RETURNSOA
+ && dp->d_rcode != NXDOMAIN
+#endif
+ ) {
+ panic(-1, "make_rr: impossible d_rcode value");
+ }
+#endif
+ zp = &zones[dp->d_zone];
+ /* check for outdated RR before updating dnptrs by dn_comp() (?) */
+ if (zp->z_type == Z_CACHE) {
+ if ((dp->d_flags & DB_F_HINT) != 0
+ || dp->d_ttl < (u_int32_t)tt.tv_sec) {
+ ttl = 0;
+ } else
+ ttl = dp->d_ttl - (u_int32_t) tt.tv_sec;
+ } else {
+ if (dp->d_ttl != USE_MINIMUM)
+ 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, name,
+ dp->d_type, 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;
+
+ if ((buflen -= INT16SZ) < 0)
+ return (-1);
+
+ /* copy preference */
+ bcopy(cp1, cp, INT16SZ);
+ cp += INT16SZ;
+ cp1 += INT16SZ;
+
+ n = dn_comp((char *)cp1, cp, buflen, dnptrs, edp);
+ if (n < 0)
+ return (-1);
+ cp += n;
+
+ /* save data length */
+ n = (u_int16_t)((cp - sp) - INT16SZ);
+ PUTSHORT((u_int16_t)n, sp);
+ if (doadd)
+ addname((char*)cp1, name, dp->d_type, dp->d_class);
+ break;
+
+ case T_PX:
+ cp1 = dp->d_data;
+
+ if ((buflen -= INT16SZ) < 0)
+ return (-1);
+
+ /* copy preference */
+ bcopy(cp1, cp, INT16SZ);
+ cp += INT16SZ;
+ cp1 += INT16SZ;
+
+ n = dn_comp((char *)cp1, cp, buflen, dnptrs, edp);
+ if (n < 0)
+ return (-1);
+ cp += n;
+ buflen -= n;
+ cp1 += strlen((char *)cp1) + 1;
+ n = dn_comp((char *)cp1, cp, buflen, dnptrs, edp);
+ if (n < 0)
+ return (-1);
+ cp += n;
+
+ /* save data length */
+ n = (u_int16_t)((cp - sp) - INT16SZ);
+ PUTSHORT((u_int16_t)n, sp);
+ break;
+
+ default:
+ 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 const char *dname,
+ register const char *rname,
+ u_int16_t rtype,
+ u_int16_t class)
+#else
+static void
+addname(dname, rname, rtype, class)
+ register const char *dname;
+ register const char *rname;
+ u_int16_t rtype;
+ u_int16_t class;
+#endif
+{
+ register struct addinfo *ap;
+ register int n;
+
+ for (ap = addinfo, n = addcount; --n >= 0; ap++)
+ if (strcasecmp(ap->a_dname, dname) == 0)
+ return;
+
+ /* add domain name to additional section */
+ if (addcount < NADDRECS) {
+ addcount++;
+ ap->a_dname = savestr(dname);
+ ap->a_rname = savestr(rname);
+ ap->a_rtype = rtype;
+ 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;
+ const char *fname;
+ int n, count;
+
+ if (!addcount)
+ return (0);
+
+ 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,
+ foundcname = 0,
+ save_count = count,
+ save_msglen = msglen;
+ u_char *save_cp = cp;
+
+ dprintf(3, (ddt, "do additional \"%s\" (from \"%s\")\n",
+ ap->a_dname, ap->a_rname));
+ htp = hashtab; /* because "nlookup" stomps on arg. */
+ np = nlookup(ap->a_dname, &htp, &fname, 0);
+ if (np == NULL || fname != ap->a_dname)
+ goto next_rr;
+ dprintf(3, (ddt, "found it\n"));
+ /* look for the data */
+ for (dp = np->n_data; dp != NULL; dp = dp->d_next) {
+#ifdef NCACHE
+ if (dp->d_rcode)
+ continue;
+#endif
+ if (match(dp, (int)ap->a_class, T_CNAME) ||
+ match(dp, C_IN, T_CNAME)) {
+ foundcname++;
+ break;
+ }
+ if (!match(dp, (int)ap->a_class, T_A) &&
+ !match(dp, C_IN, T_A) &&
+ !match(dp, (int)ap->a_class, T_AAAA) &&
+ !match(dp, C_IN, T_AAAA)) {
+ continue;
+ }
+ foundany++;
+ if (stale(dp)) {
+ foundstale++;
+ dprintf(1, (ddt,
+ "doaddinfo: stale entry '%s'%s\n",
+ NAME(*np),
+ (dp->d_flags&DB_F_HINT)
+ ? " hint"
+ : ""
+ ));
+ continue;
+ }
+ /*
+ * 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
+ */
+ dprintf(5, (ddt,
+ "addinfo: not enough room, remaining msglen = %d\n",
+ save_msglen));
+ 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 (!NoFetchGlue && !foundcname && (foundstale || !foundany)) {
+ /* ask a real server for this info */
+ (void) sysquery(ap->a_dname, (int)ap->a_class, T_A,
+ NULL, 0, QUERY);
+ }
+ if (foundcname) {
+ if (!haveComplained((char*)nhash(ap->a_dname),
+ (char*)nhash(ap->a_rname))) {
+ syslog(LOG_DEBUG,
+ "\"%s %s %s\" points to a CNAME (%s)",
+ ap->a_rname, p_class(ap->a_class),
+ p_type(ap->a_rtype), ap->a_dname);
+ }
+ }
+ free(ap->a_dname);
+ free(ap->a_rname);
+ }
+ hp->arcount = htons((u_int16_t)count);
+ return (cp - msg);
+}
+
+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(ntohs(hp->nscount) + 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;
+ const char *fname;
+ char dname[MAXDNAME];
+ HEADER *hp;
+ int fndns;
+
+ if (np == top)
+ dprintf(1, (ddt, "doaxfr()\n"));
+ fndns = 0;
+ bzero((char*)msg, sizeof msg);
+ hp = (HEADER *) msg;
+ hp->opcode = QUERY;
+ hp->qr = 1;
+ hp->rcode = NOERROR;
+ hp->ancount = htons(1);
+ cp = msg + HFIXEDSZ;
+ getname(np, dname, sizeof dname);
+
+ /* first do the NS records (del@harris) */
+ for (dp = np->n_data; dp != NULL; dp = dp->d_next) {
+#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) || (NAME(*top)[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) && (NAME(*top)[0] != '\0') )
+ continue; /* name server is not below top domain */
+ for (tnp = gnp;
+ tnp != NULL && 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) ||
+ ((tnp == NULL) && (NAME(*top)[0] == '\0')))
+ 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 (NAME(*np)[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)) {
+ 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) {
+ syslog(LOG_NOTICE,
+ "InitDynUpdate: Couldn't find SOA RR 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(%#lx): origin(%#lx)='%s'\n",
+ (u_long)dp, (u_long)cp, cp);
+ cp += strlen(cp) + 1; /* skip origin string */
+ fprintf(ddt, "printSOAdata: in-charge(%#lx)='%s'\n",
+ (u_long)cp, cp);
+ cp += strlen(cp) + 1; /* skip in-charge string */
+ fprintf(ddt, "printSOAdata: serial(%lx)=%lu\n",
+ (u_long)cp, (u_long)_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;
+ int pipefd[2];
+ char c;
+#ifdef HAVE_SETVBUF
+ char *buf;
+#endif
+#ifdef SO_SNDBUF
+ static const int sndbuf = XFER_BUFSIZE * 2;
+#endif
+#ifdef SO_LINGER
+ static const struct linger ll = { 1, 120 };
+#endif
+
+ dprintf(5, (ddt, "startxfr()\n"));
+
+ /* create a pipe to synchronize parent and child */
+ if (pipe(pipefd) != 0) {
+ syslog(LOG_NOTICE, "startxfr(%s -> %s) failing; pipe: %m",
+ dname, sin_ntoa(&qsp->s_from));
+ sqrm(qsp);
+ return;
+ }
+
+ /*
+ * child does the work while
+ * the parent continues
+ */
+ switch (pid = fork()) {
+ case -1:
+ syslog(LOG_NOTICE, "startxfr(%s -> %s) failing; fork: %m",
+ dname, sin_ntoa(&qsp->s_from));
+ close(pipefd[0]);
+ close(pipefd[1]);
+ sqrm(qsp);
+ return;
+ case 0:
+ /* child */
+ break;
+ default:
+ /* parent */
+ syslog(LOG_DEBUG, "zone transfer of \"%s\" to %s (pid %lu)",
+ dname, sin_ntoa(&qsp->s_from), (u_long)pid);
+ close(pipefd[0]); /* close the read end */
+ sqrm(qsp);
+ /* close the write end to release the child */
+ close(pipefd[1]);
+ 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);
+
+ close(pipefd[1]); /* close the write end */
+ /*
+ * Wait for parent to close the write end of the pipe which
+ * we'll see as an EOF. The parent won't close the write end
+ * until it has closed the fd we'll be writing to, at which
+ * point it will be safe for us to proceed.
+ *
+ * We shouldn't get interrupted, but ...
+ */
+ while (read(pipefd[0], &c, 1) == -1 && errno == EINTR)
+ ; /* nothing */
+ close(pipefd[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);
+#ifdef HAVE_SETVBUF
+ /* some systems (DEC OSF/1, SunOS) don't initialize the stdio buffer
+ * if all you do between fdopen() and fclose() are fwrite()'s. even
+ * on systems where the buffer is correctly set, it is too small.
+ */
+ if ((buf = malloc(XFER_BUFSIZE)) != NULL)
+ (void) setvbuf(rfp, buf, _IOFBF, XFER_BUFSIZE);
+#endif
+#ifdef SO_SNDBUF
+ /* the default seems to be 4K, and we'd like it to have enough room
+ * to parallelize sending the pushed data with accumulating more
+ * write() data from us.
+ */
+ (void) setsockopt(qsp->s_rfd, SOL_SOCKET, SO_SNDBUF,
+ (char *)&sndbuf, sizeof sndbuf);
+#endif
+ /* XXX: some day we would like to only send the size and header out
+ * when we fill a 64K DNS/AXFR "message" rather than on each RR.
+ * (PVM@ISI gets credit for this idea.)
+ */
+ fwritemsg(rfp, soa, soalen);
+ doaxfr(np, rfp, np, class);
+ fwritemsg(rfp, soa, soalen);
+ (void) fflush(rfp);
+#ifdef SO_LINGER
+ /* kernels that map pages for IO end up failing if the pipe is full
+ * at exit and we take away the final buffer. this is really a kernel
+ * bug but it's harmless on systems that are not broken, so...
+ */
+ setsockopt(qsp->s_rfd, SOL_SOCKET, SO_LINGER,
+ (char *)&ll, sizeof ll);
+ close(qsp->s_rfd);
+#endif
+ _exit(0);
+ /* NOTREACHED */
+}
+
+void
+free_addinfo() {
+ struct addinfo *ap;
+
+ for (ap = addinfo; --addcount >= 0; ap++) {
+ free(ap->a_dname);
+ free(ap->a_rname);
+ }
+ addcount = 0;
+}
+
+#ifdef DATUMREFCNT
+void
+free_nsp(nsp)
+ struct databuf **nsp;
+{
+ 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/contrib/bind/named/ns_resp.c b/contrib/bind/named/ns_resp.c
new file mode 100644
index 0000000..f64306e
--- /dev/null
+++ b/contrib/bind/named/ns_resp.c
@@ -0,0 +1,2743 @@
+#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 8.27 1996/08/05 08:31:30 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/types.h>
+#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 const char skipnameFailedAnswer[] = "skipname failed in answer",
+ skipnameFailedAuth[] = "skipname failed in authority",
+ skipnameFailedQuery[] = "skipname failed in query",
+ outofDataQuery[] = "ran out of data in query",
+ outofDataAnswer[] = "ran out of data in answer",
+ notSingleQuery[] = "not exactly one query",
+ expandFailedQuery[] = "dn_expand failed in query",
+ expandFailedAnswer[] = "dn_expand failed in answer",
+ expandFailedAuth[] = "dn_expand failed in authority",
+ outofDataAuth[] = "ran out of data in authority",
+ dlenOverrunAnswer[] = "dlen overrun in answer",
+ dlenOverrunAuth[] = "dlen overrun in authority",
+ dlenUnderrunAnswer[] = "dlen underrun in answer",
+ outofDataFinal[] = "out of data in final pass",
+ outofDataAFinal[] = "out of data after final pass",
+ badNameFound[] = "found an invalid domain name";
+
+static char *
+learntFrom(qp, server)
+ struct qinfo *qp;
+ struct sockaddr_in *server;
+{
+ static char *buf = NULL;
+ char *a, *ns, *na;
+ struct databuf *db;
+ char nsbuf[20];
+ char abuf[20];
+ int i;
+
+ if (buf) {
+ free(buf);
+ buf = NULL;
+ }
+
+ a = ns = na = "<Not Available>";
+
+ for (i = 0; i < (int)qp->q_naddr; i++) {
+ if (qp->q_addr[i].ns_addr.sin_addr.s_addr ==
+ server->sin_addr.s_addr) {
+ db = qp->q_addr[i].ns;
+ if (db) {
+#ifdef STATS
+ if (db->d_ns) {
+ strcpy(nsbuf,
+ inet_ntoa(db->d_ns->addr));
+ ns = nsbuf;
+ } else {
+ ns = zones[db->d_zone].z_origin;
+ }
+#endif
+
+#ifdef NCACHE
+ if (!db->d_rcode)
+#endif
+ na = (char*)qp->q_addr[i].ns->d_data;
+ }
+
+#ifdef STATS
+ db = qp->q_addr[i].nsdata;
+ if (db) {
+ if (db->d_ns) {
+ strcpy(abuf,
+ inet_ntoa(db->d_ns->addr));
+ a = abuf;
+ } else {
+ a = zones[db->d_zone].z_origin;
+ }
+ }
+#endif
+ break;
+ }
+ }
+
+ if ((a == ns) && (ns == na)) /* all "UNKNOWN" */
+ return ("");
+
+#ifdef STATS
+# define LEARNTFROM " '%s': learnt (A=%s,NS=%s)"
+#else
+# define LEARNTFROM " '%s'"
+#endif
+ buf = malloc(strlen(a = (*a ? a : "\".\"")) +
+ strlen(ns = (*ns ? ns : "\".\"")) +
+ strlen(na = (*na ? na : "\".\"")) +
+ sizeof(LEARNTFROM));
+ if (!buf)
+ return ("");
+ sprintf(buf, LEARNTFROM, na, a, ns);
+ return (buf);
+}
+
+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;
+ u_char *eom = msg + msglen;
+ register u_char *tempcp;
+#ifdef VALIDATE
+ struct sockaddr_in *server = &from_addr;
+ struct { char *name; int type, class; u_int cred; } defer_rm[99];
+ int defer_rm_count;
+#endif
+ struct sockaddr_in *nsa;
+ struct databuf *nsp[NSMAX];
+ int i, c, n, qdcount, ancount, aucount, nscount, arcount;
+ int qtype, qclass, dbflags;
+ int restart; /* flag for processing cname response */
+ int validanswer;
+ int cname;
+ int count, founddata, foundname;
+ int buflen;
+ int newmsglen;
+ char name[MAXDNAME], qname[MAXDNAME], msgbuf[MAXDNAME*2];
+ char *dname;
+ const char *fname;
+ const char *formerrmsg = "brain damage";
+ u_char newmsg[PACKETSZ];
+ 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 high level formatting problems by parsing the header.
+ */
+ qdcount = ntohs(hp->qdcount);
+ ancount = ntohs(hp->ancount);
+ aucount = ntohs(hp->nscount); /* !!! */
+ arcount = ntohs(hp->arcount);
+ free_addinfo(); /* sets addcount to zero */
+ cp = msg + HFIXEDSZ;
+ dpp = dnptrs;
+ *dpp++ = msg;
+ if ((*cp & INDIR_MASK) == 0)
+ *dpp++ = cp;
+ *dpp = NULL;
+ if (qdcount == 1) {
+ n = dn_expand(msg, eom, cp, qname, sizeof(qname));
+ if (n <= 0) {
+ formerrmsg = expandFailedQuery;
+ goto formerr;
+ }
+ cp += n;
+ GETSHORT(qtype, cp);
+ GETSHORT(qclass, cp);
+ if (!ns_nameok(qname, qclass, response_trans,
+ ns_ownercontext(qtype, response_trans))) {
+ formerrmsg = badNameFound;
+ goto formerr;
+ }
+ if (cp > eom) {
+ formerrmsg = outofDataQuery;
+ goto formerr;
+ }
+ if (qp->q_msg && qp->q_msglen &&
+ !res_nameinquery(qname, qtype, qclass,
+ qp->q_msg, qp->q_msg + qp->q_msglen)) {
+ sprintf(msgbuf,
+ "query section mismatch (%s %s %s)",
+ qname, p_class(qclass), p_type(qtype));
+ formerrmsg = msgbuf;
+ goto formerr;
+ }
+ } else {
+ /* Pedantic. */
+ qname[0] = '\0';
+ qtype = 0;
+ qclass = 0;
+ }
+
+ /* cp now points after the query section. */
+
+ /*
+ * 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 (it's sick)
+ * The server can't understand our query and return FORMERR
+ * In all these cases, we drop the packet, disable retries on
+ * this server and immediately force a retry.
+ */
+ if ((hp->rcode != NOERROR && hp->rcode != NXDOMAIN)
+ || (hp->opcode != QUERY
+#ifdef BIND_NOTIFY
+ && hp->opcode != NS_NOTIFY_OP
+#endif
+ )) {
+ dprintf(2, (ddt, "resp: error (ret %d, op %d), dropped\n",
+ hp->rcode, hp->opcode));
+ switch (hp->rcode) {
+ 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;
+ }
+ /* mark server as bad */
+ if (!qp->q_fwd)
+ for (i = 0; i < (int)qp->q_naddr; i++)
+ if (qp->q_addr[i].ns_addr.sin_addr.s_addr
+ == from_addr.sin_addr.s_addr)
+ qp->q_addr[i].nretry = MAXRETRY;
+ /*
+ * XXX: doesn't handle responses sent from the wrong
+ * interface on a multihomed server.
+ */
+ if (qp->q_fwd ||
+ qp->q_addr[qp->q_curaddr].ns_addr.sin_addr.s_addr
+ == from_addr.sin_addr.s_addr)
+ retry(qp);
+ return;
+ }
+
+ if (qdcount != 1) {
+ /* We don't generate or forward these (yet). */
+ formerrmsg = notSingleQuery;
+ goto formerr;
+ }
+
+#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.
+ * Workaround: disable recursion on authoritative servers so that
+ * the ambiguity does not arise.
+ */
+ /*
+ * If we weren't using a forwarder, find the qinfo pointer and update
+ * the rtt and fact that we have called on this server before.
+ */
+ if (fwd == (struct fwdinfo *)NULL) {
+ struct timeval *stp;
+
+ for (n = 0, qs = qp->q_addr; (u_int)n < qp->q_naddr; n++, qs++)
+ if (qs->ns_addr.sin_addr.s_addr ==
+ from_addr.sin_addr.s_addr)
+ break;
+ if ((u_int)n >= qp->q_naddr) {
+ if (!haveComplained((char*)from_addr.sin_addr.s_addr,
+ "unexpected source")) {
+ syslog(LOG_INFO,
+ "Response from unexpected source (%s)",
+ sin_ntoa(&from_addr));
+ }
+ /*
+ * 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",
+ sin_ntoa(&from_addr),
+ sin_ntoa(&qs->ns_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 %lu/%lu now %lu/%lu rtt %ld\n",
+ (u_long)stp->tv_sec, (u_long)stp->tv_usec,
+ (u_long)tt.tv_sec, (u_long)tt.tv_usec,
+ (long)rtrip));
+
+ /* prevent floating point overflow, limit to 1000 sec */
+ if (rtrip > 1000000) {
+ 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, sin_ntoa(&qs->ns_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;
+ (u_int)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,
+ sin_ntoa(&qs->ns_addr),
+ ns2->d_nstime));
+ }
+ }
+
+#ifdef BIND_NOTIFY
+ /* for now, NOTIFY isn't defined for ANCOUNT!=0, AUCOUNT!=0,
+ * or ADCOUNT!=0. therefore the only real work to be done for
+ * a NOTIFY-QR is to remove it from the query queue.
+ */
+ if (hp->opcode == NS_NOTIFY_OP) {
+ qremove(qp);
+ return;
+ }
+#endif
+
+#ifdef LAME_DELEGATION
+ /*
+ * Non-authoritative, no answer, no error
+ */
+ if (qdcount == 1 && hp->rcode == NOERROR && !hp->aa && ancount == 0
+ && aucount > 0
+#ifdef BIND_NOTIFY
+ && hp->opcode != NS_NOTIFY_OP
+#endif
+ ) {
+ u_char *tp;
+ int type, class;
+#ifdef DEBUG
+ if (debug > 0)
+ fp_nquery(msg, msglen, ddt);
+#endif
+ /*
+ * Since there is no answer section (ancount == 0),
+ * we must be pointing at the authority section (aucount > 0).
+ */
+ tp = cp;
+ n = dn_expand(msg, eom, tp, name, sizeof name);
+ if (n < 0) {
+ formerrmsg = expandFailedAuth;
+ goto formerr;
+ }
+ tp += n;
+ GETSHORT(type, tp);
+ if (tp >= eom) {
+ formerrmsg = outofDataAuth;
+ goto formerr;
+ }
+ GETSHORT(class, tp);
+ if (tp >= eom) {
+ formerrmsg = outofDataAuth;
+ goto formerr;
+ }
+ if (!ns_nameok(name, class, response_trans,
+ ns_ownercontext(type, response_trans))) {
+ formerrmsg = badNameFound;
+ 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. Note that for now we only log the message
+ * if the T_NS was C_IN, which is technically wrong (NS is
+ * visible in all classes) but necessary anyway (non-IN
+ * classes tend to not have good strong delegation graphs).
+ */
+
+ if (type == T_NS && samedomain(qp->q_domain, name)) {
+ nameserIncr(from_addr.sin_addr, nssRcvdLDel);
+ /* mark server as bad */
+ if (!qp->q_fwd)
+ for (i = 0; i < (int)qp->q_naddr; i++)
+ if (qp->q_addr[i].ns_addr.sin_addr.s_addr
+ == from_addr.sin_addr.s_addr)
+ qp->q_addr[i].nretry = MAXRETRY;
+#ifdef LAME_LOGGING
+ if (class == C_IN &&
+ !haveComplained((char*)nhash(sin_ntoa(&from_addr)),
+ (char*)nhash(qp->q_domain)))
+ syslog(LAME_LOGGING,
+ "Lame server on '%s' (in '%s'?): %s%s\n",
+ qname, qp->q_domain,
+ sin_ntoa(&from_addr),
+ learntFrom(qp, &from_addr));
+
+#endif /* LAME_LOGGING */
+ /* XXX - doesn't handle responses sent from the wrong
+ * interface on a multihomed server
+ */
+ if (qp->q_fwd ||
+ qp->q_addr[qp->q_curaddr].ns_addr.sin_addr.s_addr
+ == from_addr.sin_addr.s_addr)
+ retry(qp);
+ return;
+ }
+ }
+#endif /* LAME_DELEGATION */
+
+ if (qp->q_flags & Q_ZSERIAL) {
+ if (hp->aa && ancount > 0 && hp->rcode == NOERROR &&
+ qtype == T_SOA && ((qclass == C_IN) || (qclass == C_HS))) {
+ int n;
+ u_int16_t type, class, dlen;
+ u_int32_t serial;
+ u_char *tp = cp;
+
+ n = dn_expand(msg, eom, tp, name, sizeof name);
+ if (n < 0) {
+ formerrmsg = expandFailedAnswer;
+ goto formerr;
+ }
+ tp += n; /* name */
+ GETSHORT(type, tp); /* type */
+ GETSHORT(class, tp); /* class */
+ tp += INT32SZ; /* ttl */
+ GETSHORT(dlen, tp); /* dlen */
+ if (tp >= eom) {
+ formerrmsg = outofDataAnswer;
+ goto formerr;
+ }
+ if (!ns_nameok(name, class, response_trans,
+ ns_ownercontext(type, response_trans))){
+ formerrmsg = badNameFound;
+ goto formerr;
+ }
+ if (strcasecmp(qname, name) ||
+ qtype != type ||
+ qclass != class) {
+ sprintf(msgbuf,
+ "qserial answer mismatch (%s %s %s)",
+ name, p_class(class), p_type(type));
+ formerrmsg = msgbuf;
+ goto formerr;
+ }
+ if ((u_int)dlen < (5 * INT32SZ)) {
+ formerrmsg = dlenUnderrunAnswer;
+ goto formerr;
+ }
+
+ if (0 >= (n = dn_skipname(tp, eom))) {
+ formerrmsg = skipnameFailedAnswer;
+ goto formerr;
+ }
+ tp += n; /* mname */
+ if (0 >= (n = dn_skipname(tp, eom))) {
+ formerrmsg = skipnameFailedAnswer;
+ goto formerr;
+ }
+ tp += n; /* rname */
+ GETLONG(serial, tp);
+
+ qserial_answer(qp, serial);
+ qremove(qp);
+ } else {
+ retry(qp);
+ }
+ return;
+ }
+
+ /*
+ * Add the info received in the response to the data base.
+ */
+ c = ancount + aucount + arcount;
+
+ /* -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;
+
+#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 (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 */
+
+ if (qp->q_flags & Q_SYSTEM)
+ dbflags = DB_NOTAUTH | DB_NODATA;
+ else
+ dbflags = DB_NOTAUTH | DB_NODATA | DB_NOHINTS;
+ count = c;
+ if (qp->q_flags & Q_PRIMING)
+ dbflags |= DB_PRIMING;
+ if (hp->tc) {
+ count -= arcount; /* truncation had to affect this */
+ if (!arcount) {
+ count -= aucount; /* guess it got this too */
+ }
+ if (!(arcount || aucount)) {
+ count -= ancount; /* things are pretty grim */
+ }
+ /* XXX - should retry this query with TCP */
+ /*
+ * XXX - if this response is forwarded to the client
+ * the truncated section is included. We will not
+ * validate it, and if it somehow corrupt, we won't
+ * notice.
+ *
+ * XXX - if the answer section is truncated and we got
+ * this response after being redirected by a CNAME, we
+ * will not include any part of the final answer in our
+ * response to the client. This will make the client
+ * think that there are no RRs of the appropriate type.
+ */
+ }
+
+ tp = cp;
+
+ restart = 0;
+ validanswer = 0;
+ nscount = 0;
+ cname = 0;
+#ifdef VALIDATE
+ defer_rm_count = 0;
+#endif
+
+ for (i = 0; i < count; i++) {
+ struct databuf *ns3 = NULL;
+ u_char cred;
+ int VCode;
+ u_int16_t type, class;
+
+ if (cp >= eom) {
+ formerrmsg = outofDataFinal;
+ goto formerr;
+ }
+
+ /* Get the DNAME. */
+ tempcp = cp;
+ n = dn_expand(msg, eom, tempcp, name, sizeof name);
+ if (n <= 0) {
+ formerrmsg = outofDataFinal;
+ goto formerr;
+ }
+ tempcp += n;
+ GETSHORT(type, tempcp);
+ GETSHORT(class, tempcp);
+ if (!ns_nameok(name, class, response_trans,
+ ns_ownercontext(type, response_trans))) {
+ formerrmsg = badNameFound;
+ goto formerr;
+ }
+
+ /*
+ * See if there are any NS RRs in the authority section
+ * for the negative caching logic below. We'll count
+ * these before validation.
+ */
+ if (type == T_NS && i >= ancount && i < ancount + aucount)
+ nscount++;
+
+ /* Decide what credibility this ought to have in the cache. */
+ if (i < ancount)
+ cred = (hp->aa && !strcasecmp(name, qname))
+ ? DB_C_AUTH
+ : DB_C_ANSWER;
+ else
+ cred = (qp->q_flags & Q_PRIMING)
+ ? DB_C_ANSWER
+ : DB_C_ADDITIONAL;
+#ifdef VALIDATE
+ if ((n = dovalidate(msg, msglen, cp, 0,
+ dbflags, qp->q_domain, server,
+ &VCode)) < 0) {
+ formerrmsg = outofDataFinal;
+ goto formerr;
+ }
+ if (VCode == INVALID && !(qp->q_flags & Q_SYSTEM)) {
+ /*
+ * If anything in the answer section fails
+ * validation this means that it definitely did
+ * not reside below the domain owning the NS RRs
+ * that we sent the query to. This means either
+ * that it was the target of a CNAME early in the
+ * response, in which case we will treat this the
+ * same as if the answer was incomplete and restart
+ * the query on the CNAME target, or that someone
+ * was trying to spoof us.
+ */
+ if (i < ancount)
+ restart = 1;
+ /*
+ * Restart or no, if we're here it means we are not
+ * going to cache this RR. That being the case, we
+ * must burn down whatever partial RRset we've got
+ * in the cache now, lest we inadvertently answer
+ * with a truncated RRset in some future section.
+ */
+ for (c = 0; c < defer_rm_count; c++)
+ if (!strcasecmp(defer_rm[c].name, name) &&
+ defer_rm[c].class == class &&
+ defer_rm[c].type == type)
+ break;
+ if (c < defer_rm_count) {
+ if (defer_rm[c].cred < cred)
+ defer_rm[c].cred = cred;
+ } else {
+ if (defer_rm_count+1 >=
+ (sizeof defer_rm / sizeof defer_rm[0])) {
+ formerrmsg = "too many RRs in ns_resp";
+ goto formerr;
+ }
+ defer_rm[defer_rm_count].name = savestr(name);
+ defer_rm[defer_rm_count].type = type;
+ defer_rm[defer_rm_count].class = class;
+ defer_rm[defer_rm_count].cred = cred;
+ defer_rm_count++;
+ }
+ } else {
+#endif
+ if (i < ancount) {
+ /*
+ * If there are any non-CNAME RRs (or
+ * CNAME RRs if they are an acceptable)
+ * then the query is complete unless an
+ * intermediate CNAME didn't pass validation,
+ * but that's OK.
+ */
+ if (type != T_CNAME || qtype == T_CNAME ||
+ qtype == T_ANY)
+ validanswer = 1;
+ else
+ cname = 1;
+ }
+ n = doupdate(msg, msglen, cp, 0, &ns3, dbflags, cred);
+#ifdef VALIDATE
+ }
+#endif
+ if (n < 0) {
+ dprintf(1, (ddt, "resp: leaving, doupdate failed\n"));
+ formerrmsg = outofDataFinal;
+ goto formerr;
+ }
+ cp += n;
+ }
+#ifdef VALIDATE
+ if (defer_rm_count > 0) {
+ for (i = 0; i < defer_rm_count; i++) {
+ register struct databuf *db = NULL;
+
+ fname = "";
+ htp = hashtab; /* lookup relative to root */
+ np = nlookup(defer_rm[i].name, &htp, &fname, 0);
+ if (np && fname == defer_rm[i].name &&
+ defer_rm[i].class != C_ANY &&
+ defer_rm[i].type != T_ANY) {
+ /*
+ * If doupdate() wouldn't have cached this
+ * RR anyway, there's no need to delete it.
+ */
+ for (db = np->n_data;
+ db != NULL;
+ db = db->d_next) {
+ if (!db->d_zone &&
+ match(db, defer_rm[i].class,
+ defer_rm[i].type) &&
+ db->d_cred >= defer_rm[i].cred) {
+ break;
+ }
+ }
+ if (db == NULL)
+ delete_all(np, defer_rm[i].class,
+ defer_rm[i].type);
+ /* XXX: should delete name node if empty? */
+ }
+ syslog(LOG_DEBUG, "defer_rm [%s %s %s] (np%#x, db%#x)",
+ defer_rm[i].name,
+ p_class(defer_rm[i].class),
+ p_type(defer_rm[i].type),
+ np, db);
+ free(defer_rm[i].name);
+ }
+ }
+#endif
+
+ if (cp > eom) {
+ formerrmsg = outofDataAFinal;
+ goto formerr;
+ }
+
+ 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));
+#ifdef BIND_NOTIFY
+ if (qp->q_notifyzone != DB_Z_CACHE) {
+ struct zoneinfo *zp = &zones[qp->q_notifyzone];
+
+ /*
+ * Clear this first since sysnotify() might set it.
+ */
+ qp->q_notifyzone = DB_Z_CACHE;
+ sysnotify(zp->z_origin, zp->z_class, T_SOA);
+ }
+#endif
+ qremove(qp);
+ return;
+ }
+
+ if (ancount && count && !validanswer)
+ /*
+ * Everything passed validation but we didn't get the
+ * final answer. The response must have contained
+ * a dangling CNAME. Force a restart of the query.
+ *
+ * Don't set restart if count==0, since this means
+ * the response was truncated in the answer section,
+ * causing us to set count to 0 which will cause
+ * validanswer to be 0 as well even though the answer
+ * section probably contained valid RRs (just not
+ * a complete set).
+ * XXX - this works right if we can just forward this
+ * response to the client, but not if we found a CNAME
+ * in a prior response and restarted the query.
+ */
+ restart = 1;
+
+ /*
+ * If there are addresses and this is a local query,
+ * sort them appropriately for the local context.
+ */
+#ifdef SORT_RESPONSE
+ if (!restart && ancount > 1 && (lp = local(&qp->q_from)) != NULL)
+ sort_response(tp, ancount, lp, eom);
+#endif
+
+ /*
+ * An answer to a T_ANY query or a successful answer to a
+ * regular query with no indirection, then just return answer.
+ */
+ if (!restart && ancount && (qtype == T_ANY || !qp->q_cmsglen)) {
+ 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 || qclass == C_ANY)) {
+ /* we have an authoritative NO */
+ dprintf(3, (ddt, "resp: leaving auth NO\n"));
+ if (qp->q_cmsglen) {
+ /* XXX - what about additional CNAMEs in the chain? */
+ 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;
+ /*
+ * Even with VALIDATE, if restart==0 and ancount > 0, we should
+ * have some valid data because because the data in the answer
+ * section is owned by the query name and that passes the
+ * validation test by definition
+ *
+ * XXX - the restart stuff doesn't work if any of the answer RRs
+ * is not cacheable (TTL==0 or unknown RR type), since all of the
+ * answer must pass through the cache and be re-assembled.
+ */
+ if ((!restart || !cname) && qp->q_cmsglen && ancount) {
+ dprintf(1, (ddt, "Cname second pass\n"));
+ newmsglen = MIN(PACKETSZ, qp->q_cmsglen);
+ bcopy(qp->q_cmsg, newmsg, newmsglen);
+ } else {
+ newmsglen = MIN(PACKETSZ, msglen);
+ bcopy(msg, newmsg, newmsglen);
+ }
+ hp = (HEADER *) newmsg;
+ hp->ancount = htons(0);
+ hp->nscount = htons(0);
+ hp->arcount = htons(0);
+ dnptrs[0] = newmsg;
+ dnptrs[1] = NULL;
+ cp = newmsg + HFIXEDSZ;
+ /*
+ * Keep in mind that none of this code works when QDCOUNT>1.
+ * cp ends up pointed just past the query section in both cases.
+ */
+ /*
+ * Arrange for dname to contain the query name. The query
+ * name can be either the original query name if restart==0
+ * or the target of the last CNAME if we are following a
+ * CNAME chain and were referred.
+ */
+ n = dn_expand(newmsg, newmsg + newmsglen, cp, dname,
+ sizeof name);
+ if (n < 0) {
+ dprintf(1, (ddt, "dn_expand failed\n"));
+ goto servfail;
+ }
+ if (!res_dnok(dname)) {
+ dprintf(1, (ddt, "bad name (%s)\n", dname));
+ goto servfail;
+ }
+ cp += n + QFIXEDSZ;
+ buflen = sizeof(newmsg) - (cp - newmsg);
+
+ cname = 0;
+ try_again:
+ dprintf(1, (ddt, "resp: nlookup(%s) qtype=%d\n", dname, qtype));
+ fname = "";
+ htp = hashtab; /* lookup relative to root */
+ np = nlookup(dname, &htp, &fname, 0);
+ 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, qclass, qtype, hp, &dname, &buflen, &count);
+ if (n == 0)
+ goto fetch_ns; /* NO data available */
+ cp += n;
+ buflen -= n;
+ hp->ancount = htons(ntohs(hp->ancount) + (u_int16_t)count);
+ if (fname != dname && qtype != T_CNAME && qtype != 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:
+
+ if (hp->tc)
+ goto return_newmsg;
+
+ /*
+ * 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, qclass, nsp, &count, 0)) {
+ case NXDOMAIN: /* shouldn't happen */
+ dprintf(3, (ddt, "req: leaving (%s, rcode %d)\n",
+ dname, hp->rcode));
+ if (!foundname)
+ hp->rcode = NXDOMAIN;
+ if (qclass != 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, &count);
+ 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 %s %s)\n",
+ dname, p_class(qclass), p_type(qtype)));
+ syslog(LOG_INFO,
+ "MAXQUERIES exceeded, possible data loop in resolving (%s)",
+ dname);
+ goto servfail;
+ }
+
+ /* Reset the query control structure */
+#ifdef DATUMREFCNT
+ /* XXX - this code should be shared with qfree()'s similar logic. */
+ for (i = 0; (u_int)i < qp->q_naddr; i++) {
+ static const char freed[] = "freed", busy[] = "busy";
+ const char *result;
+
+ if (qp->q_addr[i].ns != NULL) {
+ if ((--(qp->q_addr[i].ns->d_rcnt)))
+ result = busy;
+ else
+ result = freed;
+ dprintf(1, (ddt, "ns_resp: ns %s rcnt %d (%s)\n",
+ qp->q_addr[i].ns->d_data,
+ qp->q_addr[i].ns->d_rcnt,
+ result));
+ if (result == freed)
+ free((char*)qp->q_addr[i].ns);
+ }
+ if (qp->q_addr[i].nsdata != NULL) {
+ if ((--(qp->q_addr[i].nsdata->d_rcnt)))
+ result = busy;
+ else
+ result = freed;
+ dprintf(1, (ddt,
+ "ns_resp: nsdata %08.8X rcnt %d (%s)\n",
+ *(int32_t *)(qp->q_addr[i].nsdata->d_data),
+ qp->q_addr[i].nsdata->d_rcnt,
+ result));
+ if (result == freed)
+ free((char*)qp->q_addr[i].nsdata);
+ }
+ }
+#endif
+ qp->q_naddr = 0;
+ qp->q_curaddr = 0;
+ qp->q_fwd = fwdtab;
+#if defined(LAME_DELEGATION) || defined(VALIDATE)
+ 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"));
+ if (cname) /* a remote CNAME that does not have data */
+ goto return_newmsg;
+ goto servfail;
+ } else {
+ dprintf(3, (ddt, "resp: no addrs found for NS's\n"));
+ /*
+ * Timeout while sysquery looks up the NS addresses.
+ *
+ * Hopefully we'll have them when the client asks
+ * again.
+ *
+ * too bad we can't just wait for the sysquery
+ * response to restart this query (it's too hard).
+ *
+ * We could try to crawl back up the tree looking
+ * for reachable servers, but we may have just
+ * gotten delegated down here by a response with
+ * no A RRs for the servers. If we blindly tried
+ * this strategy, we bang on the same server forever.
+ */
+ goto timeout;
+ }
+ }
+ for (n = 0; (u_int)n < qp->q_naddr; n++)
+ qp->q_addr[n].stime.tv_sec = 0;
+ if (!qp->q_fwd)
+ qp->q_addr[0].stime = tt;
+ 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_cmsg) {
+ qp->q_cmsg = qp->q_msg;
+ qp->q_cmsglen = qp->q_msglen;
+ } else if (qp->q_msg)
+ (void) free(qp->q_msg);
+ if ((qp->q_msg = (u_char *)malloc(BUFSIZ)) == NULL) {
+ syslog(LOG_NOTICE, "resp: malloc error\n");
+ goto servfail;
+ }
+ n = res_mkquery(QUERY, dname, qclass, qtype,
+ NULL, 0, NULL, qp->q_msg, BUFSIZ);
+ if (n < 0) {
+ syslog(LOG_INFO, "resp: res_mkquery(%s) failed",
+ dname);
+ goto servfail;
+ }
+ qp->q_msglen = n;
+ hp = (HEADER *) qp->q_msg;
+ hp->rd = 0;
+ } else
+ hp = (HEADER *) qp->q_msg;
+ hp->id = qp->q_nsid = htons(nsid_next());
+ if (qp->q_fwd)
+ hp->rd = 1;
+ unsched(qp);
+ schedretry(qp, retrytime(qp));
+ nsa = Q_NEXTADDR(qp, 0);
+ dprintf(1, (ddt, "resp: forw -> %s ds=%d nsid=%d id=%d %dms\n",
+ sin_ntoa(nsa), ds,
+ ntohs(qp->q_nsid), ntohs(qp->q_id),
+ (qp->q_addr[0].nsdata != NULL)
+ ? qp->q_addr[0].nsdata->d_nstime
+ : (-1)));
+#ifdef DEBUG
+ if (debug >= 10)
+ fp_nquery(qp->q_msg, qp->q_msglen, ddt);
+#endif
+ if (sendto(ds, (char*)qp->q_msg, qp->q_msglen, 0,
+ (struct sockaddr *)nsa,
+ sizeof(struct sockaddr_in)) < 0) {
+ if (!haveComplained((char*)nsa->sin_addr.s_addr, sendtoStr))
+ syslog(LOG_INFO, "ns_resp: sendto(%s): %m",
+ sin_ntoa(nsa));
+ nameserIncr(nsa->sin_addr, nssSendtoErr);
+ }
+ hp->rd = 0; /* leave set to 0 for dup detection */
+#ifdef XSTATS
+ nameserIncr(nsa->sin_addr, nssSentFwdR);
+#endif
+ nameserIncr(qp->q_from.sin_addr, nssRcvdFwdR);
+ dprintf(3, (ddt, "resp: Query sent.\n"));
+#ifdef DATUMREFCNT
+ free_nsp(nsp);
+#endif
+ return;
+
+ formerr:
+ if (!haveComplained((char*)from_addr.sin_addr.s_addr,
+ (char*)nhash(formerrmsg)))
+ syslog(LOG_INFO, "Malformed response from %s (%s)\n",
+ sin_ntoa(&from_addr), formerrmsg);
+#ifdef XSTATS
+ nameserIncr(from_addr.sin_addr, nssSentFErr);
+#endif
+#ifdef DATUMREFCNT
+ free_nsp(nsp);
+#endif
+ return;
+
+ return_msg:
+ nameserIncr(from_addr.sin_addr, nssRcvdFwdR);
+#ifdef XSTATS
+ nameserIncr(qp->q_from.sin_addr, nssSentFwdR);
+#endif
+ /* The "standard" return code */
+ hp->qr = 1;
+ hp->id = qp->q_id;
+ hp->rd = 1;
+ hp->ra = (NoRecurse == 0);
+ (void) send_msg(msg, msglen, qp);
+ qremove(qp);
+#ifdef DATUMREFCNT
+ free_nsp(nsp);
+#endif
+ return;
+
+ return_newmsg:
+ nameserIncr(qp->q_from.sin_addr, nssSentAns);
+
+#ifdef XSTATS
+ if (!hp->aa)
+ nameserIncr(qp->q_from.sin_addr, nssSentNaAns);
+ if (hp->rcode == NXDOMAIN)
+ nameserIncr(qp->q_from.sin_addr, nssSentNXD);
+#endif
+ n = doaddinfo(hp, cp, buflen);
+ cp += n;
+ buflen -= n;
+ hp->qr = 1;
+ hp->id = qp->q_id;
+ hp->rd = 1;
+ hp->ra = (NoRecurse == 0);
+ (void) send_msg(newmsg, cp - newmsg, qp);
+ qremove(qp);
+#ifdef DATUMREFCNT
+ free_nsp(nsp);
+#endif
+ return;
+
+ servfail:
+#ifdef XSTATS
+ nameserIncr(qp->q_from.sin_addr, nssSentFail);
+#endif
+ hp = (HEADER *)(qp->q_cmsglen ? qp->q_cmsg : qp->q_msg);
+ hp->rcode = SERVFAIL;
+ hp->qr = 1;
+ hp->id = qp->q_id;
+ hp->rd = 1;
+ hp->ra = (NoRecurse == 0);
+ (void) send_msg((u_char *)hp, (qp->q_cmsglen ? qp->q_cmsglen : qp->q_msglen),
+ qp);
+ timeout:
+ 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;
+ enum context context;
+#ifdef ALLOW_UPDATES
+ int zonenum;
+#endif
+
+ dprintf(3, (ddt, "doupdate(zone %d, savens %#lx, flags %#lx)\n",
+ zone, (u_long)savens, (u_long)flags));
+
+ cp = rrp;
+ if ((n = dn_expand(msg, msg + msglen, cp, dname, sizeof dname)) < 0) {
+ hp->rcode = FORMERR;
+ return (-1);
+ }
+ cp += n;
+ GETSHORT(type, cp);
+ GETSHORT(class, cp);
+ GETLONG(ttl, cp);
+ GETSHORT(dlen, cp);
+ if (!ns_nameok(dname, class, response_trans,
+ ns_ownercontext(type, response_trans))) {
+ hp->rcode = FORMERR;
+ return (-1);
+ }
+ 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:
+ case T_AAAA:
+ case T_LOC:
+#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);
+ }
+ if (!ns_nameok((char *)data, class, response_trans,
+ (type == T_PTR)
+ ? ns_ptrcontext(dname)
+ : domain_ctx)) {
+ hp->rcode = FORMERR;
+ return (-1);
+ }
+ cp += n;
+ cp1 = data;
+ n = strlen((char *)data) + 1;
+ break;
+
+ case T_SOA:
+ context = hostname_ctx;
+ goto soa_rp_minfo;
+ case T_RP:
+ case T_MINFO:
+ context = mailname_ctx;
+ /* FALLTHROUGH */
+ soa_rp_minfo:
+ n = dn_expand(msg, msg + msglen, cp,
+ (char *)data, sizeof data);
+ if (n < 0) {
+ hp->rcode = FORMERR;
+ return (-1);
+ }
+ if (!ns_nameok((char *)data, class, response_trans, context)) {
+ 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);
+ }
+ if (type == T_RP)
+ context = domain_ctx;
+ else
+ context = mailname_ctx;
+ if (!ns_nameok((char *)cp1, class, response_trans, context)) {
+ 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);
+ }
+ if (!ns_nameok((char *)cp1, class, response_trans,
+ hostname_ctx)) {
+ 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;
+
+ case T_PX:
+ /* grab preference */
+ bcopy(cp, data, INT16SZ);
+ cp1 = data + INT16SZ;
+ cp += INT16SZ;
+
+ /* get MAP822 name */
+ n = dn_expand(msg, msg + msglen, cp, (char *)cp1,
+ sizeof data - INT16SZ);
+ if (n < 0) {
+ hp->rcode = FORMERR;
+ return (-1);
+ }
+ if (!ns_nameok((char *)cp1, class, response_trans,
+ domain_ctx)) {
+ hp->rcode = FORMERR;
+ return (-1);
+ }
+ cp += n;
+ cp1 += (n = strlen((char *)cp1) + 1);
+ n1 = sizeof(data) - n;
+ n = dn_expand(msg, msg + msglen, cp, (char *)cp1, n1);
+ if (n < 0) {
+ hp->rcode = FORMERR;
+ return (-1);
+ }
+ if (!ns_nameok((char *)cp1, class, response_trans,
+ domain_ctx)) {
+ hp->rcode = FORMERR;
+ return (-1);
+ }
+ cp += n;
+ cp1 += strlen((char *)cp1) + 1;
+ n = cp1 - data;
+ cp1 = data;
+ break;
+
+ default:
+ dprintf(3, (ddt, "unknown type %d\n", type));
+ return ((cp - rrp) + dlen);
+ }
+ if (n > MAXDATA) {
+ dprintf(1, (ddt,
+ "update type %d: %d bytes is too much data\n",
+ type, n));
+ hp->rcode = 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 *temp, qname[MAXDNAME];
+ 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, sin_ntoa(&from_addr), qname);
+ return (cp - rrp);
+ }
+#ifdef BOGUSNS
+ if (bogusns) {
+ if (!haveComplained((char*)from_addr.sin_addr.s_addr,
+ "bogus nonroot NS"))
+ syslog(LOG_INFO,
+ "bogus nonroot NS %s rcvd from %s on query for \"%s\"",
+ data, sin_ntoa(&from_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) id=%d\n",
+ sin_ntoa(&qp->q_from),
+ qp->q_stream == QSTREAM_NULL ? "UDP" : "TCP",
+ qp->q_stream == QSTREAM_NULL ? qp->q_dfd
+ : qp->q_stream->s_rfd,
+ ntohs(qp->q_id));
+ }
+ if (debug > 4) {
+ struct qinfo *tqp;
+
+ for (tqp = nsqhead; tqp!=QINFO_NULL; tqp = tqp->q_link) {
+ fprintf(ddt,
+ "qp %#lx q_id: %d q_nsid: %d q_msglen: %d ",
+ (u_long)tqp, tqp->q_id,
+ tqp->q_nsid, tqp->q_msglen);
+ fprintf(ddt,
+ "q_naddr: %d q_curaddr: %d\n",
+ tqp->q_naddr, tqp->q_curaddr);
+ fprintf(ddt, "q_next: %#lx q_link: %#lx\n",
+ (u_long)qp->q_next, (u_long)qp->q_link);
+ }
+ }
+ if (debug > 5)
+ fp_nquery(msg, msglen, ddt);
+#endif /* DEBUG */
+ if (qp->q_stream == QSTREAM_NULL) {
+ if (sendto(qp->q_dfd, (char*)msg, msglen, 0,
+ (struct sockaddr *)&qp->q_from,
+ sizeof(qp->q_from)) < 0) {
+ if (!haveComplained((char*)qp->q_from.sin_addr.s_addr,
+ sendtoStr))
+#if defined(SPURIOUS_ECONNREFUSED)
+ if (errno != ECONNREFUSED)
+#endif
+ syslog(LOG_INFO,
+ "send_msg: sendto(%s): %m",
+ sin_ntoa(&qp->q_from));
+ 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, QUERY);
+}
+#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, QUERY)))
+ priming = 0;
+ else
+ qp->q_flags |= (Q_SYSTEM | Q_PRIMING);
+ }
+ needs_prime_cache = 0;
+ return;
+}
+
+#ifdef BIND_NOTIFY
+struct notify *
+findNotifyPeer(zp, ina)
+ const struct zoneinfo *zp;
+ struct in_addr ina;
+{
+ register struct notify *ap;
+
+ for (ap = zp->z_notifylist; ap; ap = ap->next)
+ if (ap->addr.s_addr == ina.s_addr)
+ break;
+ return (ap);
+}
+
+/* sysnotify(dname, class, type)
+ * cause a NOTIFY request to be sysquery()'d to each secondary server
+ * of the zone that "dname" is within.
+ */
+void
+sysnotify(dname, class, type)
+ const char *dname;
+ int class, type;
+{
+ char *soaname, *zname;
+ const char *fname;
+ register struct databuf *dp;
+ struct in_addr nss[NSMAX];
+ int nns, na, zn, nsc;
+ struct hashbuf *htp;
+ struct zoneinfo *zp;
+ struct notify *ap;
+ struct namebuf *np;
+
+ htp = hashtab;
+ np = nlookup(dname, &htp, &fname, 0);
+ if (!np)
+ panic(-1, "sysnotify: can't find name");
+ zn = findMyZone(np, class);
+ if (zn == DB_Z_CACHE)
+ panic(-1, "sysnotify: not auth zone");
+ zp = &zones[zn];
+ if (zp->z_type != Z_PRIMARY && zp->z_type != Z_SECONDARY)
+ panic(-1, "sysnotify: not pri/sec");
+ zname = zp->z_origin;
+/*
+**DBG** syslog(LOG_INFO, "sysnotify: found \"%s\" in \"%s\" (%s)",
+**DBG** dname, zname, zoneTypeString(zp));
+*/
+ nns = na = 0;
+ /*
+ * Send to recent AXFR peers.
+ */
+ for (ap = zp->z_notifylist; ap; ap = ap->next) {
+ if (tt.tv_sec - ap->last >= zp->z_refresh) {
+ /* XXX - probably should do GC here. */
+ continue;
+ }
+ nss[0] = ap->addr;
+ nsc = 1;
+ nns++;
+ na++;
+ sysquery(dname, class, T_SOA, nss, nsc, NS_NOTIFY_OP);
+ }
+ if (zp->z_type != Z_PRIMARY)
+ goto done;
+ /*
+ * Master.
+ */
+ htp = hashtab;
+ np = nlookup(zname, &htp, &fname, 0);
+ if (!np)
+ panic(-1, "sysnotify: found name but not zone");
+ soaname = NULL;
+ for (dp = np->n_data; dp; dp = dp->d_next) {
+ if (!dp->d_zone || !match(dp, class, T_SOA))
+ continue;
+ if (soaname) {
+ syslog(LOG_NOTICE, "multiple SOA's for zone \"%s\"?",
+ zname);
+ return;
+ }
+ soaname = (char *) dp->d_data;
+ }
+ if (!soaname) {
+ syslog(LOG_NOTICE, "no SOA found for zone \"%s\"", zname);
+ return;
+ }
+
+ for (dp = np->n_data; dp; dp = dp->d_next) {
+ register struct databuf *adp;
+ struct namebuf *anp;
+
+ if (!dp->d_zone || !match(dp, class, T_NS))
+ continue;
+ /* NS RDATA is server name. */
+ if (strcasecmp((char*)dp->d_data, soaname) == 0)
+ continue;
+ htp = hashtab;
+ anp = nlookup((char*)dp->d_data, &htp, &fname, 0);
+ if (!anp) {
+ syslog(LOG_INFO, "sysnotify: can't nlookup(%s)?",
+ (char*)dp->d_data);
+ continue;
+ }
+ nsc = 0;
+ for (adp = anp->n_data; adp; adp = adp->d_next) {
+ struct in_addr ina;
+ if (!match(adp, class, T_A))
+ continue;
+ ina = data_inaddr(adp->d_data);
+ /* Don't send to things we handled above. */
+ ap = findNotifyPeer(zp, ina);
+ if (ap && tt.tv_sec - ap->last < zp->z_refresh)
+ goto nextns;
+ if (nsc < NSMAX)
+ nss[nsc++] = ina;
+ } /*next A*/
+ if (nsc == 0) {
+ struct qinfo *qp;
+
+ qp = sysquery((char*)dp->d_data, /*NS name*/
+ class, /*XXX: C_IN?*/
+ T_A, 0, 0, QUERY);
+ if (qp)
+ qp->q_notifyzone = zn;
+ continue;
+ }
+ (void) sysquery(dname, class, T_SOA, nss, nsc, NS_NOTIFY_OP);
+ nns++;
+ na += nsc;
+ nextns:;
+ } /*next NS*/
+ done:
+ if (nns || na) {
+ char tmp[MAXDNAME*2];
+
+ /* Many syslog()'s only take 5 args. */
+ sprintf(tmp, "%s %s %s", dname, p_class(class), p_type(type));
+ syslog(LOG_INFO, "Sent NOTIFY for \"%s\" (%s); %d NS, %d A",
+ tmp, zname, nns, na);
+ }
+}
+#endif /*BIND_NOTIFY*/
+
+struct qinfo *
+sysquery(dname, class, type, nss, nsc, opcode)
+ const char *dname;
+ int class, type;
+ struct in_addr *nss;
+ int nsc, opcode;
+{
+ register struct qinfo *qp, *oqp;
+ register HEADER *hp;
+ struct namebuf *np;
+ struct databuf *nsp[NSMAX];
+ struct hashbuf *htp;
+ struct sockaddr_in *nsa;
+ const char *fname;
+ int n, count;
+
+#ifdef DATUMREFCNT
+ nsp[0] = NULL;
+#endif
+ dprintf(3, (ddt, "sysquery(%s, %d, %d, %#lx, %d)\n",
+ dname, class, type, (u_long)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) {
+ syslog(LOG_INFO, "sysquery: nlookup error on %s?",
+ dname);
+ err1:
+ qfree(qp);
+ return (NULL);
+ }
+
+ n = findns(&np, class, nsp, &count, 0);
+ switch (n) {
+ case NXDOMAIN:
+ case SERVFAIL:
+ syslog(LOG_DEBUG, "sysquery: findns error (%d) on %s?",
+ n, dname);
+ err2:
+#ifdef DATUMREFCNT
+ free_nsp(nsp);
+#endif
+ goto err1;
+ }
+ }
+
+ /* 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;
+#if defined(LAME_DELEGATION) || defined(VALIDATE)
+ getname(np, qp->q_domain, sizeof(qp->q_domain));
+#endif /* LAME_DELEGATION */
+
+ if ((qp->q_msg = (u_char *)malloc(BUFSIZ)) == NULL) {
+ syslog(LOG_NOTICE, "sysquery: malloc failed");
+ goto err2;
+ }
+ n = res_mkquery(opcode, dname, class,
+ type, NULL, 0, NULL,
+ qp->q_msg, BUFSIZ);
+ if (n < 0) {
+ syslog(LOG_INFO, "sysquery: res_mkquery(%s) failed", dname);
+ goto err2;
+ }
+ qp->q_msglen = n;
+ hp = (HEADER *) qp->q_msg;
+ hp->id = qp->q_nsid = htons(nsid_next());
+ hp->rd = (qp->q_fwd ? 1 : 0);
+
+ /* First check for an already pending query for this data */
+ for (oqp = nsqhead; oqp != QINFO_NULL; oqp = oqp->q_link) {
+ if ((oqp != qp)
+ && (oqp->q_msglen == qp->q_msglen)
+ && bcmp((char *)oqp->q_msg+2,
+ qp->q_msg+2,
+ qp->q_msglen-2) == 0
+ ) {
+#ifdef BIND_NOTIFY
+ /* XXX - need fancier test to suppress duplicate
+ * NOTIFYs to the same server (compare nss?)
+ */
+ if (opcode != NS_NOTIFY_OP)
+#endif /*BIND_NOTIFY*/
+ {
+ dprintf(3, (ddt, "sysquery: duplicate\n"));
+ goto err2;
+ }
+ }
+ }
+
+ 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 {
+ fetch_a:
+ count = nslookup(nsp, qp, dname, "sysquery");
+ if (count <= 0) {
+ if (count < 0) {
+ syslog(LOG_INFO,
+ "sysquery: nslookup reports danger (%s)",
+ dname);
+ goto err2;
+ } else if (np && NAME(*np)[0] == '\0') {
+ syslog(LOG_WARNING,
+ "sysquery: no addrs found for root NS (%s)",
+ dname);
+ if (class == C_IN && !priming)
+ needs_prime_cache = 1;
+ goto err2;
+ }
+ if (np) {
+#ifdef DATUMREFCNT
+ free_nsp(nsp);
+ nsp[0] = NULL;
+#endif
+ np = np_parent(np);
+ n = findns(&np, class, nsp, &count, 0);
+ switch (n) {
+ case NXDOMAIN: /*FALLTHROUGH*/
+ case SERVFAIL:
+ syslog(LOG_DEBUG,
+ "sysquery: findns error (%d) on %s?",
+ n, dname);
+ goto err2;
+ }
+ goto fetch_a;
+ }
+ goto err2;
+ }
+ }
+
+ 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 dfd=%d nsid=%d id=%d retry=%ld\n",
+ sin_ntoa(nsa), qp->q_dfd,
+ ntohs(qp->q_nsid), ntohs(qp->q_id),
+ (long)qp->q_time));
+#ifdef DEBUG
+ if (debug >= 10)
+ fp_nquery(qp->q_msg, qp->q_msglen, ddt);
+#endif
+ if (sendto(qp->q_dfd, (char*)qp->q_msg, qp->q_msglen, 0,
+ (struct sockaddr *)nsa,
+ sizeof(struct sockaddr_in)) < 0) {
+ if (!haveComplained((char*)nsa->sin_addr.s_addr, sendtoStr))
+ syslog(LOG_INFO, "sysquery: sendto(%s): %m",
+ sin_ntoa(nsa));
+ 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 (NAME(*np)[0] == '\0')
+ break;
+ if (np == NULL) {
+ syslog(LOG_NOTICE, "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_NOTICE,
+ "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;
+ const 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 (NAME(*np)[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 %#lx\n",
+ dname, fname, (u_long)tnp));
+ sysquery(dname, dp->d_class, T_A, NULL,
+ 0, QUERY);
+ 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",
+ NAME(*tnp)));
+ /* Cache invalidate the address RR's */
+ delete_all(tnp, dp->d_class, T_A);
+ found_arr = 0;
+ break;
+ }
+ found_arr++;
+ }
+ if (!found_arr)
+ sysquery(dname, dp->d_class, T_A, NULL,
+ 0, QUERY);
+ }
+ }
+}
+
+/* int findns(npp, class, nsp, countp, flag)
+ * Find NS' or an SOA
+ * npp, class:
+ * dname whose most enclosing 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 || NAME(*np)[0] == '\0'))
+ htp = fcachetab;
+ else
+ htp = hashtab;
+
+ try_again:
+ if (htp == fcachetab && class == C_IN && !priming)
+ needs_prime_cache = 1;
+ if (np == NULL) {
+ /* find the root */
+ for (np = htp->h_tab[0]; np != NULL; np = np->n_next)
+ if (NAME(*np)[0] == '\0')
+ break;
+ }
+ while (np != NULL) {
+ dprintf(5, (ddt, "findns: np %#lx '%s'\n",
+ (u_long)np, NAME(*np)));
+ /* 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 &&
+#ifdef PURGE_ZONE
+ ((zones[dp->d_zone].z_type == Z_PRIMARY) ||
+ (zones[dp->d_zone].z_type == Z_SECONDARY)) &&
+#endif
+ match(dp, class, T_SOA)) {
+ dprintf(3, (ddt, "findns: SOA found\n"));
+ if (zones[dp->d_zone].z_flags & Z_AUTH) {
+ *npp = np;
+ 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;
+#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!
+ *
+ * XXX: this is horribly bogus.
+ */
+ if ((dp->d_zone == 0) &&
+#ifdef DATUMREFCNT
+ (dp->d_ttl < tt.tv_sec) &&
+#else
+ (dp->d_ttl < (tt.tv_sec+900)) &&
+#endif
+ !(dp->d_flags & DB_F_HINT)) {
+ dprintf(1, (ddt, "findns: stale entry '%s'\n",
+ NAME(*np)));
+#ifdef DATUMREFCNT
+ /*
+ * We may have already added NS databufs
+ * and are going to throw them away. Fix
+ * fix reference counts. We don't need
+ * free() them here as we just got them
+ * from the cache.
+ */
+ while (nspp > &nsp[0])
+ (*--nspp)->d_rcnt--;
+#endif
+ /* Cache invalidate the NS RR's. */
+#ifndef DATUMREFCNT
+ if (dp->d_ttl < tt.tv_sec)
+#endif
+ delete_all(np, class, T_NS);
+ nsp[0] = NULL;
+ 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, NAME(*np)));
+ *nspp = NULL;
+ *npp = np;
+ return (OK); /* Success, got some NS's */
+ }
+try_parent:
+ np = np_parent(np);
+ }
+ if (htp == hashtab) {
+ htp = fcachetab;
+ 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_INFO, "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;
+#ifdef DEBUG
+ if (buflen > PACKETSZ)
+ dprintf(1, (ddt, "finddata(): buflen=%d\n", buflen));
+#endif
+ cp = ((char *)hp) + *countp;
+ for (dp = np->n_data; dp != NULL; dp = dp->d_next) {
+ if (!wanted(dp, class, type)) {
+#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",
+ NAME(*np)));
+ 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_INFO,
+ "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_INFO,
+ "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 != DB_Z_CACHE &&
+ (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(%#lx, %d, %d) [%s %s]\n",
+ (u_long)dp, class, type,
+ p_class(dp->d_class), p_type(dp->d_type)));
+
+ if (dp->d_class != class && class != C_ANY)
+ return (0);
+ 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 occured. Typically you are
+ * adding NS records to a response.
+ */
+int
+add_data(np, dpp, cp, buflen, countp)
+ struct namebuf *np;
+ struct databuf **dpp;
+ register u_char *cp;
+ int buflen, *countp;
+{
+ register struct databuf *dp;
+ char dname[MAXDNAME];
+ register int n, bytes;
+
+ bytes = *countp = 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 (-bytes); /* Truncation */
+ cp += n;
+ buflen -= n;
+ bytes += n;
+ (*countp)++;
+ }
+ return (bytes);
+}
+
+/*
+ * This is best thought of as a "cache invalidate" function.
+ * It is called whenever a piece of data is determined to have
+ * become invalid either through a timeout or a validation
+ * failure. 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(%#lx:\"%s\" %s %s)\n",
+ (u_long)np, NAME(*np), p_class(class), p_type(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/contrib/bind/named/ns_sort.c b/contrib/bind/named/ns_sort.c
new file mode 100644
index 0000000..0f53cce
--- /dev/null
+++ b/contrib/bind/named/ns_sort.c
@@ -0,0 +1,171 @@
+#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 8.3 1995/12/22 10:20:30 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));
+
+#ifdef SORT_RESPONSE
+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(%#lx, %d, [%s])\n",
+ (u_long)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);
+}
+#endif
diff --git a/contrib/bind/named/ns_stats.c b/contrib/bind/named/ns_stats.c
new file mode 100644
index 0000000..9a29fb1
--- /dev/null
+++ b/contrib/bind/named/ns_stats.c
@@ -0,0 +1,399 @@
+#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 8.7 1996/08/05 08:31:30 vixie Exp $";
+#endif /* not lint */
+
+/*
+ * ++Copyright++ 1986,1994
+ * -
+ * Copyright (c) 1986,1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * 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/types.h>
+#include <sys/param.h>
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <arpa/inet.h>
+#include <stdio.h>
+#include <syslog.h>
+#include <errno.h>
+
+#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", "NSAP_PTR", "SIG",
+ "KEY", "PX", "invalid(GPOS)", "AAAA", "LOC",
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ /* 20 per line */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 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 = time(NULL);
+ register FILE *f;
+ register int i;
+
+ syslog(LOG_NOTICE, "dumping nameserver stats\n");
+
+ if (!(f = fopen(statsfile, "a"))) {
+ syslog(LOG_NOTICE, "cannot open stat file, \"%s\"\n",
+ statsfile);
+ return;
+ }
+
+ fprintf(f, "+++ Statistics Dump +++ (%ld) %s",
+ (long)timenow, ctime(&timenow));
+ fprintf(f, "%ld\ttime since boot (secs)\n",
+ (long)(timenow - boottime));
+ fprintf(f, "%ld\ttime since reset (secs)\n",
+ (long)(timenow - resettime));
+
+#ifdef DMALLOC
+ /* malloc statistics */
+ dmallocstats(f);
+#endif
+
+ /* query type statistics */
+ fprintf(f, "%lu\tUnknown query types\n", (u_long)typestats[0]);
+ for(i=1; i < T_ANY+1; i++)
+ if (typestats[i])
+ if (typenames[i])
+ fprintf(f, "%lu\t%s queries\n",
+ (u_long)typestats[i], typenames[i]);
+ else
+ fprintf(f, "%lu\ttype %d queries\n",
+ (u_long)typestats[i], i);
+
+ /* name server statistics */
+ nameserStats(f);
+
+ fprintf(f, "--- Statistics Dump --- (%ld) %s",
+ (long)timenow, ctime(&timenow));
+ (void) my_fclose(f);
+ syslog(LOG_NOTICE, "done dumping nameserver stats\n");
+}
+
+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] = {
+ "RR", /* sent us an answer */
+ "RNXD", /* sent us a negative response */
+ "RFwdR", /* sent us a response we had to fwd */
+ "RDupR", /* sent us an extra answer */
+ "RFail", /* sent us a SERVFAIL */
+ "RFErr", /* sent us a FORMERR */
+ "RErr", /* sent us some other error */
+ "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 */
+ "SDupQ", /* sent them a retry */
+ "SErr", /* sent failed (in sendto) */
+#ifdef XSTATS
+ "RQ", /* sent us a query */
+ "RIQ", /* sent us an inverse query */
+ "RFwdQ", /* sent us a query we had to fwd */
+ "RDupQ", /* sent us a retry */
+ "RTCP", /* sent us a query using TCP */
+ "SFwdR", /* fwdd a response to them */
+ "SFail", /* sent them a SERVFAIL */
+ "SFErr", /* sent them a FORMERR */
+ "SNaAns", /* sent them a non autoritative answer */
+ "SNXD", /* sent them a negative response */
+#endif
+ };
+#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;
+ const char *pre = "\t";
+
+ for (i = 0; i < (int)nssLast; i++) {
+ fprintf(f, "%s%lu", pre, (u_long)stats[i]);
+ pre = ((i+1) % 5) ? " " : " ";
+ }
+ fputc('\n', f);
+}
+
+static void
+nameserStatsHdr(f)
+ FILE *f;
+{
+ int i;
+ const 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*/
+}
+
+#ifdef XSTATS
+/* Benoit Grange, log minimal statistics, called from ns_maint */
+void
+ns_logstats()
+{
+ char buffer[1024];
+ char buffer2[32], header[64];
+ time_t timenow = time(NULL);
+ int i;
+
+#ifdef HAVE_GETRUSAGE
+# define tv_float(tv) ((tv).tv_sec + ((tv).tv_usec / 1000000.0))
+ struct rusage usage, childu;
+
+ getrusage(RUSAGE_SELF, &usage);
+ getrusage(RUSAGE_CHILDREN, &childu);
+
+ sprintf(buffer, "CPU=%gu/%gs CHILDCPU=%gu/%gs",
+ tv_float(usage.ru_utime), tv_float(usage.ru_stime),
+ tv_float(childu.ru_utime), tv_float(childu.ru_stime));
+ syslog(LOG_INFO, "USAGE %lu %lu %s", (u_long)timenow, (u_long)boottime,
+ buffer);
+# undef tv_float
+#endif
+
+ sprintf(header, "NSTATS %lu %lu", (u_long)timenow, (u_long)boottime);
+ strcpy(buffer, header);
+
+ for (i = 0; i < T_ANY+1; i++) {
+ if (typestats[i]) {
+ if (typenames[i])
+ sprintf(buffer2, " %s=%lu",
+ typenames[i], typestats[i]);
+ else
+ sprintf(buffer2, " %d=%lu", i, typestats[i]);
+ if (strlen(buffer) + strlen(buffer2) >
+ sizeof(buffer) - 1) {
+ syslog(LOG_INFO, buffer);
+ strcpy(buffer, header);
+ }
+ strcat(buffer, buffer2);
+ }
+ }
+ syslog(LOG_INFO, buffer);
+
+ sprintf(header, "XSTATS %lu %lu", (u_long)timenow, (u_long)boottime);
+ strcpy(buffer, header);
+ for (i = 0; i < (int)nssLast; i++) {
+ sprintf(buffer2, " %s=%lu",
+ statNames[i]?statNames[i]:"?", (u_long)globalStats[i]);
+ if (strlen(buffer) + strlen(buffer2) > sizeof(buffer) - 1) {
+ syslog(LOG_INFO, buffer);
+ strcpy(buffer, header);
+ }
+ strcat(buffer, buffer2);
+ }
+ syslog(LOG_INFO, buffer);
+}
+
+#endif /*XSTATS*/
diff --git a/contrib/bind/named/ns_validate.c b/contrib/bind/named/ns_validate.c
new file mode 100644
index 0000000..00df9d7
--- /dev/null
+++ b/contrib/bind/named/ns_validate.c
@@ -0,0 +1,1246 @@
+/**************************************************************************
+ * 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/types.h>
+#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"
+
+#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, qdomain, 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 (domain lives below the qdomain)
+ * return VALID_CACHE;
+ * 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, qdomain, server, type, class, data, dlen
+#ifdef NCACHE
+ ,rcode
+#endif
+ )
+ char *dname, *qdomain;
+ struct sockaddr_in *server;
+ int type, class;
+ char *data;
+ int dlen;
+#ifdef NCACHE
+ int rcode;
+#endif
+{
+ struct namebuf *np, *dnamep;
+ struct hashbuf *htp;
+ struct databuf *nsp[NSMAX];
+ int count;
+ const 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 = "";
+ dprintf(5, (ddt,
+ "validate:namebuf found np:%#lx, d:\"%s\", f:\"%s\"\n",
+ (u_long)np, dname, fname));
+ /* save the namebuf if we were able to locate the exact dname */
+ if (!strcasecmp(dname, fname)) {
+ dnamep = np;
+ exactmatch = 1;
+ }
+ 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, NAME(*np))) {
+
+ /* 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\n"));
+ if (needs_prime_cache)
+ needs_prime_cache = 0;
+ if (samedomain(dname, qdomain) ||
+ 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:
+ case T_LOC:
+#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);
+
+ case T_PX:
+ x = memcmp(dp->d_data, data,
+ INT16SZ);
+ if (x != 0)
+ break;
+ td = data + INT16SZ;
+ tdp = dp->d_data + INT16SZ;
+
+ /* compare first string */
+ x = strncasecmp(td, (char *)tdp,
+ strlen((char *)td) + 1);
+ if (x != 0)
+ break;
+ td += (strlen(td) + 1);
+ tdp += (strlen((char *)tdp) + 1);
+
+ /* compare second string */
+ x = strncasecmp(td, (char *)tdp,
+ strlen((char *)td+1));
+ if (x != 0)
+ break;
+ return (1);
+
+ default:
+ dprintf(3, (ddt, "unknown type %d\n", type));
+ return (0);
+ }
+ /* 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%lx, d:\"%s\"\n",
+ inet_ntoa(*saddr), (u_long)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;
+ const char *dname, *fname;
+ int class;
+ int qcomp();
+
+ dprintf(3, (ddt, "check_in_tables(nsp=x%lx, qp=x%x, '%s')\n",
+ (u_long)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)
+ const char *servername;
+ struct in_addr serveraddr;
+ const char *syslogdname;
+ const 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*)
+ nhash(nameaddrlist[i].nsname),
+ (char*)nhash(servername)))
+ syslog(LOG_INFO,
+ "%s: server name mismatch for [%s]: (%s != %s) (server for %s)",
+ sysloginfo,
+ inet_ntoa(serveraddr),
+ nameaddrlist[i].nsname, servername,
+ syslogdname);
+#endif
+ free(nameaddrlist[i].nsname);
+ nameaddrlist[i].nsname = savestr(servername);
+ return;
+ }
+ }
+ /* we have to add this one to our cache */
+
+ nameaddrlist[firstNA].nsname = savestr(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, qdomain, server, VCode)
+ u_char *msg, *rrp;
+ int msglen, zone, flags;
+ char *qdomain;
+ 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_nquery(msg, msglen, 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:
+ case T_LOC:
+#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;
+
+ case T_PX:
+ /* grab preference */
+ bcopy((char *)cp, data, INT16SZ);
+ cp1 = data + INT16SZ;
+ cp += INT16SZ;
+
+ /* get first name */
+ n = dn_expand(msg, msg + msglen, cp,
+ (char *)cp1, sizeof(data) - INT16SZ);
+ if (n < 0) {
+ hp->rcode = FORMERR;
+ return (-1);
+ }
+ cp += n;
+ cp1 += (n = strlen((char *)cp1) + 1);
+ n1 = sizeof(data) - n;
+
+ /* get second name */
+ n = dn_expand(msg, msg + msglen, cp, (char *)cp1, n1);
+ if (n < 0) {
+ hp->rcode = FORMERR;
+ return (-1);
+ }
+ cp += n;
+ cp1 += strlen((char *)cp1) + 1;
+ n = cp1 - data;
+ cp1 = data;
+ break;
+
+ default:
+ dprintf(3, (ddt, "unknown type %d\n", type));
+ return ((cp - rrp) + dlen);
+ }
+ if (n > MAXDATA) {
+ dprintf(2, (ddt,
+ "update type %d: %d bytes is too much data\n",
+ type, n));
+ hp->rcode = FORMERR;
+ return (-1);
+ }
+
+ *VCode = validate(dname, qdomain, 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));
+ if (!validateQ)
+ panic(errno, "malloc(validateQ)");
+ validateQ->type = type;
+ validateQ->class = class;
+ validateQ->dname = savestr(dname);
+ validateQ->data = savestr(data); /* XXX no \0 */
+ 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));
+ if (!tempVQ)
+ panic(errno, "malloc(tempVQ)");
+ tempVQ->type = type;
+ tempVQ->class = class;
+ tempVQ->dname = savestr(dname);
+ tempVQ->data = savestr(data); /* XXX no \0 */
+ 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
+
+#ifdef BAD_IDEA
+/* 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_nquery(msg, *msglen, 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));
+ if (!RRlen)
+ panic(errno, "malloc(RRlen)");
+ 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_expand() 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:
+ case T_LOC:
+#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;
+
+ case T_PX:
+ /* grab preference */
+ bcopy(cp, newcp, INT16SZ);
+ cp += INT16SZ;
+ newcp += INT16SZ;
+
+ /* get first name */
+ n = dn_expand(msg, eom, cp, (char *)data, sizeof data);
+ if (n < 0) {
+ hp->rcode = FORMERR;
+ goto badend;
+ }
+ cp += n;
+ n_new = dn_comp((char *)data, newcp, rembuflen,
+ dnptrs, edp);
+ if (n_new < 0)
+ goto badend;
+ newcp += n_new;
+ newlen += n_new+INT16SZ;
+ rembuflen -= n_new+INT16SZ;
+ dlen = n_new+INT16SZ;
+ n = dn_expand(msg, eom, cp, (char *)data, sizeof data);
+ if (n < 0) {
+ hp->rcode = FORMERR;
+ goto badend;
+ }
+ cp += n;
+ n_new = dn_comp((char *)data, newcp, rembuflen,
+ dnptrs, edp);
+ if (n_new < 0)
+ goto badend;
+ newcp += n_new;
+ newlen += n_new;
+ rembuflen -= n_new;
+ dlen += n_new;
+ PUTSHORT(dlen, tempcp);
+ break;
+
+ default:
+ dprintf(3, (ddt, "unknown type %d\n", type));
+ goto badend;
+ }
+ 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_nquery(msg, *msglen, ddt);
+#endif
+ free((char *)RRlen);
+ return (n);
+badend:
+ dprintf(2, (ddt, "encountered problems: UPDATE_MSG\n"));
+ free((char *)RRlen);
+ return (-1);
+}
+#endif /*BAD_IDEA*/
+
+#endif /*VALIDATE*/
diff --git a/contrib/bind/named/pathnames.h b/contrib/bind/named/pathnames.h
new file mode 100644
index 0000000..7ded7d2
--- /dev/null
+++ b/contrib/bind/named/pathnames.h
@@ -0,0 +1,122 @@
+/*
+ * @(#)pathnames.h 5.4 (Berkeley) 6/1/90
+ * $Id: pathnames.h,v 8.1 1994/12/15 06:24:14 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/contrib/bind/named/storage.c b/contrib/bind/named/storage.c
new file mode 100644
index 0000000..2fa53cd
--- /dev/null
+++ b/contrib/bind/named/storage.c
@@ -0,0 +1,205 @@
+/*
+ * ++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/types.h>
+#include <sys/param.h>
+#include <syslog.h>
+
+#include "../conf/portability.h"
+#include "../conf/options.h"
+extern void panic __P((int, const char *));
+
+#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 8.2 1996/08/05 08:31:30 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 ) {
+ panic(errno, "rt_malloc: malloc failure");
+ } 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 )
+ panic(-1, "rt_free: corrupt magic");
+ }
+ mp->mdb_len = 0; /* successful free */
+ goto ok;
+ }
+ panic(-1, "rt_free: bad pointer");
+ 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/contrib/bind/named/tree.c b/contrib/bind/named/tree.c
new file mode 100644
index 0000000..58607ea
--- /dev/null
+++ b/contrib/bind/named/tree.c
@@ -0,0 +1,570 @@
+/* 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/contrib/bind/named/tree.h b/contrib/bind/named/tree.h
new file mode 100644
index 0000000..7d027b9
--- /dev/null
+++ b/contrib/bind/named/tree.h
@@ -0,0 +1,48 @@
+/* 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 8.1 1994/12/15 06:24:14 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/contrib/bind/named/tree.man3 b/contrib/bind/named/tree.man3
new file mode 100644
index 0000000..5be48783
--- /dev/null
+++ b/contrib/bind/named/tree.man3
@@ -0,0 +1,154 @@
+.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/contrib/bind/res/Makefile b/contrib/bind/res/Makefile
new file mode 100644
index 0000000..fe9f399
--- /dev/null
+++ b/contrib/bind/res/Makefile
@@ -0,0 +1,115 @@
+#
+# from @(#)Makefile 5.16 (Berkeley) 3/14/88
+# $Id: Makefile,v 8.11 1996/08/05 08:31:35 vixie Exp $
+#
+
+## ++Copyright++ 1988, 1995
+## -
+## Copyright (c) 1988, 1995
+## The Regents of the University of California. All rights reserved.
+##
+## Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions
+## are met:
+## 1. Redistributions of source code must retain the above copyright
+## notice, this list of conditions and the following disclaimer.
+## 2. Redistributions in binary form must reproduce the above copyright
+## notice, this list of conditions and the following disclaimer in the
+## documentation and/or other materials provided with the distribution.
+## 3. All advertising materials mentioning features or use of this software
+## must display the following acknowledgement:
+## This product includes software developed by the University of
+## California, Berkeley and its contributors.
+## 4. Neither the name of the University nor the names of its contributors
+## may be used to endorse or promote products derived from this software
+## without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+## ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+## ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+## FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+## OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+## HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+## LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+## OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+## SUCH DAMAGE.
+## -
+## Portions Copyright (c) 1993 by Digital Equipment Corporation.
+##
+## Permission to use, copy, modify, and distribute this software for any
+## purpose with or without fee is hereby granted, provided that the above
+## copyright notice and this permission notice appear in all copies, and that
+## the name of Digital Equipment Corporation not be used in advertising or
+## publicity pertaining to distribution of the document or software without
+## specific, written prior permission.
+##
+## THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
+## WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
+## OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
+## CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+## DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+## PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+## ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+## SOFTWARE.
+## -
+## --Copyright--
+
+DESTDIR =
+DESTLIB = /usr/lib
+CC= cc
+SHELL= /bin/sh
+CDEBUG= -g
+INCL = ../include
+COMPINCL = ../compat/include
+AR= ar cru
+RANLIB= ranlib
+DEFS=
+LOCDEFS= -DUSE_OPTIONS_H
+INSTALL= install
+
+AROBJS= ${ARPREF} ${OBJS} ${ARSUFF}
+
+CFLAGS= ${CDEBUG} -I${INCL} -I${COMPINCL} ${DEFS} ${LOCDEFS}
+
+SRCS= herror.c res_debug.c res_data.c \
+ res_comp.c res_init.c res_mkquery.c res_query.c res_send.c \
+ getnetbyaddr.c getnetbyname.c getnetent.c getnetnamadr.c \
+ gethnamaddr.c sethostent.c nsap_addr.c hostnamelen.c \
+ inet_addr.c inet_ntop.c inet_pton.c
+
+OBJS= herror.o res_debug.o res_data.o \
+ res_comp.o res_init.o res_mkquery.o res_query.o res_send.o \
+ getnetbyaddr.o getnetbyname.o getnetent.o getnetnamadr.o \
+ gethnamaddr.o sethostent.o nsap_addr.o hostnamelen.o \
+ inet_addr.o inet_ntop.o inet_pton.o
+
+all: libresolv.a
+
+libresolv.a: ${OBJS}
+ ${AR} libresolv.a ${AROBJS}
+ $(RANLIB) libresolv.a
+
+install: ${DESTDIR}${DESTLIB}/libresolv.a
+
+${DESTDIR}${DESTLIB}/libresolv.a: libresolv.a
+ ${INSTALL} -c -o bin -g bin -m 644 libresolv.a ${DESTDIR}${DESTLIB}/
+ ( cd ${DESTDIR}${DESTLIB} ; $(RANLIB) libresolv.a )
+
+.c.o:
+ ${CC} ${CPPFLAGS} ${CFLAGS} -c $*.c
+ -${LDS} ld -x -r $*.o
+ ${LDS} mv a.out $*.o
+
+clean: FRC
+ rm -f errs a.out core libresolv.a tags .depend
+ rm -f *.o *.BAK *.CKP *~ *.orig
+
+depend: FRC
+ mkdep ${CPPFLAGS} -I${INCL} -I${COMPINCL} ${DEFS} ${SRCS}
+
+FRC:
+
+# DO NOT DELETE THIS LINE -- mkdep uses it.
+# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY.
diff --git a/contrib/bind/res/gethnamaddr.c b/contrib/bind/res/gethnamaddr.c
new file mode 100644
index 0000000..54fabd6
--- /dev/null
+++ b/contrib/bind/res/gethnamaddr.c
@@ -0,0 +1,927 @@
+/*
+ * ++Copyright++ 1985, 1988, 1993
+ * -
+ * Copyright (c) 1985, 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * -
+ * Portions Copyright (c) 1993 by Digital Equipment Corporation.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies, and that
+ * the name of Digital Equipment Corporation not be used in advertising or
+ * publicity pertaining to distribution of the document or software without
+ * specific, written prior permission.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
+ * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ * -
+ * --Copyright--
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)gethostnamadr.c 8.1 (Berkeley) 6/4/93";
+static char rcsid[] = "$Id: gethnamaddr.c,v 8.17 1996/08/05 08:31:35 vixie Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+
+#include <stdio.h>
+#include <netdb.h>
+#include <resolv.h>
+#include <ctype.h>
+#include <errno.h>
+#include <syslog.h>
+
+#ifndef LOG_AUTH
+# define LOG_AUTH 0
+#endif
+
+#define MULTI_PTRS_ARE_ALIASES 1 /* XXX - experimental */
+
+#if defined(BSD) && (BSD >= 199103) && defined(AF_INET6)
+# include <string.h>
+#else
+# include "../conf/portability.h"
+#endif
+#if defined(USE_OPTIONS_H)
+# include <../conf/options.h>
+#endif
+
+#ifdef SPRINTF_CHAR
+# define SPRINTF(x) strlen(sprintf/**/x)
+#else
+# define SPRINTF(x) ((size_t)sprintf x)
+#endif
+
+#define MAXALIASES 35
+#define MAXADDRS 35
+
+static const char AskedForGot[] =
+ "gethostby*.getanswer: asked for \"%s\", got \"%s\"";
+
+static char *h_addr_ptrs[MAXADDRS + 1];
+static struct hostent *gethostbyname_ipv4 __P((const char *));
+
+static struct hostent host;
+static char *host_aliases[MAXALIASES];
+static char hostbuf[8*1024];
+static u_char host_addr[16]; /* IPv4 or IPv6 */
+static FILE *hostf = NULL;
+static int stayopen = 0;
+
+static void map_v4v6_address __P((const char *src, char *dst));
+static void map_v4v6_hostent __P((struct hostent *hp, char **bp, int *len));
+
+#ifdef RESOLVSORT
+static void addrsort __P((char **, int));
+#endif
+
+#if PACKETSZ > 1024
+#define MAXPACKET PACKETSZ
+#else
+#define MAXPACKET 1024
+#endif
+
+typedef union {
+ HEADER hdr;
+ u_char buf[MAXPACKET];
+} querybuf;
+
+typedef union {
+ int32_t al;
+ char ac;
+} align;
+
+extern int h_errno;
+
+#ifdef DEBUG
+static void
+dprintf(msg, num)
+ char *msg;
+ int num;
+{
+ if (_res.options & RES_DEBUG) {
+ int save = errno;
+
+ printf(msg, num);
+ errno = save;
+ }
+}
+#else
+# define dprintf(msg, num) /*nada*/
+#endif
+
+static struct hostent *
+getanswer(answer, anslen, qname, qtype)
+ const querybuf *answer;
+ int anslen;
+ const char *qname;
+ int qtype;
+{
+ register const HEADER *hp;
+ register const u_char *cp;
+ register int n;
+ const u_char *eom;
+ char *bp, **ap, **hap;
+ int type, class, buflen, ancount, qdcount;
+ int haveanswer, had_error;
+ int toobig = 0;
+ char tbuf[MAXDNAME+1];
+ const char *tname;
+ int (*name_ok) __P((const char *));
+
+ tname = qname;
+ host.h_name = NULL;
+ eom = answer->buf + anslen;
+ switch (qtype) {
+ case T_A:
+ case T_AAAA:
+ name_ok = res_hnok;
+ break;
+ case T_PTR:
+ name_ok = res_dnok;
+ break;
+ default:
+ return (NULL); /* XXX should be abort(); */
+ }
+ /*
+ * find first satisfactory answer
+ */
+ hp = &answer->hdr;
+ ancount = ntohs(hp->ancount);
+ qdcount = ntohs(hp->qdcount);
+ bp = hostbuf;
+ buflen = sizeof hostbuf;
+ cp = answer->buf + HFIXEDSZ;
+ if (qdcount != 1) {
+ h_errno = NO_RECOVERY;
+ return (NULL);
+ }
+ n = dn_expand(answer->buf, eom, cp, bp, buflen);
+ if ((n < 0) || !(*name_ok)(bp)) {
+ h_errno = NO_RECOVERY;
+ return (NULL);
+ }
+ cp += n + QFIXEDSZ;
+ if (qtype == T_A || qtype == T_AAAA) {
+ /* res_send() has already verified that the query name is the
+ * same as the one we sent; this just gets the expanded name
+ * (i.e., with the succeeding search-domain tacked on).
+ */
+ n = strlen(bp) + 1; /* for the \0 */
+ host.h_name = bp;
+ bp += n;
+ buflen -= n;
+ /* The qname can be abbreviated, but h_name is now absolute. */
+ qname = host.h_name;
+ }
+ ap = host_aliases;
+ *ap = NULL;
+ host.h_aliases = host_aliases;
+ hap = h_addr_ptrs;
+ *hap = NULL;
+ host.h_addr_list = h_addr_ptrs;
+ haveanswer = 0;
+ had_error = 0;
+ while (ancount-- > 0 && cp < eom && !had_error) {
+ n = dn_expand(answer->buf, eom, cp, bp, buflen);
+ if ((n < 0) || !(*name_ok)(bp)) {
+ had_error++;
+ continue;
+ }
+ cp += n; /* name */
+ type = _getshort(cp);
+ cp += INT16SZ; /* type */
+ class = _getshort(cp);
+ cp += INT16SZ + INT32SZ; /* class, TTL */
+ n = _getshort(cp);
+ cp += INT16SZ; /* len */
+ if (class != C_IN) {
+ /* XXX - debug? syslog? */
+ cp += n;
+ continue; /* XXX - had_error++ ? */
+ }
+ if ((qtype == T_A || qtype == T_AAAA) && type == T_CNAME) {
+ if (ap >= &host_aliases[MAXALIASES-1])
+ continue;
+ n = dn_expand(answer->buf, eom, cp, tbuf, sizeof tbuf);
+ if ((n < 0) || !(*name_ok)(tbuf)) {
+ had_error++;
+ continue;
+ }
+ cp += n;
+ /* Store alias. */
+ *ap++ = bp;
+ n = strlen(bp) + 1; /* for the \0 */
+ bp += n;
+ buflen -= n;
+ /* Get canonical name. */
+ n = strlen(tbuf) + 1; /* for the \0 */
+ if (n > buflen) {
+ had_error++;
+ continue;
+ }
+ strcpy(bp, tbuf);
+ host.h_name = bp;
+ bp += n;
+ buflen -= n;
+ continue;
+ }
+ if (qtype == T_PTR && type == T_CNAME) {
+ n = dn_expand(answer->buf, eom, cp, tbuf, sizeof tbuf);
+ if ((n < 0) || !res_hnok(tbuf)) {
+ had_error++;
+ continue;
+ }
+ cp += n;
+ /* Get canonical name. */
+ n = strlen(tbuf) + 1; /* for the \0 */
+ if (n > buflen) {
+ had_error++;
+ continue;
+ }
+ strcpy(bp, tbuf);
+ tname = bp;
+ bp += n;
+ buflen -= n;
+ continue;
+ }
+ if (type != qtype) {
+ syslog(LOG_NOTICE|LOG_AUTH,
+ "gethostby*.getanswer: asked for \"%s %s %s\", got type \"%s\"",
+ qname, p_class(C_IN), p_type(qtype),
+ p_type(type));
+ cp += n;
+ continue; /* XXX - had_error++ ? */
+ }
+ switch (type) {
+ case T_PTR:
+ if (strcasecmp(tname, bp) != 0) {
+ syslog(LOG_NOTICE|LOG_AUTH,
+ AskedForGot, qname, bp);
+ cp += n;
+ continue; /* XXX - had_error++ ? */
+ }
+ n = dn_expand(answer->buf, eom, cp, bp, buflen);
+ if ((n < 0) || !res_hnok(bp)) {
+ had_error++;
+ break;
+ }
+#if MULTI_PTRS_ARE_ALIASES
+ cp += n;
+ if (!haveanswer)
+ host.h_name = bp;
+ else if (ap < &host_aliases[MAXALIASES-1])
+ *ap++ = bp;
+ else
+ n = -1;
+ if (n != -1) {
+ n = strlen(bp) + 1; /* for the \0 */
+ bp += n;
+ buflen -= n;
+ }
+ break;
+#else
+ host.h_name = bp;
+ if (_res.options & RES_USE_INET6) {
+ n = strlen(bp) + 1; /* for the \0 */
+ bp += n;
+ buflen -= n;
+ map_v4v6_hostent(&host, &bp, &buflen);
+ }
+ h_errno = NETDB_SUCCESS;
+ return (&host);
+#endif
+ case T_A:
+ case T_AAAA:
+ if (strcasecmp(host.h_name, bp) != 0) {
+ syslog(LOG_NOTICE|LOG_AUTH,
+ AskedForGot, host.h_name, bp);
+ cp += n;
+ continue; /* XXX - had_error++ ? */
+ }
+ if (haveanswer) {
+ if (n != host.h_length) {
+ cp += n;
+ continue;
+ }
+ } else {
+ register int nn;
+
+ host.h_name = bp;
+ nn = strlen(bp) + 1; /* for the \0 */
+ bp += nn;
+ buflen -= nn;
+ }
+
+ bp += sizeof(align) - ((u_long)bp % sizeof(align));
+
+ if (bp + n >= &hostbuf[sizeof hostbuf]) {
+ dprintf("size (%d) too big\n", n);
+ had_error++;
+ continue;
+ }
+ if (hap >= &h_addr_ptrs[MAXADDRS-1]) {
+ if (!toobig++)
+ dprintf("Too many addresses (%d)\n",
+ MAXADDRS);
+ cp += n;
+ continue;
+ }
+ bcopy(cp, *hap++ = bp, n);
+ bp += n;
+ buflen -= n;
+ cp += n;
+ break;
+ default:
+ abort();
+ }
+ if (!had_error)
+ haveanswer++;
+ }
+ if (haveanswer) {
+ *ap = NULL;
+ *hap = NULL;
+# if defined(RESOLVSORT)
+ /*
+ * Note: we sort even if host can take only one address
+ * in its return structures - should give it the "best"
+ * address in that case, not some random one
+ */
+ if (_res.nsort && haveanswer > 1 && qtype == T_A)
+ addrsort(h_addr_ptrs, haveanswer);
+# endif /*RESOLVSORT*/
+ if (!host.h_name) {
+ n = strlen(qname) + 1; /* for the \0 */
+ if (n > buflen)
+ goto try_again;
+ strcpy(bp, qname);
+ host.h_name = bp;
+ bp += n;
+ buflen -= n;
+ }
+ if (_res.options & RES_USE_INET6)
+ map_v4v6_hostent(&host, &bp, &buflen);
+ h_errno = NETDB_SUCCESS;
+ return (&host);
+ }
+ try_again:
+ h_errno = TRY_AGAIN;
+ return (NULL);
+}
+
+struct hostent *
+gethostbyname(name)
+ const char *name;
+{
+ struct hostent *hp;
+
+ if (_res.options & RES_USE_INET6) {
+ hp = gethostbyname2(name, AF_INET6);
+ if (hp)
+ return (hp);
+ }
+ return (gethostbyname2(name, AF_INET));
+}
+
+struct hostent *
+gethostbyname2(name, af)
+ const char *name;
+ int af;
+{
+ querybuf buf;
+ register const char *cp;
+ char *bp;
+ int n, size, type, len;
+ extern struct hostent *_gethtbyname2();
+
+ if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
+ h_errno = NETDB_INTERNAL;
+ return (NULL);
+ }
+
+ switch (af) {
+ case AF_INET:
+ size = INADDRSZ;
+ type = T_A;
+ break;
+ case AF_INET6:
+ size = IN6ADDRSZ;
+ type = T_AAAA;
+ break;
+ default:
+ h_errno = NETDB_INTERNAL;
+ errno = EAFNOSUPPORT;
+ return (NULL);
+ }
+
+ host.h_addrtype = af;
+ host.h_length = size;
+
+ /*
+ * if there aren't any dots, it could be a user-level alias.
+ * this is also done in res_query() since we are not the only
+ * function that looks up host names.
+ */
+ if (!strchr(name, '.') && (cp = __hostalias(name)))
+ name = cp;
+
+ /*
+ * disallow names consisting only of digits/dots, unless
+ * they end in a dot.
+ */
+ if (isdigit(name[0]))
+ for (cp = name;; ++cp) {
+ if (!*cp) {
+ if (*--cp == '.')
+ break;
+ /*
+ * All-numeric, no dot at the end.
+ * Fake up a hostent as if we'd actually
+ * done a lookup.
+ */
+ if (inet_pton(af, name, host_addr) <= 0) {
+ h_errno = HOST_NOT_FOUND;
+ return (NULL);
+ }
+ strncpy(hostbuf, name, MAXDNAME);
+ hostbuf[MAXDNAME] = '\0';
+ bp = hostbuf + MAXDNAME;
+ len = sizeof hostbuf - MAXDNAME;
+ host.h_name = hostbuf;
+ host.h_aliases = host_aliases;
+ host_aliases[0] = NULL;
+ h_addr_ptrs[0] = (char *)host_addr;
+ h_addr_ptrs[1] = NULL;
+ host.h_addr_list = h_addr_ptrs;
+ if (_res.options & RES_USE_INET6)
+ map_v4v6_hostent(&host, &bp, &len);
+ h_errno = NETDB_SUCCESS;
+ return (&host);
+ }
+ if (!isdigit(*cp) && *cp != '.')
+ break;
+ }
+
+ if ((n = res_search(name, C_IN, type, buf.buf, sizeof(buf))) < 0) {
+ dprintf("res_search failed (%d)\n", n);
+ if (errno == ECONNREFUSED)
+ return (_gethtbyname2(name, af));
+ return (NULL);
+ }
+ return (getanswer(&buf, n, name, type));
+}
+
+struct hostent *
+gethostbyaddr(addr, len, af)
+ const char *addr; /* XXX should have been def'd as u_char! */
+ int len, af;
+{
+ const u_char *uaddr = (const u_char *)addr;
+ static const u_char mapped[] = { 0,0, 0,0, 0,0, 0,0, 0,0, 0xff,0xff };
+ static const u_char tunnelled[] = { 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 };
+ int n, size;
+ querybuf buf;
+ register struct hostent *hp;
+ char qbuf[MAXDNAME+1], *qp;
+#ifdef SUNSECURITY
+ register struct hostent *rhp;
+ char **haddr;
+ u_long old_options;
+ char hname2[MAXDNAME+1];
+#endif /*SUNSECURITY*/
+ extern struct hostent *_gethtbyaddr();
+
+ if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
+ h_errno = NETDB_INTERNAL;
+ return (NULL);
+ }
+ if (af == AF_INET6 && len == IN6ADDRSZ &&
+ (!bcmp(uaddr, mapped, sizeof mapped) ||
+ !bcmp(uaddr, tunnelled, sizeof tunnelled))) {
+ /* Unmap. */
+ addr += sizeof mapped;
+ uaddr += sizeof mapped;
+ af = AF_INET;
+ len = INADDRSZ;
+ }
+ switch (af) {
+ case AF_INET:
+ size = INADDRSZ;
+ break;
+ case AF_INET6:
+ size = IN6ADDRSZ;
+ break;
+ default:
+ errno = EAFNOSUPPORT;
+ h_errno = NETDB_INTERNAL;
+ return (NULL);
+ }
+ if (size != len) {
+ errno = EINVAL;
+ h_errno = NETDB_INTERNAL;
+ return (NULL);
+ }
+ switch (af) {
+ case AF_INET:
+ (void) sprintf(qbuf, "%u.%u.%u.%u.in-addr.arpa",
+ (uaddr[3] & 0xff),
+ (uaddr[2] & 0xff),
+ (uaddr[1] & 0xff),
+ (uaddr[0] & 0xff));
+ break;
+ case AF_INET6:
+ qp = qbuf;
+ for (n = IN6ADDRSZ - 1; n >= 0; n--) {
+ qp += SPRINTF((qp, "%x.%x.",
+ uaddr[n] & 0xf,
+ (uaddr[n] >> 4) & 0xf));
+ }
+ strcpy(qp, "ip6.int");
+ break;
+ default:
+ abort();
+ }
+ n = res_query(qbuf, C_IN, T_PTR, (u_char *)buf.buf, sizeof buf.buf);
+ if (n < 0) {
+ dprintf("res_query failed (%d)\n", n);
+ if (errno == ECONNREFUSED)
+ return (_gethtbyaddr(addr, len, af));
+ return (NULL);
+ }
+ if (!(hp = getanswer(&buf, n, qbuf, T_PTR)))
+ return (NULL); /* h_errno was set by getanswer() */
+#ifdef SUNSECURITY
+ if (af == AF_INET) {
+ /*
+ * turn off search as the name should be absolute,
+ * 'localhost' should be matched by defnames
+ */
+ strncpy(hname2, hp->h_name, MAXDNAME);
+ hname2[MAXDNAME] = '\0';
+ old_options = _res.options;
+ _res.options &= ~RES_DNSRCH;
+ _res.options |= RES_DEFNAMES;
+ if (!(rhp = gethostbyname(hname2))) {
+ syslog(LOG_NOTICE|LOG_AUTH,
+ "gethostbyaddr: No A record for %s (verifying [%s])",
+ hname2, inet_ntoa(*((struct in_addr *)addr)));
+ _res.options = old_options;
+ h_errno = HOST_NOT_FOUND;
+ return (NULL);
+ }
+ _res.options = old_options;
+ for (haddr = rhp->h_addr_list; *haddr; haddr++)
+ if (!memcmp(*haddr, addr, INADDRSZ))
+ break;
+ if (!*haddr) {
+ syslog(LOG_NOTICE|LOG_AUTH,
+ "gethostbyaddr: A record of %s != PTR record [%s]",
+ hname2, inet_ntoa(*((struct in_addr *)addr)));
+ h_errno = HOST_NOT_FOUND;
+ return (NULL);
+ }
+ }
+#endif /*SUNSECURITY*/
+ hp->h_addrtype = af;
+ hp->h_length = len;
+ bcopy(addr, host_addr, len);
+ h_addr_ptrs[0] = (char *)host_addr;
+ h_addr_ptrs[1] = NULL;
+ if (af == AF_INET && (_res.options & RES_USE_INET6)) {
+ map_v4v6_address((char*)host_addr, (char*)host_addr);
+ hp->h_addrtype = AF_INET6;
+ hp->h_length = IN6ADDRSZ;
+ }
+ h_errno = NETDB_SUCCESS;
+ return (hp);
+}
+
+void
+_sethtent(f)
+ int f;
+{
+ if (!hostf)
+ hostf = fopen(_PATH_HOSTS, "r" );
+ else
+ rewind(hostf);
+ stayopen = f;
+}
+
+void
+_endhtent()
+{
+ if (hostf && !stayopen) {
+ (void) fclose(hostf);
+ hostf = NULL;
+ }
+}
+
+struct hostent *
+_gethtent()
+{
+ char *p;
+ register char *cp, **q;
+ int af, len;
+
+ if (!hostf && !(hostf = fopen(_PATH_HOSTS, "r" ))) {
+ h_errno = NETDB_INTERNAL;
+ return (NULL);
+ }
+ again:
+ if (!(p = fgets(hostbuf, sizeof hostbuf, hostf))) {
+ h_errno = HOST_NOT_FOUND;
+ return (NULL);
+ }
+ if (*p == '#')
+ goto again;
+ if (!(cp = strpbrk(p, "#\n")))
+ goto again;
+ *cp = '\0';
+ if (!(cp = strpbrk(p, " \t")))
+ goto again;
+ *cp++ = '\0';
+ if ((_res.options & RES_USE_INET6) &&
+ inet_pton(AF_INET6, p, host_addr) > 0) {
+ af = AF_INET6;
+ len = IN6ADDRSZ;
+ } else if (inet_pton(AF_INET, p, host_addr) > 0) {
+ if (_res.options & RES_USE_INET6) {
+ map_v4v6_address((char*)host_addr, (char*)host_addr);
+ af = AF_INET6;
+ len = IN6ADDRSZ;
+ } else {
+ af = AF_INET;
+ len = INADDRSZ;
+ }
+ } else {
+ goto again;
+ }
+ h_addr_ptrs[0] = (char *)host_addr;
+ h_addr_ptrs[1] = NULL;
+ host.h_addr_list = h_addr_ptrs;
+ host.h_length = len;
+ host.h_addrtype = af;
+ while (*cp == ' ' || *cp == '\t')
+ cp++;
+ host.h_name = cp;
+ q = host.h_aliases = host_aliases;
+ if (cp = strpbrk(cp, " \t"))
+ *cp++ = '\0';
+ while (cp && *cp) {
+ if (*cp == ' ' || *cp == '\t') {
+ cp++;
+ continue;
+ }
+ if (q < &host_aliases[MAXALIASES - 1])
+ *q++ = cp;
+ if (cp = strpbrk(cp, " \t"))
+ *cp++ = '\0';
+ }
+ *q = NULL;
+ if (_res.options & RES_USE_INET6) {
+ char *bp = hostbuf;
+ int buflen = sizeof hostbuf;
+
+ map_v4v6_hostent(&host, &bp, &buflen);
+ }
+ h_errno = NETDB_SUCCESS;
+ return (&host);
+}
+
+struct hostent *
+_gethtbyname(name)
+ const char *name;
+{
+ extern struct hostent *_gethtbyname2();
+ struct hostent *hp;
+
+ if (_res.options & RES_USE_INET6) {
+ hp = _gethtbyname2(name, AF_INET6);
+ if (hp)
+ return (hp);
+ }
+ return (_gethtbyname2(name, AF_INET));
+}
+
+struct hostent *
+_gethtbyname2(name, af)
+ const char *name;
+ int af;
+{
+ register struct hostent *p;
+ register char **cp;
+
+ _sethtent(0);
+ while (p = _gethtent()) {
+ if (p->h_addrtype != af)
+ continue;
+ if (strcasecmp(p->h_name, name) == 0)
+ break;
+ for (cp = p->h_aliases; *cp != 0; cp++)
+ if (strcasecmp(*cp, name) == 0)
+ goto found;
+ }
+ found:
+ _endhtent();
+ return (p);
+}
+
+struct hostent *
+_gethtbyaddr(addr, len, af)
+ const char *addr;
+ int len, af;
+{
+ register struct hostent *p;
+
+ _sethtent(0);
+ while (p = _gethtent())
+ if (p->h_addrtype == af && !bcmp(p->h_addr, addr, len))
+ break;
+ _endhtent();
+ return (p);
+}
+
+static void
+map_v4v6_address(src, dst)
+ const char *src;
+ char *dst;
+{
+ u_char *p = (u_char *)dst;
+ char tmp[INADDRSZ];
+ int i;
+
+ /* Stash a temporary copy so our caller can update in place. */
+ bcopy(src, tmp, INADDRSZ);
+ /* Mark this ipv6 addr as a mapped ipv4. */
+ for (i = 0; i < 10; i++)
+ *p++ = 0x00;
+ *p++ = 0xff;
+ *p++ = 0xff;
+ /* Retrieve the saved copy and we're done. */
+ bcopy(tmp, (void*)p, INADDRSZ);
+}
+
+static void
+map_v4v6_hostent(hp, bpp, lenp)
+ struct hostent *hp;
+ char **bpp;
+ int *lenp;
+{
+ char **ap;
+
+ if (hp->h_addrtype != AF_INET || hp->h_length != INADDRSZ)
+ return;
+ hp->h_addrtype = AF_INET6;
+ hp->h_length = IN6ADDRSZ;
+ for (ap = hp->h_addr_list; *ap; ap++) {
+ int i = sizeof(align) - ((u_long)*bpp % sizeof(align));
+
+ if (*lenp < (i + IN6ADDRSZ)) {
+ /* Out of memory. Truncate address list here. XXX */
+ *ap = NULL;
+ return;
+ }
+ *bpp += i;
+ *lenp -= i;
+ map_v4v6_address(*ap, *bpp);
+ *ap = *bpp;
+ *bpp += IN6ADDRSZ;
+ *lenp -= IN6ADDRSZ;
+ }
+}
+
+#ifdef RESOLVSORT
+static void
+addrsort(ap, num)
+ char **ap;
+ int num;
+{
+ int i, j;
+ char **p;
+ short aval[MAXADDRS];
+ int needsort = 0;
+
+ p = ap;
+ for (i = 0; i < num; i++, p++) {
+ for (j = 0 ; (unsigned)j < _res.nsort; j++)
+ if (_res.sort_list[j].addr.s_addr ==
+ (((struct in_addr *)(*p))->s_addr & _res.sort_list[j].mask))
+ break;
+ aval[i] = j;
+ if (needsort == 0 && i > 0 && j < aval[i-1])
+ needsort = i;
+ }
+ if (!needsort)
+ return;
+
+ while (needsort < num) {
+ for (j = needsort - 1; j >= 0; j--) {
+ if (aval[j] > aval[j+1]) {
+ char *hp;
+
+ i = aval[j];
+ aval[j] = aval[j+1];
+ aval[j+1] = i;
+
+ hp = ap[j];
+ ap[j] = ap[j+1];
+ ap[j+1] = hp;
+
+ } else
+ break;
+ }
+ needsort++;
+ }
+}
+#endif
+
+#if defined(BSD43_BSD43_NFS) || defined(sun)
+/* some libc's out there are bound internally to these names (UMIPS) */
+void
+ht_sethostent(stayopen)
+ int stayopen;
+{
+ _sethtent(stayopen);
+}
+
+void
+ht_endhostent()
+{
+ _endhtent();
+}
+
+struct hostent *
+ht_gethostbyname(name)
+ char *name;
+{
+ return (_gethtbyname(name));
+}
+
+struct hostent *
+ht_gethostbyaddr(addr, len, af)
+ const char *addr;
+ int len, af;
+{
+ return (_gethtbyaddr(addr, len, af));
+}
+
+struct hostent *
+gethostent()
+{
+ return (_gethtent());
+}
+
+void
+dns_service()
+{
+ return;
+}
+
+#undef dn_skipname
+dn_skipname(comp_dn, eom)
+ const u_char *comp_dn, *eom;
+{
+ return (__dn_skipname(comp_dn, eom));
+}
+#endif /*old-style libc with yp junk in it*/
diff --git a/contrib/bind/res/getnetbyaddr.c b/contrib/bind/res/getnetbyaddr.c
new file mode 100644
index 0000000..b847730
--- /dev/null
+++ b/contrib/bind/res/getnetbyaddr.c
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)getnetbyaddr.c 1.1 (Coimbra) 93/06/02";
+static char rcsid[] = "$Id: getnetbyaddr.c,v 8.2 1996/05/09 05:59:13 vixie Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <netdb.h>
+
+extern int _net_stayopen;
+
+struct netent *
+_getnetbyaddr(net, type)
+ register unsigned long net;
+ register int type;
+{
+ register struct netent *p;
+
+ setnetent(_net_stayopen);
+ while (p = getnetent())
+ if (p->n_addrtype == type && p->n_net == net)
+ break;
+ if (!_net_stayopen)
+ endnetent();
+ return (p);
+}
diff --git a/contrib/bind/res/getnetbyname.c b/contrib/bind/res/getnetbyname.c
new file mode 100644
index 0000000..6bf450d
--- /dev/null
+++ b/contrib/bind/res/getnetbyname.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 1983, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)getnetbyname.c 8.1 (Berkeley) 6/4/93";
+static char sccsid_[] = "from getnetbyname.c 1.1 (Coimbra) 93/06/02";
+static char rcsid[] = "$Id: getnetbyname.c,v 8.2 1995/06/19 08:35:01 vixie Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <netdb.h>
+#include <string.h>
+
+extern int _net_stayopen;
+
+struct netent *
+_getnetbyname(name)
+ register const char *name;
+{
+ register struct netent *p;
+ register char **cp;
+
+ setnetent(_net_stayopen);
+ while (p = getnetent()) {
+ if (strcasecmp(p->n_name, name) == 0)
+ break;
+ for (cp = p->n_aliases; *cp != 0; cp++)
+ if (strcasecmp(*cp, name) == 0)
+ goto found;
+ }
+found:
+ if (!_net_stayopen)
+ endnetent();
+ return (p);
+}
diff --git a/contrib/bind/res/getnetent.c b/contrib/bind/res/getnetent.c
new file mode 100644
index 0000000..24ee286
--- /dev/null
+++ b/contrib/bind/res/getnetent.c
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/* Portions Copyright (c) 1993 Carlos Leandro and Rui Salgueiro
+ * Dep. Matematica Universidade de Coimbra, Portugal, Europe
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * from getnetent.c 1.1 (Coimbra) 93/06/02
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)getnetent.c 8.1 (Berkeley) 6/4/93";
+static char rcsid[] = "$Id: getnetent.c,v 8.3 1996/08/05 08:31:35 vixie Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+
+#include <stdio.h>
+#include <resolv.h>
+#include <netdb.h>
+#include <string.h>
+
+#ifndef _PATH_NETWORKS
+#define _PATH_NETWORKS "/etc/networks"
+#endif
+
+#define MAXALIASES 35
+
+static FILE *netf;
+static char line[BUFSIZ+1];
+static struct netent net;
+static char *net_aliases[MAXALIASES];
+int _net_stayopen;
+
+void _setnetent __P((int));
+void _endnetent __P((void));
+
+void
+setnetent(stayopen)
+ int stayopen;
+{
+
+ sethostent(stayopen);
+ _setnetent(stayopen);
+}
+
+void
+endnetent()
+{
+
+ endhostent();
+ _endnetent();
+}
+
+void
+_setnetent(f)
+ int f;
+{
+
+ if (netf == NULL)
+ netf = fopen(_PATH_NETWORKS, "r" );
+ else
+ rewind(netf);
+ _net_stayopen |= f;
+}
+
+void
+_endnetent()
+{
+
+ if (netf) {
+ fclose(netf);
+ netf = NULL;
+ }
+ _net_stayopen = 0;
+}
+
+struct netent *
+getnetent()
+{
+ char *p;
+ register char *cp, **q;
+
+ if (netf == NULL && (netf = fopen(_PATH_NETWORKS, "r" )) == NULL)
+ return (NULL);
+again:
+ p = fgets(line, BUFSIZ, netf);
+ if (p == NULL)
+ return (NULL);
+ if (*p == '#')
+ goto again;
+ cp = strpbrk(p, "#\n");
+ if (cp == NULL)
+ goto again;
+ *cp = '\0';
+ net.n_name = p;
+ cp = strpbrk(p, " \t");
+ if (cp == NULL)
+ goto again;
+ *cp++ = '\0';
+ while (*cp == ' ' || *cp == '\t')
+ cp++;
+ p = strpbrk(cp, " \t");
+ if (p != NULL)
+ *p++ = '\0';
+ net.n_net = inet_network(cp);
+ net.n_addrtype = AF_INET;
+ q = net.n_aliases = net_aliases;
+ if (p != NULL) {
+ cp = p;
+ while (cp && *cp) {
+ if (*cp == ' ' || *cp == '\t') {
+ cp++;
+ continue;
+ }
+ if (q < &net_aliases[MAXALIASES - 1])
+ *q++ = cp;
+ cp = strpbrk(cp, " \t");
+ if (cp != NULL)
+ *cp++ = '\0';
+ }
+ }
+ *q = NULL;
+ return (&net);
+}
diff --git a/contrib/bind/res/getnetnamadr.c b/contrib/bind/res/getnetnamadr.c
new file mode 100644
index 0000000..d2f33a1
--- /dev/null
+++ b/contrib/bind/res/getnetnamadr.c
@@ -0,0 +1,288 @@
+/* Copyright (c) 1993 Carlos Leandro and Rui Salgueiro
+ * Dep. Matematica Universidade de Coimbra, Portugal, Europe
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ */
+/*
+ * Copyright (c) 1983, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)getnetbyaddr.c 8.1 (Berkeley) 6/4/93";
+static char sccsid_[] = "from getnetnamadr.c 1.4 (Coimbra) 93/06/03";
+static char rcsid[] = "$Id: getnetnamadr.c,v 8.7 1996/08/05 08:31:35 vixie Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+
+#include <stdio.h>
+#include <netdb.h>
+#include <resolv.h>
+#include <ctype.h>
+#include <errno.h>
+#include <string.h>
+
+extern int h_errno;
+
+#if defined(mips) && defined(SYSTYPE_BSD43)
+extern int errno;
+#endif
+
+struct netent *_getnetbyaddr __P((long net, int type));
+struct netent *_getnetbyname __P((const char *name));
+
+#define BYADDR 0
+#define BYNAME 1
+#define MAXALIASES 35
+
+#if PACKETSZ > 1024
+#define MAXPACKET PACKETSZ
+#else
+#define MAXPACKET 1024
+#endif
+
+typedef union {
+ HEADER hdr;
+ u_char buf[MAXPACKET];
+} querybuf;
+
+typedef union {
+ long al;
+ char ac;
+} align;
+
+static struct netent *
+getnetanswer(answer, anslen, net_i)
+ querybuf *answer;
+ int anslen;
+ int net_i;
+{
+
+ register HEADER *hp;
+ register u_char *cp;
+ register int n;
+ u_char *eom;
+ int type, class, buflen, ancount, qdcount, haveanswer, i, nchar;
+ char aux1[30], aux2[30], ans[30], *in, *st, *pauxt, *bp, **ap,
+ *paux1 = &aux1[0], *paux2 = &aux2[0], flag = 0;
+static struct netent net_entry;
+static char *net_aliases[MAXALIASES], netbuf[BUFSIZ+1];
+
+ /*
+ * find first satisfactory answer
+ *
+ * answer --> +------------+ ( MESSAGE )
+ * | Header |
+ * +------------+
+ * | Question | the question for the name server
+ * +------------+
+ * | Answer | RRs answering the question
+ * +------------+
+ * | Authority | RRs pointing toward an authority
+ * | Additional | RRs holding additional information
+ * +------------+
+ */
+ eom = answer->buf + anslen;
+ hp = &answer->hdr;
+ ancount = ntohs(hp->ancount); /* #/records in the answer section */
+ qdcount = ntohs(hp->qdcount); /* #/entries in the question section */
+ bp = netbuf;
+ buflen = sizeof(netbuf);
+ cp = answer->buf + HFIXEDSZ;
+ if (!qdcount) {
+ if (hp->aa)
+ h_errno = HOST_NOT_FOUND;
+ else
+ h_errno = TRY_AGAIN;
+ return (NULL);
+ }
+ while (qdcount-- > 0)
+ cp += __dn_skipname(cp, eom) + QFIXEDSZ;
+ ap = net_aliases;
+ *ap = NULL;
+ net_entry.n_aliases = net_aliases;
+ haveanswer = 0;
+ while (--ancount >= 0 && cp < eom) {
+ n = dn_expand(answer->buf, eom, cp, bp, buflen);
+ if ((n < 0) || !res_dnok(bp))
+ break;
+ cp += n;
+ ans[0] = '\0';
+ (void)strcpy(&ans[0], bp);
+ GETSHORT(type, cp);
+ GETSHORT(class, cp);
+ cp += INT32SZ; /* TTL */
+ GETSHORT(n, cp);
+ if (class == C_IN && type == T_PTR) {
+ n = dn_expand(answer->buf, eom, cp, bp, buflen);
+ if ((n < 0) || !res_hnok(bp)) {
+ cp += n;
+ return (NULL);
+ }
+ cp += n;
+ *ap++ = bp;
+ bp += strlen(bp) + 1;
+ net_entry.n_addrtype =
+ (class == C_IN) ? AF_INET : AF_UNSPEC;
+ haveanswer++;
+ }
+ }
+ if (haveanswer) {
+ *ap = NULL;
+ switch (net_i) {
+ case BYADDR:
+ net_entry.n_name = *net_entry.n_aliases;
+ net_entry.n_net = 0L;
+ break;
+ case BYNAME:
+ in = *net_entry.n_aliases;
+ net_entry.n_name = &ans[0];
+ aux2[0] = '\0';
+ for (i = 0; i < 4; i++) {
+ for (st = in, nchar = 0;
+ *st != '.';
+ st++, nchar++)
+ ;
+ if (nchar != 1 || *in != '0' || flag) {
+ flag = 1;
+ (void)strncpy(paux1,
+ (i==0) ? in : in-1,
+ (i==0) ?nchar : nchar+1);
+ paux1[(i==0) ? nchar : nchar+1] = '\0';
+ pauxt = paux2;
+ paux2 = strcat(paux1, paux2);
+ paux1 = pauxt;
+ }
+ in = ++st;
+ }
+ net_entry.n_net = inet_network(paux2);
+ break;
+ }
+ net_entry.n_aliases++;
+ return (&net_entry);
+ }
+ h_errno = TRY_AGAIN;
+ return (NULL);
+}
+
+struct netent *
+getnetbyaddr(net, net_type)
+ register u_long net;
+ register int net_type;
+{
+ unsigned int netbr[4];
+ int nn, anslen;
+ querybuf buf;
+ char qbuf[MAXDNAME];
+ unsigned long net2;
+ struct netent *net_entry;
+
+ if (net_type != AF_INET)
+ return (_getnetbyaddr(net, net_type));
+
+ for (nn = 4, net2 = net; net2; net2 >>= 8)
+ netbr[--nn] = net2 & 0xff;
+ switch (nn) {
+ case 3: /* Class A */
+ sprintf(qbuf, "0.0.0.%u.in-addr.arpa", netbr[3]);
+ break;
+ case 2: /* Class B */
+ sprintf(qbuf, "0.0.%u.%u.in-addr.arpa", netbr[3], netbr[2]);
+ break;
+ case 1: /* Class C */
+ sprintf(qbuf, "0.%u.%u.%u.in-addr.arpa", netbr[3], netbr[2],
+ netbr[1]);
+ break;
+ case 0: /* Class D - E */
+ sprintf(qbuf, "%u.%u.%u.%u.in-addr.arpa", netbr[3], netbr[2],
+ netbr[1], netbr[0]);
+ break;
+ }
+ anslen = res_query(qbuf, C_IN, T_PTR, (u_char *)&buf, sizeof(buf));
+ if (anslen < 0) {
+#ifdef DEBUG
+ if (_res.options & RES_DEBUG)
+ printf("res_query failed\n");
+#endif
+ if (errno == ECONNREFUSED)
+ return (_getnetbyaddr(net, net_type));
+ return (NULL);
+ }
+ net_entry = getnetanswer(&buf, anslen, BYADDR);
+ if (net_entry) {
+ unsigned u_net = net; /* maybe net should be unsigned ? */
+
+ /* Strip trailing zeros */
+ while ((u_net & 0xff) == 0 && u_net != 0)
+ u_net >>= 8;
+ net_entry->n_net = u_net;
+ return (net_entry);
+ }
+ return (_getnetbyaddr(net, net_type));
+}
+
+struct netent *
+getnetbyname(net)
+ register const char *net;
+{
+ int anslen;
+ querybuf buf;
+ char qbuf[MAXDNAME];
+ struct netent *net_entry;
+
+ if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
+ h_errno = NETDB_INTERNAL;
+ return (NULL);
+ }
+ strcpy(&qbuf[0], net);
+ anslen = res_search(qbuf, C_IN, T_PTR, (u_char *)&buf, sizeof(buf));
+ if (anslen < 0) {
+#ifdef DEBUG
+ if (_res.options & RES_DEBUG)
+ printf("res_query failed\n");
+#endif
+ if (errno == ECONNREFUSED)
+ return (_getnetbyname(net));
+ return (_getnetbyname(net));
+ }
+ net_entry = getnetanswer(&buf, anslen, BYNAME);
+ if (net_entry)
+ return (net_entry);
+ return (_getnetbyname(net));
+}
diff --git a/contrib/bind/res/herror.c b/contrib/bind/res/herror.c
new file mode 100644
index 0000000..6d88b49
--- /dev/null
+++ b/contrib/bind/res/herror.c
@@ -0,0 +1,119 @@
+/*
+ * ++Copyright++ 1987, 1993
+ * -
+ * Copyright (c) 1987, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * -
+ * Portions Copyright (c) 1993 by Digital Equipment Corporation.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies, and that
+ * the name of Digital Equipment Corporation not be used in advertising or
+ * publicity pertaining to distribution of the document or software without
+ * specific, written prior permission.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
+ * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ * -
+ * --Copyright--
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)herror.c 8.1 (Berkeley) 6/4/93";
+static char rcsid[] = "$Id: herror.c,v 8.3 1996/08/05 08:31:35 vixie Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/uio.h>
+#include <netdb.h>
+#if defined(BSD) && (BSD >= 199103)
+# include <unistd.h>
+# include <string.h>
+#else
+# include "../conf/portability.h"
+#endif
+
+const char *h_errlist[] = {
+ "Resolver Error 0 (no error)",
+ "Unknown host", /* 1 HOST_NOT_FOUND */
+ "Host name lookup failure", /* 2 TRY_AGAIN */
+ "Unknown server error", /* 3 NO_RECOVERY */
+ "No address associated with name", /* 4 NO_ADDRESS */
+};
+int h_nerr = { sizeof h_errlist / sizeof h_errlist[0] };
+
+extern int h_errno;
+
+/*
+ * herror --
+ * print the error indicated by the h_errno value.
+ */
+void
+herror(s)
+ const char *s;
+{
+ struct iovec iov[4];
+ register struct iovec *v = iov;
+
+ if (s && *s) {
+ v->iov_base = (char *)s;
+ v->iov_len = strlen(s);
+ v++;
+ v->iov_base = ": ";
+ v->iov_len = 2;
+ v++;
+ }
+ v->iov_base = (char *)hstrerror(h_errno);
+ v->iov_len = strlen(v->iov_base);
+ v++;
+ v->iov_base = "\n";
+ v->iov_len = 1;
+ writev(STDERR_FILENO, iov, (v - iov) + 1);
+}
+
+const char *
+hstrerror(err)
+ int err;
+{
+ if (err < 0)
+ return ("Resolver internal error");
+ else if (err < h_nerr)
+ return (h_errlist[err]);
+ return ("Unknown resolver error");
+}
diff --git a/contrib/bind/res/hostnamelen.c b/contrib/bind/res/hostnamelen.c
new file mode 100644
index 0000000..9388062
--- /dev/null
+++ b/contrib/bind/res/hostnamelen.c
@@ -0,0 +1,94 @@
+/*
+ * ++Copyright++ 1995
+ * -
+ * Copyright (c) 1995
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * -
+ * Portions Copyright (c) 1993 by Digital Equipment Corporation.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies, and that
+ * the name of Digital Equipment Corporation not be used in advertising or
+ * publicity pertaining to distribution of the document or software without
+ * specific, written prior permission.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
+ * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ * -
+ * --Copyright--
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char rcsid[] = "$Id: hostnamelen.c,v 8.2 1995/08/22 05:01:47 vixie Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <resolv.h>
+
+#if defined(BSD) && (BSD >= 199103)
+# include <string.h>
+#else
+# include "../conf/portability.h"
+#endif
+#if defined(USE_OPTIONS_H)
+# include <../conf/options.h>
+#endif
+
+#ifndef ultrix
+int __local_hostname_length_unneeded;
+#else
+int
+local_hostname_length(hostname)
+ const char *hostname;
+{
+ int len_host, len_domain;
+
+ if (!*_res.defdname)
+ res_init();
+ len_host = strlen(hostname);
+ len_domain = strlen(_res.defdname);
+ if (len_host > len_domain &&
+ !strcasecmp(hostname + len_host - len_domain, _res.defdname) &&
+ hostname[len_host - len_domain - 1] == '.')
+ return (len_host - len_domain - 1);
+ return (0);
+}
+#endif
diff --git a/contrib/bind/res/inet_addr.c b/contrib/bind/res/inet_addr.c
new file mode 100644
index 0000000..6f66869
--- /dev/null
+++ b/contrib/bind/res/inet_addr.c
@@ -0,0 +1,184 @@
+/*
+ * ++Copyright++ 1983, 1990, 1993
+ * -
+ * Copyright (c) 1983, 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * -
+ * Portions Copyright (c) 1993 by Digital Equipment Corporation.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies, and that
+ * the name of Digital Equipment Corporation not be used in advertising or
+ * publicity pertaining to distribution of the document or software without
+ * specific, written prior permission.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
+ * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ * -
+ * --Copyright--
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)inet_addr.c 8.1 (Berkeley) 6/17/93";
+static char rcsid[] = "$Id: inet_addr.c,v 8.5 1996/08/05 08:31:35 vixie Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <ctype.h>
+#include "../conf/portability.h"
+
+/* these are compatibility routines, not needed on recent BSD releases */
+
+/*
+ * Ascii internet address interpretation routine.
+ * The value returned is in network order.
+ */
+u_long
+inet_addr(cp)
+ register const char *cp;
+{
+ struct in_addr val;
+
+ if (inet_aton(cp, &val))
+ return (val.s_addr);
+ return (INADDR_NONE);
+}
+
+/*
+ * Check whether "cp" is a valid ascii representation
+ * of an Internet address and convert to a binary address.
+ * Returns 1 if the address is valid, 0 if not.
+ * This replaces inet_addr, the return value from which
+ * cannot distinguish between failure and a local broadcast address.
+ */
+int
+inet_aton(cp, addr)
+ register const char *cp;
+ struct in_addr *addr;
+{
+ register u_long val;
+ register int base, n;
+ register char c;
+ u_int parts[4];
+ register u_int *pp = parts;
+
+ c = *cp;
+ for (;;) {
+ /*
+ * Collect number up to ``.''.
+ * Values are specified as for C:
+ * 0x=hex, 0=octal, isdigit=decimal.
+ */
+ if (!isdigit(c))
+ return (0);
+ val = 0; base = 10;
+ if (c == '0') {
+ c = *++cp;
+ if (c == 'x' || c == 'X')
+ base = 16, c = *++cp;
+ else
+ base = 8;
+ }
+ for (;;) {
+ if (isascii(c) && isdigit(c)) {
+ val = (val * base) + (c - '0');
+ c = *++cp;
+ } else if (base == 16 && isascii(c) && isxdigit(c)) {
+ val = (val << 4) |
+ (c + 10 - (islower(c) ? 'a' : 'A'));
+ c = *++cp;
+ } else
+ break;
+ }
+ if (c == '.') {
+ /*
+ * Internet format:
+ * a.b.c.d
+ * a.b.c (with c treated as 16 bits)
+ * a.b (with b treated as 24 bits)
+ */
+ if (pp >= parts + 3)
+ return (0);
+ *pp++ = val;
+ c = *++cp;
+ } else
+ break;
+ }
+ /*
+ * Check for trailing characters.
+ */
+ if (c != '\0' && (!isascii(c) || !isspace(c)))
+ return (0);
+ /*
+ * Concoct the address according to
+ * the number of parts specified.
+ */
+ n = pp - parts + 1;
+ switch (n) {
+
+ case 0:
+ return (0); /* initial nondigit */
+
+ case 1: /* a -- 32 bits */
+ break;
+
+ case 2: /* a.b -- 8.24 bits */
+ if (val > 0xffffff)
+ return (0);
+ val |= parts[0] << 24;
+ break;
+
+ case 3: /* a.b.c -- 8.8.16 bits */
+ if (val > 0xffff)
+ return (0);
+ val |= (parts[0] << 24) | (parts[1] << 16);
+ break;
+
+ case 4: /* a.b.c.d -- 8.8.8.8 bits */
+ if (val > 0xff)
+ return (0);
+ val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
+ break;
+ }
+ if (addr)
+ addr->s_addr = htonl(val);
+ return (1);
+}
diff --git a/contrib/bind/res/inet_ntop.c b/contrib/bind/res/inet_ntop.c
new file mode 100644
index 0000000..3fd8506
--- /dev/null
+++ b/contrib/bind/res/inet_ntop.c
@@ -0,0 +1,195 @@
+/* Copyright (c) 1996 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char rcsid[] = "$Id: inet_ntop.c,v 8.7 1996/08/05 08:41:18 vixie Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+#include <string.h>
+#include <errno.h>
+#include <stdio.h>
+#include "../conf/portability.h"
+
+#ifdef SPRINTF_CHAR
+# define SPRINTF(x) strlen(sprintf/**/x)
+#else
+# define SPRINTF(x) ((size_t)sprintf x)
+#endif
+
+/*
+ * WARNING: Don't even consider trying to compile this on a system where
+ * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX.
+ */
+
+static const char *inet_ntop4 __P((const u_char *src, char *dst, size_t size));
+static const char *inet_ntop6 __P((const u_char *src, char *dst, size_t size));
+
+/* char *
+ * inet_ntop(af, src, dst, size)
+ * convert a network format address to presentation format.
+ * return:
+ * pointer to presentation format address (`dst'), or NULL (see errno).
+ * author:
+ * Paul Vixie, 1996.
+ */
+const char *
+inet_ntop(af, src, dst, size)
+ int af;
+ const void *src;
+ char *dst;
+ size_t size;
+{
+ switch (af) {
+ case AF_INET:
+ return (inet_ntop4(src, dst, size));
+ case AF_INET6:
+ return (inet_ntop6(src, dst, size));
+ default:
+ errno = EAFNOSUPPORT;
+ return (NULL);
+ }
+ /* NOTREACHED */
+}
+
+/* const char *
+ * inet_ntop4(src, dst, size)
+ * format an IPv4 address, more or less like inet_ntoa()
+ * return:
+ * `dst' (as a const)
+ * notes:
+ * (1) uses no statics
+ * (2) takes a u_char* not an in_addr as input
+ * author:
+ * Paul Vixie, 1996.
+ */
+static const char *
+inet_ntop4(src, dst, size)
+ const u_char *src;
+ char *dst;
+ size_t size;
+{
+ static const char fmt[] = "%u.%u.%u.%u";
+ char tmp[sizeof "255.255.255.255"];
+
+ if (SPRINTF((tmp, fmt, src[0], src[1], src[2], src[3])) > size) {
+ errno = ENOSPC;
+ return (NULL);
+ }
+ strcpy(dst, tmp);
+ return (dst);
+}
+
+/* const char *
+ * inet_ntop6(src, dst, size)
+ * convert IPv6 binary address into presentation (printable) format
+ * author:
+ * Paul Vixie, 1996.
+ */
+static const char *
+inet_ntop6(src, dst, size)
+ const u_char *src;
+ char *dst;
+ size_t size;
+{
+ /*
+ * Note that int32_t and int16_t need only be "at least" large enough
+ * to contain a value of the specified size. On some systems, like
+ * Crays, there is no such thing as an integer variable with 16 bits.
+ * Keep this in mind if you think this function should have been coded
+ * to use pointer overlays. All the world's not a VAX.
+ */
+ char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp;
+ struct { int base, len; } best, cur;
+ u_int words[IN6ADDRSZ / INT16SZ];
+ int i;
+
+ /*
+ * Preprocess:
+ * Copy the input (bytewise) array into a wordwise array.
+ * Find the longest run of 0x00's in src[] for :: shorthanding.
+ */
+ memset(words, '\0', sizeof words);
+ for (i = 0; i < IN6ADDRSZ; i++)
+ words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3));
+ best.base = -1;
+ cur.base = -1;
+ for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) {
+ if (words[i] == 0) {
+ if (cur.base == -1)
+ cur.base = i, cur.len = 1;
+ else
+ cur.len++;
+ } else {
+ if (cur.base != -1) {
+ if (best.base == -1 || cur.len > best.len)
+ best = cur;
+ cur.base = -1;
+ }
+ }
+ }
+ if (cur.base != -1) {
+ if (best.base == -1 || cur.len > best.len)
+ best = cur;
+ }
+ if (best.base != -1 && best.len < 2)
+ best.base = -1;
+
+ /*
+ * Format the result.
+ */
+ tp = tmp;
+ for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) {
+ /* Are we inside the best run of 0x00's? */
+ if (best.base != -1 && i >= best.base &&
+ i < (best.base + best.len)) {
+ if (i == best.base)
+ *tp++ = ':';
+ continue;
+ }
+ /* Are we following an initial run of 0x00s or any real hex? */
+ if (i != 0)
+ *tp++ = ':';
+ /* Is this address an encapsulated IPv4? */
+ if (i == 6 && best.base == 0 &&
+ (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) {
+ if (!inet_ntop4(src+12, tp, sizeof tmp - (tp - tmp)))
+ return (NULL);
+ tp += strlen(tp);
+ break;
+ }
+ tp += SPRINTF((tp, "%x", words[i]));
+ }
+ /* Was it a trailing run of 0x00's? */
+ if (best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ))
+ *tp++ = ':';
+ *tp++ = '\0';
+
+ /*
+ * Check for overflow, copy, and we're done.
+ */
+ if ((size_t)(tp - tmp) > size) {
+ errno = ENOSPC;
+ return (NULL);
+ }
+ strcpy(dst, tmp);
+ return (dst);
+}
diff --git a/contrib/bind/res/inet_pton.c b/contrib/bind/res/inet_pton.c
new file mode 100644
index 0000000..244107b
--- /dev/null
+++ b/contrib/bind/res/inet_pton.c
@@ -0,0 +1,215 @@
+/* Copyright (c) 1996 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char rcsid[] = "$Id: inet_pton.c,v 8.7 1996/08/05 08:31:35 vixie Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+#include <string.h>
+#include <errno.h>
+#include "../conf/portability.h"
+
+/*
+ * WARNING: Don't even consider trying to compile this on a system where
+ * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX.
+ */
+
+static int inet_pton4 __P((const char *src, u_char *dst));
+static int inet_pton6 __P((const char *src, u_char *dst));
+
+/* int
+ * inet_pton(af, src, dst)
+ * convert from presentation format (which usually means ASCII printable)
+ * to network format (which is usually some kind of binary format).
+ * return:
+ * 1 if the address was valid for the specified address family
+ * 0 if the address wasn't valid (`dst' is untouched in this case)
+ * -1 if some other error occurred (`dst' is untouched in this case, too)
+ * author:
+ * Paul Vixie, 1996.
+ */
+int
+inet_pton(af, src, dst)
+ int af;
+ const char *src;
+ void *dst;
+{
+ switch (af) {
+ case AF_INET:
+ return (inet_pton4(src, dst));
+ case AF_INET6:
+ return (inet_pton6(src, dst));
+ default:
+ errno = EAFNOSUPPORT;
+ return (-1);
+ }
+ /* NOTREACHED */
+}
+
+/* int
+ * inet_pton4(src, dst)
+ * like inet_aton() but without all the hexadecimal and shorthand.
+ * return:
+ * 1 if `src' is a valid dotted quad, else 0.
+ * notice:
+ * does not touch `dst' unless it's returning 1.
+ * author:
+ * Paul Vixie, 1996.
+ */
+static int
+inet_pton4(src, dst)
+ const char *src;
+ u_char *dst;
+{
+ static const char digits[] = "0123456789";
+ int saw_digit, octets, ch;
+ u_char tmp[INADDRSZ], *tp;
+
+ saw_digit = 0;
+ octets = 0;
+ *(tp = tmp) = 0;
+ while ((ch = *src++) != '\0') {
+ const char *pch;
+
+ if ((pch = strchr(digits, ch)) != NULL) {
+ u_int new = *tp * 10 + (pch - digits);
+
+ if (new > 255)
+ return (0);
+ *tp = new;
+ if (! saw_digit) {
+ if (++octets > 4)
+ return (0);
+ saw_digit = 1;
+ }
+ } else if (ch == '.' && saw_digit) {
+ if (octets == 4)
+ return (0);
+ *++tp = 0;
+ saw_digit = 0;
+ } else
+ return (0);
+ }
+ if (octets < 4)
+ return (0);
+
+ memcpy(dst, tmp, INADDRSZ);
+ return (1);
+}
+
+/* int
+ * inet_pton6(src, dst)
+ * convert presentation level address to network order binary form.
+ * return:
+ * 1 if `src' is a valid [RFC1884 2.2] address, else 0.
+ * notice:
+ * (1) does not touch `dst' unless it's returning 1.
+ * (2) :: in a full address is silently ignored.
+ * credit:
+ * inspired by Mark Andrews.
+ * author:
+ * Paul Vixie, 1996.
+ */
+static int
+inet_pton6(src, dst)
+ const char *src;
+ u_char *dst;
+{
+ static const char xdigits_l[] = "0123456789abcdef",
+ xdigits_u[] = "0123456789ABCDEF";
+ u_char tmp[IN6ADDRSZ], *tp, *endp, *colonp;
+ const char *xdigits, *curtok;
+ int ch, saw_xdigit;
+ u_int val;
+
+ memset((tp = tmp), '\0', IN6ADDRSZ);
+ endp = tp + IN6ADDRSZ;
+ colonp = NULL;
+ /* Leading :: requires some special handling. */
+ if (*src == ':')
+ if (*++src != ':')
+ return (0);
+ curtok = src;
+ saw_xdigit = 0;
+ val = 0;
+ while ((ch = *src++) != '\0') {
+ const char *pch;
+
+ if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
+ pch = strchr((xdigits = xdigits_u), ch);
+ if (pch != NULL) {
+ val <<= 4;
+ val |= (pch - xdigits);
+ if (val > 0xffff)
+ return (0);
+ saw_xdigit = 1;
+ continue;
+ }
+ if (ch == ':') {
+ curtok = src;
+ if (!saw_xdigit) {
+ if (colonp)
+ return (0);
+ colonp = tp;
+ continue;
+ }
+ if (tp + INT16SZ > endp)
+ return (0);
+ *tp++ = (u_char) (val >> 8) & 0xff;
+ *tp++ = (u_char) val & 0xff;
+ saw_xdigit = 0;
+ val = 0;
+ continue;
+ }
+ if (ch == '.' && ((tp + INADDRSZ) <= endp) &&
+ inet_pton4(curtok, tp) > 0) {
+ tp += INADDRSZ;
+ saw_xdigit = 0;
+ break; /* '\0' was seen by inet_pton4(). */
+ }
+ return (0);
+ }
+ if (saw_xdigit) {
+ if (tp + INT16SZ > endp)
+ return (0);
+ *tp++ = (u_char) (val >> 8) & 0xff;
+ *tp++ = (u_char) val & 0xff;
+ }
+ if (colonp != NULL) {
+ /*
+ * Since some memmove()'s erroneously fail to handle
+ * overlapping regions, we'll do the shift by hand.
+ */
+ const int n = tp - colonp;
+ int i;
+
+ for (i = 1; i <= n; i++) {
+ endp[- i] = colonp[n - i];
+ colonp[n - i] = 0;
+ }
+ tp = endp;
+ }
+ if (tp != endp)
+ return (0);
+ memcpy(dst, tmp, IN6ADDRSZ);
+ return (1);
+}
diff --git a/contrib/bind/res/nsap_addr.c b/contrib/bind/res/nsap_addr.c
new file mode 100644
index 0000000..162961a
--- /dev/null
+++ b/contrib/bind/res/nsap_addr.c
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 1996 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char rcsid[] = "$Id: nsap_addr.c,v 8.3 1996/08/05 08:31:35 vixie Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <ctype.h>
+#include <resolv.h>
+
+#include "../conf/portability.h"
+
+#if !defined(isxdigit) /* XXX - could be a function */
+static int
+isxdigit(c)
+ register int c;
+{
+ return ((c >= '0') && (c <= '9')) || ((c >= 'A') && (c <= 'F'));
+}
+#endif
+
+static char
+xtob(c)
+ register int c;
+{
+ return (c - (((c >= '0') && (c <= '9')) ? '0' : '7'));
+}
+
+u_int
+inet_nsap_addr(ascii, binary, maxlen)
+ const char *ascii;
+ u_char *binary;
+ int maxlen;
+{
+ register u_char c, nib;
+ u_int len = 0;
+
+ while ((c = *ascii++) != '\0' && len < maxlen) {
+ if (c == '.' || c == '+' || c == '/')
+ continue;
+ if (!isascii(c))
+ return (0);
+ if (islower(c))
+ c = toupper(c);
+ if (isxdigit(c)) {
+ nib = xtob(c);
+ if (c = *ascii++) {
+ c = toupper(c);
+ if (isxdigit(c)) {
+ *binary++ = (nib << 4) | xtob(c);
+ len++;
+ } else
+ return (0);
+ }
+ else
+ return (0);
+ }
+ else
+ return (0);
+ }
+ return (len);
+}
+
+char *
+inet_nsap_ntoa(binlen, binary, ascii)
+ int binlen;
+ register const u_char *binary;
+ register char *ascii;
+{
+ register int nib;
+ int i;
+ static char tmpbuf[255*3];
+ char *start;
+
+ if (ascii)
+ start = ascii;
+ else {
+ ascii = tmpbuf;
+ start = tmpbuf;
+ }
+
+ if (binlen > 255)
+ binlen = 255;
+
+ for (i = 0; i < binlen; i++) {
+ nib = *binary >> 4;
+ *ascii++ = nib + (nib < 10 ? '0' : '7');
+ nib = *binary++ & 0x0f;
+ *ascii++ = nib + (nib < 10 ? '0' : '7');
+ if (((i % 2) == 0 && (i + 1) < binlen))
+ *ascii++ = '.';
+ }
+ *ascii = '\0';
+ return (start);
+}
diff --git a/contrib/bind/res/res_comp.c b/contrib/bind/res/res_comp.c
new file mode 100644
index 0000000..38e5a26
--- /dev/null
+++ b/contrib/bind/res/res_comp.c
@@ -0,0 +1,535 @@
+/*
+ * ++Copyright++ 1985, 1993
+ * -
+ * Copyright (c) 1985, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * -
+ * Portions Copyright (c) 1993 by Digital Equipment Corporation.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies, and that
+ * the name of Digital Equipment Corporation not be used in advertising or
+ * publicity pertaining to distribution of the document or software without
+ * specific, written prior permission.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
+ * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ * -
+ * --Copyright--
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)res_comp.c 8.1 (Berkeley) 6/4/93";
+static char rcsid[] = "$Id: res_comp.c,v 8.8 1996/08/05 08:31:35 vixie Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+
+#include <stdio.h>
+#include <resolv.h>
+#include <ctype.h>
+
+#if defined(BSD) && (BSD >= 199103)
+# include <unistd.h>
+# include <string.h>
+#else
+# include "../conf/portability.h"
+#endif
+
+static int dn_find __P((u_char *exp_dn, u_char *msg,
+ u_char **dnptrs, u_char **lastdnptr));
+
+/*
+ * Expand compressed domain name 'comp_dn' to full domain name.
+ * 'msg' is a pointer to the begining of the message,
+ * 'eomorig' points to the first location after the message,
+ * 'exp_dn' is a pointer to a buffer of size 'length' for the result.
+ * Return size of compressed name or -1 if there was an error.
+ */
+int
+dn_expand(msg, eomorig, comp_dn, exp_dn, length)
+ const u_char *msg, *eomorig, *comp_dn;
+ char *exp_dn;
+ int length;
+{
+ register const u_char *cp;
+ register char *dn;
+ register int n, c;
+ char *eom;
+ int len = -1, checked = 0;
+
+ dn = exp_dn;
+ cp = comp_dn;
+ eom = exp_dn + length;
+ /*
+ * fetch next label in domain name
+ */
+ while (n = *cp++) {
+ /*
+ * Check for indirection
+ */
+ switch (n & INDIR_MASK) {
+ case 0:
+ if (dn != exp_dn) {
+ if (dn >= eom)
+ return (-1);
+ *dn++ = '.';
+ }
+ if (dn+n >= eom)
+ return (-1);
+ checked += n + 1;
+ while (--n >= 0) {
+ if (((c = *cp++) == '.') || (c == '\\')) {
+ if (dn + n + 2 >= eom)
+ return (-1);
+ *dn++ = '\\';
+ }
+ *dn++ = c;
+ if (cp >= eomorig) /* out of range */
+ return (-1);
+ }
+ break;
+
+ case INDIR_MASK:
+ if (len < 0)
+ len = cp - comp_dn + 1;
+ cp = msg + (((n & 0x3f) << 8) | (*cp & 0xff));
+ if (cp < msg || cp >= eomorig) /* out of range */
+ return (-1);
+ checked += 2;
+ /*
+ * Check for loops in the compressed name;
+ * if we've looked at the whole message,
+ * there must be a loop.
+ */
+ if (checked >= eomorig - msg)
+ return (-1);
+ break;
+
+ default:
+ return (-1); /* flag error */
+ }
+ }
+ *dn = '\0';
+ if (len < 0)
+ len = cp - comp_dn;
+ return (len);
+}
+
+/*
+ * Compress domain name 'exp_dn' into 'comp_dn'.
+ * Return the size of the compressed name or -1.
+ * 'length' is the size of the array pointed to by 'comp_dn'.
+ * 'dnptrs' is a list of pointers to previous compressed names. dnptrs[0]
+ * is a pointer to the beginning of the message. The list ends with NULL.
+ * 'lastdnptr' is a pointer to the end of the arrary pointed to
+ * by 'dnptrs'. Side effect is to update the list of pointers for
+ * labels inserted into the message as we compress the name.
+ * If 'dnptr' is NULL, we don't try to compress names. If 'lastdnptr'
+ * is NULL, we don't update the list.
+ */
+int
+dn_comp(exp_dn, comp_dn, length, dnptrs, lastdnptr)
+ const char *exp_dn;
+ u_char *comp_dn, **dnptrs, **lastdnptr;
+ int length;
+{
+ register u_char *cp, *dn;
+ register int c, l;
+ u_char **cpp, **lpp, *sp, *eob;
+ u_char *msg;
+
+ dn = (u_char *)exp_dn;
+ cp = comp_dn;
+ eob = cp + length;
+ lpp = cpp = NULL;
+ if (dnptrs != NULL) {
+ if ((msg = *dnptrs++) != NULL) {
+ for (cpp = dnptrs; *cpp != NULL; cpp++)
+ ;
+ lpp = cpp; /* end of list to search */
+ }
+ } else
+ msg = NULL;
+ for (c = *dn++; c != '\0'; ) {
+ /* look to see if we can use pointers */
+ if (msg != NULL) {
+ if ((l = dn_find(dn-1, msg, dnptrs, lpp)) >= 0) {
+ if (cp+1 >= eob)
+ return (-1);
+ *cp++ = (l >> 8) | INDIR_MASK;
+ *cp++ = l % 256;
+ return (cp - comp_dn);
+ }
+ /* not found, save it */
+ if (lastdnptr != NULL && cpp < lastdnptr-1) {
+ *cpp++ = cp;
+ *cpp = NULL;
+ }
+ }
+ sp = cp++; /* save ptr to length byte */
+ do {
+ if (c == '.') {
+ c = *dn++;
+ break;
+ }
+ if (c == '\\') {
+ if ((c = *dn++) == '\0')
+ break;
+ }
+ if (cp >= eob) {
+ if (msg != NULL)
+ *lpp = NULL;
+ return (-1);
+ }
+ *cp++ = c;
+ } while ((c = *dn++) != '\0');
+ /* catch trailing '.'s but not '..' */
+ if ((l = cp - sp - 1) == 0 && c == '\0') {
+ cp--;
+ break;
+ }
+ if (l <= 0 || l > MAXLABEL) {
+ if (msg != NULL)
+ *lpp = NULL;
+ return (-1);
+ }
+ *sp = l;
+ }
+ if (cp >= eob) {
+ if (msg != NULL)
+ *lpp = NULL;
+ return (-1);
+ }
+ *cp++ = '\0';
+ return (cp - comp_dn);
+}
+
+/*
+ * Skip over a compressed domain name. Return the size or -1.
+ */
+int
+__dn_skipname(comp_dn, eom)
+ const u_char *comp_dn, *eom;
+{
+ register const u_char *cp;
+ register int n;
+
+ cp = comp_dn;
+ while (cp < eom && (n = *cp++)) {
+ /*
+ * check for indirection
+ */
+ switch (n & INDIR_MASK) {
+ case 0: /* normal case, n == len */
+ cp += n;
+ continue;
+ case INDIR_MASK: /* indirection */
+ cp++;
+ break;
+ default: /* illegal type */
+ return (-1);
+ }
+ break;
+ }
+ if (cp > eom)
+ return (-1);
+ return (cp - comp_dn);
+}
+
+static int
+mklower(ch)
+ register int ch;
+{
+ if (isascii(ch) && isupper(ch))
+ return (tolower(ch));
+ return (ch);
+}
+
+/*
+ * Search for expanded name from a list of previously compressed names.
+ * Return the offset from msg if found or -1.
+ * dnptrs is the pointer to the first name on the list,
+ * not the pointer to the start of the message.
+ */
+static int
+dn_find(exp_dn, msg, dnptrs, lastdnptr)
+ u_char *exp_dn, *msg;
+ u_char **dnptrs, **lastdnptr;
+{
+ register u_char *dn, *cp, **cpp;
+ register int n;
+ u_char *sp;
+
+ for (cpp = dnptrs; cpp < lastdnptr; cpp++) {
+ dn = exp_dn;
+ sp = cp = *cpp;
+ while (n = *cp++) {
+ /*
+ * check for indirection
+ */
+ switch (n & INDIR_MASK) {
+ case 0: /* normal case, n == len */
+ while (--n >= 0) {
+ if (*dn == '.')
+ goto next;
+ if (*dn == '\\')
+ dn++;
+ if (mklower(*dn++) != mklower(*cp++))
+ goto next;
+ }
+ if ((n = *dn++) == '\0' && *cp == '\0')
+ return (sp - msg);
+ if (n == '.')
+ continue;
+ goto next;
+
+ case INDIR_MASK: /* indirection */
+ cp = msg + (((n & 0x3f) << 8) | *cp);
+ break;
+
+ default: /* illegal type */
+ return (-1);
+ }
+ }
+ if (*dn == '\0')
+ return (sp - msg);
+ next: ;
+ }
+ return (-1);
+}
+
+/*
+ * Verify that a domain name uses an acceptable character set.
+ */
+
+/*
+ * Note the conspicuous absence of ctype macros in these definitions. On
+ * non-ASCII hosts, we can't depend on string literals or ctype macros to
+ * tell us anything about network-format data. The rest of the BIND system
+ * is not careful about this, but for some reason, we're doing it right here.
+ */
+#define PERIOD 0x2e
+#define hyphenchar(c) ((c) == 0x2d)
+#define bslashchar(c) ((c) == 0x5c)
+#define periodchar(c) ((c) == PERIOD)
+#define asterchar(c) ((c) == 0x2a)
+#define alphachar(c) (((c) >= 0x41 && (c) <= 0x5a) \
+ || ((c) >= 0x61 && (c) <= 0x7a))
+#define digitchar(c) ((c) >= 0x30 && (c) <= 0x39)
+
+#define borderchar(c) (alphachar(c) || digitchar(c))
+#define middlechar(c) (borderchar(c) || hyphenchar(c))
+#define domainchar(c) ((c) > 0x20 && (c) < 0x7f)
+
+int
+res_hnok(dn)
+ const char *dn;
+{
+ int ppch = '\0', pch = PERIOD, ch = *dn++;
+
+ while (ch != '\0') {
+ int nch = *dn++;
+
+ if (periodchar(ch)) {
+ NULL;
+ } else if (periodchar(pch)) {
+ if (!borderchar(ch))
+ return (0);
+ } else if (periodchar(nch) || nch == '\0') {
+ if (!borderchar(ch))
+ return (0);
+ } else {
+ if (!middlechar(ch))
+ return (0);
+ }
+ ppch = pch, pch = ch, ch = nch;
+ }
+ return (1);
+}
+
+/*
+ * hostname-like (A, MX, WKS) owners can have "*" as their first label
+ * but must otherwise be as a host name.
+ */
+int
+res_ownok(dn)
+ const char *dn;
+{
+ if (asterchar(dn[0]) && periodchar(dn[1]))
+ dn += 2;
+ return (res_hnok(dn));
+}
+
+/*
+ * SOA RNAMEs and RP RNAMEs can have any printable character in their first
+ * label, but the rest of the name has to look like a host name.
+ */
+int
+res_mailok(dn)
+ const char *dn;
+{
+ int ch, escaped = 0;
+
+ /* "." is a valid missing representation */
+ if (*dn == '\0')
+ return(1);
+
+ /* otherwise <label>.<hostname> */
+ while ((ch = *dn++) != '\0') {
+ if (!domainchar(ch))
+ return (0);
+ if (!escaped && periodchar(ch))
+ break;
+ if (escaped)
+ escaped = 0;
+ else if (bslashchar(ch))
+ escaped = 1;
+ }
+ if (periodchar(ch))
+ return (res_hnok(dn));
+ return(0);
+}
+
+/*
+ * This function is quite liberal, since RFC 1034's character sets are only
+ * recommendations.
+ */
+int
+res_dnok(dn)
+ const char *dn;
+{
+ int ch;
+
+ while ((ch = *dn++) != '\0')
+ if (!domainchar(ch))
+ return (0);
+ return (1);
+}
+
+/*
+ * Routines to insert/extract short/long's.
+ */
+
+u_int16_t
+_getshort(msgp)
+ register const u_char *msgp;
+{
+ register u_int16_t u;
+
+ GETSHORT(u, msgp);
+ return (u);
+}
+
+#ifdef NeXT
+/*
+ * nExt machines have some funky library conventions, which we must maintain.
+ */
+u_int16_t
+res_getshort(msgp)
+ register const u_char *msgp;
+{
+ return (_getshort(msgp));
+}
+#endif
+
+u_int32_t
+_getlong(msgp)
+ register const u_char *msgp;
+{
+ register u_int32_t u;
+
+ GETLONG(u, msgp);
+ return (u);
+}
+
+void
+#if defined(__STDC__) || defined(__cplusplus)
+__putshort(register u_int16_t s, register u_char *msgp) /* must match proto */
+#else
+__putshort(s, msgp)
+ register u_int16_t s;
+ register u_char *msgp;
+#endif
+{
+ PUTSHORT(s, msgp);
+}
+
+void
+__putlong(l, msgp)
+ register u_int32_t l;
+ register u_char *msgp;
+{
+ PUTLONG(l, msgp);
+}
+
+#ifdef ultrix
+/* ultrix 4.0 had some icky packaging in its libc.a. alias for it here.
+ * there is more gunk of this kind over in res_debug.c.
+ */
+#undef putshort
+void
+#if defined(__STDC__) || defined(__cplusplus)
+putshort(register u_short s, register u_char *msgp)
+#else
+putshort(s, msgp)
+ register u_short s;
+ register u_char *msgp;
+#endif
+{
+ __putshort(s, msgp);
+}
+#undef putlong
+void
+putlong(l, msgp)
+ register u_int32_t l;
+ register u_char *msgp;
+{
+ __putlong(l, msgp);
+}
+
+#undef dn_skipname
+dn_skipname(comp_dn, eom)
+ const u_char *comp_dn, *eom;
+{
+ return (__dn_skipname(comp_dn, eom));
+}
+#endif /* Ultrix 4.0 hackery */
diff --git a/contrib/bind/res/res_data.c b/contrib/bind/res/res_data.c
new file mode 100644
index 0000000..3d26707
--- /dev/null
+++ b/contrib/bind/res/res_data.c
@@ -0,0 +1,115 @@
+/*
+ * ++Copyright++ 1995
+ * -
+ * Copyright (c) 1995
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * -
+ * Portions Copyright (c) 1993 by Digital Equipment Corporation.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies, and that
+ * the name of Digital Equipment Corporation not be used in advertising or
+ * publicity pertaining to distribution of the document or software without
+ * specific, written prior permission.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
+ * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ * -
+ * --Copyright--
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char rcsid[] = "$Id: res_data.c,v 8.2 1996/08/05 08:31:35 vixie Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+
+#include <stdio.h>
+#include <ctype.h>
+#include <resolv.h>
+#if defined(BSD) && (BSD >= 199103)
+# include <unistd.h>
+# include <stdlib.h>
+# include <string.h>
+#else
+# include "../conf/portability.h"
+#endif
+
+const char *_res_opcodes[] = {
+ "QUERY",
+ "IQUERY",
+ "CQUERYM",
+ "CQUERYU", /* experimental */
+ "NOTIFY", /* experimental */
+ "5",
+ "6",
+ "7",
+ "8",
+ "UPDATEA",
+ "UPDATED",
+ "UPDATEDA",
+ "UPDATEM",
+ "UPDATEMA",
+ "ZONEINIT",
+ "ZONEREF",
+};
+
+const char *_res_resultcodes[] = {
+ "NOERROR",
+ "FORMERR",
+ "SERVFAIL",
+ "NXDOMAIN",
+ "NOTIMP",
+ "REFUSED",
+ "6",
+ "7",
+ "8",
+ "9",
+ "10",
+ "11",
+ "12",
+ "13",
+ "14",
+ "NOCHANGE",
+};
diff --git a/contrib/bind/res/res_debug.c b/contrib/bind/res/res_debug.c
new file mode 100644
index 0000000..09e0500
--- /dev/null
+++ b/contrib/bind/res/res_debug.c
@@ -0,0 +1,1225 @@
+/*
+ * ++Copyright++ 1985, 1990, 1993
+ * -
+ * Copyright (c) 1985, 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * -
+ * Portions Copyright (c) 1993 by Digital Equipment Corporation.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies, and that
+ * the name of Digital Equipment Corporation not be used in advertising or
+ * publicity pertaining to distribution of the document or software without
+ * specific, written prior permission.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
+ * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ * -
+ * --Copyright--
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)res_debug.c 8.1 (Berkeley) 6/4/93";
+static char rcsid[] = "$Id: res_debug.c,v 8.12 1996/08/05 08:31:35 vixie Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+
+#include <stdio.h>
+#include <netdb.h>
+#include <resolv.h>
+#include <ctype.h>
+#if defined(BSD) && (BSD >= 199103) && defined(AF_INET6)
+# include <string.h>
+#else
+# include "../conf/portability.h"
+#endif
+
+#if defined(USE_OPTIONS_H)
+# include "../conf/options.h"
+#endif
+
+extern const char *_res_opcodes[];
+extern const char *_res_resultcodes[];
+
+/* XXX: we should use getservbyport() instead. */
+static const char *
+dewks(wks)
+ int wks;
+{
+ static char nbuf[20];
+
+ switch (wks) {
+ case 5: return "rje";
+ case 7: return "echo";
+ case 9: return "discard";
+ case 11: return "systat";
+ case 13: return "daytime";
+ case 15: return "netstat";
+ case 17: return "qotd";
+ case 19: return "chargen";
+ case 20: return "ftp-data";
+ case 21: return "ftp";
+ case 23: return "telnet";
+ case 25: return "smtp";
+ case 37: return "time";
+ case 39: return "rlp";
+ case 42: return "name";
+ case 43: return "whois";
+ case 53: return "domain";
+ case 57: return "apts";
+ case 59: return "apfs";
+ case 67: return "bootps";
+ case 68: return "bootpc";
+ case 69: return "tftp";
+ case 77: return "rje";
+ case 79: return "finger";
+ case 87: return "link";
+ case 95: return "supdup";
+ case 100: return "newacct";
+ case 101: return "hostnames";
+ case 102: return "iso-tsap";
+ case 103: return "x400";
+ case 104: return "x400-snd";
+ case 105: return "csnet-ns";
+ case 109: return "pop-2";
+ case 111: return "sunrpc";
+ case 113: return "auth";
+ case 115: return "sftp";
+ case 117: return "uucp-path";
+ case 119: return "nntp";
+ case 121: return "erpc";
+ case 123: return "ntp";
+ case 133: return "statsrv";
+ case 136: return "profile";
+ case 144: return "NeWS";
+ case 161: return "snmp";
+ case 162: return "snmp-trap";
+ case 170: return "print-srv";
+ default: (void) sprintf(nbuf, "%d", wks); return (nbuf);
+ }
+}
+
+/* XXX: we should use getprotobynumber() instead. */
+static const char *
+deproto(protonum)
+ int protonum;
+{
+ static char nbuf[20];
+
+ switch (protonum) {
+ case 1: return "icmp";
+ case 2: return "igmp";
+ case 3: return "ggp";
+ case 5: return "st";
+ case 6: return "tcp";
+ case 7: return "ucl";
+ case 8: return "egp";
+ case 9: return "igp";
+ case 11: return "nvp-II";
+ case 12: return "pup";
+ case 16: return "chaos";
+ case 17: return "udp";
+ default: (void) sprintf(nbuf, "%d", protonum); return (nbuf);
+ }
+}
+
+static const u_char *
+do_rrset(msg, len, cp, cnt, pflag, file, hs)
+ int cnt, pflag, len;
+ const u_char *cp, *msg;
+ const char *hs;
+ FILE *file;
+{
+ int n;
+ int sflag;
+
+ /*
+ * Print answer records.
+ */
+ sflag = (_res.pfcode & pflag);
+ if (n = ntohs(cnt)) {
+ if ((!_res.pfcode) ||
+ ((sflag) && (_res.pfcode & RES_PRF_HEAD1)))
+ fprintf(file, hs);
+ while (--n >= 0) {
+ if ((!_res.pfcode) || sflag) {
+ cp = p_rr(cp, msg, file);
+ } else {
+ unsigned int dlen;
+ cp += __dn_skipname(cp, cp + MAXCDNAME);
+ cp += INT16SZ;
+ cp += INT16SZ;
+ cp += INT32SZ;
+ dlen = _getshort((u_char*)cp);
+ cp += INT16SZ;
+ cp += dlen;
+ }
+ if ((cp - msg) > len)
+ return (NULL);
+ }
+ if ((!_res.pfcode) ||
+ ((sflag) && (_res.pfcode & RES_PRF_HEAD1)))
+ putc('\n', file);
+ }
+ return (cp);
+}
+
+void
+__p_query(msg)
+ const u_char *msg;
+{
+ __fp_query(msg, stdout);
+}
+
+#ifdef ultrix
+/* ultrix 4.0's packaging has some icky packaging. alias for it here.
+ * there is more junk of this kind over in res_comp.c.
+ */
+void
+p_query(msg)
+ const u_char *msg;
+{
+ __p_query(msg);
+}
+#endif
+
+/*
+ * Print the current options.
+ * This is intended to be primarily a debugging routine.
+ */
+void
+__fp_resstat(statp, file)
+ struct __res_state *statp;
+ FILE *file;
+{
+ register u_long mask;
+
+ fprintf(file, ";; res options:");
+ if (!statp)
+ statp = &_res;
+ for (mask = 1; mask != 0; mask <<= 1)
+ if (statp->options & mask)
+ fprintf(file, " %s", p_option(mask));
+ putc('\n', file);
+}
+
+/*
+ * Print the contents of a query.
+ * This is intended to be primarily a debugging routine.
+ */
+void
+__fp_nquery(msg, len, file)
+ const u_char *msg;
+ int len;
+ FILE *file;
+{
+ register const u_char *cp, *endMark;
+ register const HEADER *hp;
+ register int n;
+
+ if ((_res.options & RES_INIT) == 0 && res_init() == -1)
+ return;
+
+#define TruncTest(x) if (x >= endMark) goto trunc
+#define ErrorTest(x) if (x == NULL) goto error
+
+ /*
+ * Print header fields.
+ */
+ hp = (HEADER *)msg;
+ cp = msg + HFIXEDSZ;
+ endMark = cp + len;
+ if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEADX) || hp->rcode) {
+ fprintf(file, ";; ->>HEADER<<- opcode: %s, status: %s, id: %d",
+ _res_opcodes[hp->opcode],
+ _res_resultcodes[hp->rcode],
+ ntohs(hp->id));
+ putc('\n', file);
+ }
+ if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEADX))
+ putc(';', file);
+ if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEAD2)) {
+ fprintf(file, "; flags:");
+ if (hp->qr)
+ fprintf(file, " qr");
+ if (hp->aa)
+ fprintf(file, " aa");
+ if (hp->tc)
+ fprintf(file, " tc");
+ if (hp->rd)
+ fprintf(file, " rd");
+ if (hp->ra)
+ fprintf(file, " ra");
+ }
+ if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEAD1)) {
+ fprintf(file, "; Ques: %d", ntohs(hp->qdcount));
+ fprintf(file, ", Ans: %d", ntohs(hp->ancount));
+ fprintf(file, ", Auth: %d", ntohs(hp->nscount));
+ fprintf(file, ", Addit: %d", ntohs(hp->arcount));
+ }
+ if ((!_res.pfcode) || (_res.pfcode &
+ (RES_PRF_HEADX | RES_PRF_HEAD2 | RES_PRF_HEAD1))) {
+ putc('\n',file);
+ }
+ /*
+ * Print question records.
+ */
+ if (n = ntohs(hp->qdcount)) {
+ if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES))
+ fprintf(file, ";; QUESTIONS:\n");
+ while (--n >= 0) {
+ if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES))
+ fprintf(file, ";;\t");
+ TruncTest(cp);
+ if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES))
+ cp = p_cdnname(cp, msg, len, file);
+ else {
+ int n;
+ char name[MAXDNAME];
+
+ if ((n = dn_expand(msg, msg+len, cp, name,
+ sizeof name)) < 0)
+ cp = NULL;
+ else
+ cp += n;
+ }
+ ErrorTest(cp);
+ TruncTest(cp);
+ if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES))
+ fprintf(file, ", type = %s",
+ __p_type(_getshort((u_char*)cp)));
+ cp += INT16SZ;
+ TruncTest(cp);
+ if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES))
+ fprintf(file, ", class = %s\n",
+ __p_class(_getshort((u_char*)cp)));
+ cp += INT16SZ;
+ if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES))
+ putc('\n', file);
+ }
+ }
+ /*
+ * Print authoritative answer records
+ */
+ TruncTest(cp);
+ cp = do_rrset(msg, len, cp, hp->ancount, RES_PRF_ANS, file,
+ ";; ANSWERS:\n");
+ ErrorTest(cp);
+
+ /*
+ * print name server records
+ */
+ TruncTest(cp);
+ cp = do_rrset(msg, len, cp, hp->nscount, RES_PRF_AUTH, file,
+ ";; AUTHORITY RECORDS:\n");
+ ErrorTest(cp);
+
+ TruncTest(cp);
+ /*
+ * print additional records
+ */
+ cp = do_rrset(msg, len, cp, hp->arcount, RES_PRF_ADD, file,
+ ";; ADDITIONAL RECORDS:\n");
+ ErrorTest(cp);
+ return;
+ trunc:
+ fprintf(file, "\n;; ...truncated\n");
+ return;
+ error:
+ fprintf(file, "\n;; ...malformed\n");
+}
+
+void
+__fp_query(msg, file)
+ const u_char *msg;
+ FILE *file;
+{
+ fp_nquery(msg, PACKETSZ, file);
+}
+
+const u_char *
+__p_cdnname(cp, msg, len, file)
+ const u_char *cp, *msg;
+ int len;
+ FILE *file;
+{
+ char name[MAXDNAME];
+ int n;
+
+ if ((n = dn_expand(msg, msg + len, cp, name, sizeof name)) < 0)
+ return (NULL);
+ if (name[0] == '\0')
+ putc('.', file);
+ else
+ fputs(name, file);
+ return (cp + n);
+}
+
+const u_char *
+__p_cdname(cp, msg, file)
+ const u_char *cp, *msg;
+ FILE *file;
+{
+ return (p_cdnname(cp, msg, PACKETSZ, file));
+}
+
+/* XXX: the rest of these functions need to become length-limited, too. (vix)
+ */
+
+const u_char *
+__p_fqname(cp, msg, file)
+ const u_char *cp, *msg;
+ FILE *file;
+{
+ char name[MAXDNAME];
+ int n;
+
+ if ((n = dn_expand(msg, cp + MAXCDNAME, cp, name, sizeof name)) < 0)
+ return (NULL);
+ if (name[0] == '\0') {
+ putc('.', file);
+ } else {
+ fputs(name, file);
+ if (name[strlen(name) - 1] != '.')
+ putc('.', file);
+ }
+ return (cp + n);
+}
+
+/*
+ * Print resource record fields in human readable form.
+ */
+const u_char *
+__p_rr(cp, msg, file)
+ const u_char *cp, *msg;
+ FILE *file;
+{
+ int type, class, dlen, n, c;
+ struct in_addr inaddr;
+ const u_char *cp1, *cp2;
+ u_int32_t tmpttl, t;
+ int lcnt;
+
+ if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
+ h_errno = NETDB_INTERNAL;
+ return (NULL);
+ }
+ if ((cp = p_fqname(cp, msg, file)) == NULL)
+ return (NULL); /* compression error */
+ type = _getshort((u_char*)cp);
+ cp += INT16SZ;
+ class = _getshort((u_char*)cp);
+ cp += INT16SZ;
+ tmpttl = _getlong((u_char*)cp);
+ cp += INT32SZ;
+ dlen = _getshort((u_char*)cp);
+ cp += INT16SZ;
+ cp1 = cp;
+ if ((!_res.pfcode) || (_res.pfcode & RES_PRF_TTLID))
+ fprintf(file, "\t%lu", (u_long)tmpttl);
+ if ((!_res.pfcode) || (_res.pfcode & RES_PRF_CLASS))
+ fprintf(file, "\t%s", __p_class(class));
+ fprintf(file, "\t%s", __p_type(type));
+ /*
+ * Print type specific data, if appropriate
+ */
+ switch (type) {
+ case T_A:
+ switch (class) {
+ case C_IN:
+ case C_HS:
+ bcopy(cp, (char *)&inaddr, INADDRSZ);
+ if (dlen == 4) {
+ fprintf(file, "\t%s", inet_ntoa(inaddr));
+ cp += dlen;
+ } else if (dlen == 7) {
+ char *address;
+ u_char protocol;
+ u_short port;
+
+ address = inet_ntoa(inaddr);
+ cp += INADDRSZ;
+ protocol = *(u_char*)cp;
+ cp += sizeof(u_char);
+ port = _getshort((u_char*)cp);
+ cp += INT16SZ;
+ fprintf(file, "\t%s\t; proto %d, port %d",
+ address, protocol, port);
+ }
+ break;
+ default:
+ cp += dlen;
+ }
+ break;
+ case T_CNAME:
+ case T_MB:
+ case T_MG:
+ case T_MR:
+ case T_NS:
+ case T_PTR:
+ putc('\t', file);
+ if ((cp = p_fqname(cp, msg, file)) == NULL)
+ return (NULL);
+ break;
+
+ case T_HINFO:
+ case T_ISDN:
+ (void) fputs("\t\"", file);
+ cp2 = cp + dlen;
+ if ((n = (unsigned char) *cp++) != 0) {
+ for (c = n; c > 0 && cp < cp2; c--) {
+ if (strchr("\n\"\\", *cp))
+ (void) putc('\\', file);
+ (void) putc(*cp++, file);
+ }
+ putc('"', file);
+ }
+ if (cp < cp2 && (n = (unsigned char) *cp++) != 0) {
+ (void) fputs ("\t\"", file);
+ for (c = n; c > 0 && cp < cp2; c--) {
+ if (strchr("\n\"\\", *cp))
+ (void) putc('\\', file);
+ (void) putc(*cp++, file);
+ }
+ putc('"', file);
+ } else if (type == T_HINFO) {
+ (void) fputs("\"?\"", file);
+ fprintf(file, "\n;; *** Warning *** OS-type missing");
+ }
+ break;
+
+ case T_SOA:
+ putc('\t', file);
+ if ((cp = p_fqname(cp, msg, file)) == NULL)
+ return (NULL);
+ putc(' ', file);
+ if ((cp = p_fqname(cp, msg, file)) == NULL)
+ return (NULL);
+ fputs(" (\n", file);
+ t = _getlong((u_char*)cp); cp += INT32SZ;
+ fprintf(file, "\t\t\t%lu\t; serial\n", (u_long)t);
+ t = _getlong((u_char*)cp); cp += INT32SZ;
+ fprintf(file, "\t\t\t%lu\t; refresh (%s)\n",
+ (u_long)t, __p_time(t));
+ t = _getlong((u_char*)cp); cp += INT32SZ;
+ fprintf(file, "\t\t\t%lu\t; retry (%s)\n",
+ (u_long)t, __p_time(t));
+ t = _getlong((u_char*)cp); cp += INT32SZ;
+ fprintf(file, "\t\t\t%lu\t; expire (%s)\n",
+ (u_long)t, __p_time(t));
+ t = _getlong((u_char*)cp); cp += INT32SZ;
+ fprintf(file, "\t\t\t%lu )\t; minimum (%s)",
+ (u_long)t, __p_time(t));
+ break;
+
+ case T_MX:
+ case T_AFSDB:
+ case T_RT:
+ fprintf(file, "\t%d ", _getshort((u_char*)cp));
+ cp += INT16SZ;
+ if ((cp = p_fqname(cp, msg, file)) == NULL)
+ return (NULL);
+ break;
+
+ case T_PX:
+ fprintf(file, "\t%d ", _getshort((u_char*)cp));
+ cp += INT16SZ;
+ if ((cp = p_fqname(cp, msg, file)) == NULL)
+ return (NULL);
+ putc(' ', file);
+ if ((cp = p_fqname(cp, msg, file)) == NULL)
+ return (NULL);
+ break;
+
+ case T_TXT:
+ case T_X25:
+ (void) fputs("\t\"", file);
+ cp2 = cp1 + dlen;
+ while (cp < cp2) {
+ if (n = (unsigned char) *cp++) {
+ for (c = n; c > 0 && cp < cp2; c--) {
+ if (strchr("\n\"\\", *cp))
+ (void) putc('\\', file);
+ (void) putc(*cp++, file);
+ }
+ }
+ }
+ putc('"', file);
+ break;
+
+ case T_NSAP:
+ (void) fprintf(file, "\t%s", inet_nsap_ntoa(dlen, cp, NULL));
+ cp += dlen;
+ break;
+
+ case T_AAAA: {
+ char t[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"];
+
+ fprintf(file, "\t%s\n", inet_ntop(AF_INET6, cp, t, sizeof t));
+ cp += dlen;
+ break;
+ }
+
+ case T_LOC: {
+ char t[255];
+
+ (void) fprintf(file, "\t%s\n", loc_ntoa(cp, t));
+ cp += dlen;
+ break;
+ }
+
+ case T_MINFO:
+ case T_RP:
+ putc('\t', file);
+ if ((cp = p_fqname(cp, msg, file)) == NULL)
+ return (NULL);
+ putc(' ', file);
+ if ((cp = p_fqname(cp, msg, file)) == NULL)
+ return (NULL);
+ break;
+
+ case T_UINFO:
+ putc('\t', file);
+ fputs((char *)cp, file);
+ cp += dlen;
+ break;
+
+ case T_UID:
+ case T_GID:
+ if (dlen == 4) {
+ fprintf(file, "\t%u", _getlong((u_char*)cp));
+ cp += INT32SZ;
+ }
+ break;
+
+ case T_WKS:
+ if (dlen < INT32SZ + 1)
+ break;
+ bcopy(cp, (char *)&inaddr, INADDRSZ);
+ cp += INT32SZ;
+ fprintf(file, "\t%s %s ( ",
+ inet_ntoa(inaddr),
+ deproto((int) *cp));
+ cp += sizeof(u_char);
+ n = 0;
+ lcnt = 0;
+ while (cp < cp1 + dlen) {
+ c = *cp++;
+ do {
+ if (c & 0200) {
+ if (lcnt == 0) {
+ fputs("\n\t\t\t", file);
+ lcnt = 5;
+ }
+ fputs(dewks(n), file);
+ putc(' ', file);
+ lcnt--;
+ }
+ c <<= 1;
+ } while (++n & 07);
+ }
+ putc(')', file);
+ break;
+
+#ifdef ALLOW_T_UNSPEC
+ case T_UNSPEC:
+ {
+ int NumBytes = 8;
+ u_char *DataPtr;
+ int i;
+
+ if (dlen < NumBytes) NumBytes = dlen;
+ fprintf(file, "\tFirst %d bytes of hex data:",
+ NumBytes);
+ for (i = 0, DataPtr = cp; i < NumBytes; i++, DataPtr++)
+ fprintf(file, " %x", *DataPtr);
+ cp += dlen;
+ }
+ break;
+#endif /* ALLOW_T_UNSPEC */
+
+ default:
+ fprintf(file, "\t?%d?", type);
+ cp += dlen;
+ }
+#if 0
+ fprintf(file, "\t; dlen=%d, ttl %s\n", dlen, __p_time(tmpttl));
+#else
+ putc('\n', file);
+#endif
+ if (cp - cp1 != dlen) {
+ fprintf(file, ";; packet size error (found %d, dlen was %d)\n",
+ cp - cp1, dlen);
+ cp = NULL;
+ }
+ return (cp);
+}
+
+/*
+ * Return a string for the type
+ */
+const char *
+__p_type(type)
+ int type;
+{
+ static char nbuf[20];
+
+ switch (type) {
+ case T_A: return "A";
+ case T_NS: return "NS";
+ case T_CNAME: return "CNAME";
+ case T_SOA: return "SOA";
+ case T_MB: return "MB";
+ case T_MG: return "MG";
+ case T_MR: return "MR";
+ case T_NULL: return "NULL";
+ case T_WKS: return "WKS";
+ case T_PTR: return "PTR";
+ case T_HINFO: return "HINFO";
+ case T_MINFO: return "MINFO";
+ case T_MX: return "MX";
+ case T_TXT: return "TXT";
+ case T_RP: return "RP";
+ case T_AFSDB: return "AFSDB";
+ case T_X25: return "X25";
+ case T_ISDN: return "ISDN";
+ case T_RT: return "RT";
+ case T_NSAP: return "NSAP";
+ case T_NSAP_PTR: return "NSAP_PTR";
+ case T_SIG: return "SIG";
+ case T_KEY: return "KEY";
+ case T_PX: return "PX";
+ case T_GPOS: return "GPOS";
+ case T_AAAA: return "AAAA";
+ case T_LOC: return "LOC";
+ case T_AXFR: return "AXFR";
+ case T_MAILB: return "MAILB";
+ case T_MAILA: return "MAILA";
+ case T_ANY: return "ANY";
+ case T_UINFO: return "UINFO";
+ case T_UID: return "UID";
+ case T_GID: return "GID";
+#ifdef ALLOW_T_UNSPEC
+ case T_UNSPEC: return "UNSPEC";
+#endif /* ALLOW_T_UNSPEC */
+ default: (void)sprintf(nbuf, "%d", type); return (nbuf);
+ }
+}
+
+/*
+ * Return a mnemonic for class
+ */
+const char *
+__p_class(class)
+ int class;
+{
+ static char nbuf[20];
+
+ switch (class) {
+ case C_IN: return "IN";
+ case C_HS: return "HS";
+ case C_ANY: return "ANY";
+ default: (void)sprintf(nbuf, "%d", class); return (nbuf);
+ }
+}
+
+/*
+ * Return a mnemonic for an option
+ */
+const char *
+__p_option(option)
+ u_long option;
+{
+ static char nbuf[40];
+
+ switch (option) {
+ case RES_INIT: return "init";
+ case RES_DEBUG: return "debug";
+ case RES_AAONLY: return "aaonly(unimpl)";
+ case RES_USEVC: return "usevc";
+ case RES_PRIMARY: return "primry(unimpl)";
+ case RES_IGNTC: return "igntc";
+ case RES_RECURSE: return "recurs";
+ case RES_DEFNAMES: return "defnam";
+ case RES_STAYOPEN: return "styopn";
+ case RES_DNSRCH: return "dnsrch";
+ case RES_INSECURE1: return "insecure1";
+ case RES_INSECURE2: return "insecure2";
+ default: sprintf(nbuf, "?0x%lx?", (u_long)option);
+ return (nbuf);
+ }
+}
+
+/*
+ * Return a mnemonic for a time to live
+ */
+char *
+__p_time(value)
+ u_int32_t value;
+{
+ static char nbuf[40];
+ int secs, mins, hours, days;
+ register char *p;
+
+ if (value == 0) {
+ strcpy(nbuf, "0 secs");
+ return (nbuf);
+ }
+
+ secs = value % 60;
+ value /= 60;
+ mins = value % 60;
+ value /= 60;
+ hours = value % 24;
+ value /= 24;
+ days = value;
+ value = 0;
+
+#define PLURALIZE(x) x, (x == 1) ? "" : "s"
+ p = nbuf;
+ if (days) {
+ (void)sprintf(p, "%d day%s", PLURALIZE(days));
+ while (*++p);
+ }
+ if (hours) {
+ if (days)
+ *p++ = ' ';
+ (void)sprintf(p, "%d hour%s", PLURALIZE(hours));
+ while (*++p);
+ }
+ if (mins) {
+ if (days || hours)
+ *p++ = ' ';
+ (void)sprintf(p, "%d min%s", PLURALIZE(mins));
+ while (*++p);
+ }
+ if (secs || ! (days || hours || mins)) {
+ if (days || hours || mins)
+ *p++ = ' ';
+ (void)sprintf(p, "%d sec%s", PLURALIZE(secs));
+ }
+ return (nbuf);
+}
+
+/*
+ * routines to convert between on-the-wire RR format and zone file format.
+ * Does not contain conversion to/from decimal degrees; divide or multiply
+ * by 60*60*1000 for that.
+ */
+
+static unsigned int poweroften[10] = {1, 10, 100, 1000, 10000, 100000,
+ 1000000,10000000,100000000,1000000000};
+
+/* takes an XeY precision/size value, returns a string representation. */
+static const char *
+precsize_ntoa(prec)
+ u_int8_t prec;
+{
+ static char retbuf[sizeof("90000000.00")];
+ unsigned long val;
+ int mantissa, exponent;
+
+ mantissa = (int)((prec >> 4) & 0x0f) % 10;
+ exponent = (int)((prec >> 0) & 0x0f) % 10;
+
+ val = mantissa * poweroften[exponent];
+
+ (void) sprintf(retbuf, "%ld.%.2ld", val/100, val%100);
+ return (retbuf);
+}
+
+/* converts ascii size/precision X * 10**Y(cm) to 0xXY. moves pointer. */
+static u_int8_t
+precsize_aton(strptr)
+ char **strptr;
+{
+ unsigned int mval = 0, cmval = 0;
+ u_int8_t retval = 0;
+ register char *cp;
+ register int exponent;
+ register int mantissa;
+
+ cp = *strptr;
+
+ while (isdigit(*cp))
+ mval = mval * 10 + (*cp++ - '0');
+
+ if (*cp == '.') { /* centimeters */
+ cp++;
+ if (isdigit(*cp)) {
+ cmval = (*cp++ - '0') * 10;
+ if (isdigit(*cp)) {
+ cmval += (*cp++ - '0');
+ }
+ }
+ }
+ cmval = (mval * 100) + cmval;
+
+ for (exponent = 0; exponent < 9; exponent++)
+ if (cmval < poweroften[exponent+1])
+ break;
+
+ mantissa = cmval / poweroften[exponent];
+ if (mantissa > 9)
+ mantissa = 9;
+
+ retval = (mantissa << 4) | exponent;
+
+ *strptr = cp;
+
+ return (retval);
+}
+
+/* converts ascii lat/lon to unsigned encoded 32-bit number. moves pointer. */
+static u_int32_t
+latlon2ul(latlonstrptr,which)
+ char **latlonstrptr;
+ int *which;
+{
+ register char *cp;
+ u_int32_t retval;
+ int deg = 0, min = 0, secs = 0, secsfrac = 0;
+
+ cp = *latlonstrptr;
+
+ while (isdigit(*cp))
+ deg = deg * 10 + (*cp++ - '0');
+
+ while (isspace(*cp))
+ cp++;
+
+ if (!(isdigit(*cp)))
+ goto fndhemi;
+
+ while (isdigit(*cp))
+ min = min * 10 + (*cp++ - '0');
+
+ while (isspace(*cp))
+ cp++;
+
+ if (!(isdigit(*cp)))
+ goto fndhemi;
+
+ while (isdigit(*cp))
+ secs = secs * 10 + (*cp++ - '0');
+
+ if (*cp == '.') { /* decimal seconds */
+ cp++;
+ if (isdigit(*cp)) {
+ secsfrac = (*cp++ - '0') * 100;
+ if (isdigit(*cp)) {
+ secsfrac += (*cp++ - '0') * 10;
+ if (isdigit(*cp)) {
+ secsfrac += (*cp++ - '0');
+ }
+ }
+ }
+ }
+
+ while (!isspace(*cp)) /* if any trailing garbage */
+ cp++;
+
+ while (isspace(*cp))
+ cp++;
+
+ fndhemi:
+ switch (*cp) {
+ case 'N': case 'n':
+ case 'E': case 'e':
+ retval = ((unsigned)1<<31)
+ + (((((deg * 60) + min) * 60) + secs) * 1000)
+ + secsfrac;
+ break;
+ case 'S': case 's':
+ case 'W': case 'w':
+ retval = ((unsigned)1<<31)
+ - (((((deg * 60) + min) * 60) + secs) * 1000)
+ - secsfrac;
+ break;
+ default:
+ retval = 0; /* invalid value -- indicates error */
+ break;
+ }
+
+ switch (*cp) {
+ case 'N': case 'n':
+ case 'S': case 's':
+ *which = 1; /* latitude */
+ break;
+ case 'E': case 'e':
+ case 'W': case 'w':
+ *which = 2; /* longitude */
+ break;
+ default:
+ *which = 0; /* error */
+ break;
+ }
+
+ cp++; /* skip the hemisphere */
+
+ while (!isspace(*cp)) /* if any trailing garbage */
+ cp++;
+
+ while (isspace(*cp)) /* move to next field */
+ cp++;
+
+ *latlonstrptr = cp;
+
+ return (retval);
+}
+
+/* converts a zone file representation in a string to an RDATA on-the-wire
+ * representation. */
+int
+loc_aton(ascii, binary)
+ const char *ascii;
+ u_char *binary;
+{
+ const char *cp, *maxcp;
+ u_char *bcp;
+
+ u_int32_t latit = 0, longit = 0, alt = 0;
+ u_int32_t lltemp1 = 0, lltemp2 = 0;
+ int altmeters = 0, altfrac = 0, altsign = 1;
+ u_int8_t hp = 0x16; /* default = 1e6 cm = 10000.00m = 10km */
+ u_int8_t vp = 0x13; /* default = 1e3 cm = 10.00m */
+ u_int8_t siz = 0x12; /* default = 1e2 cm = 1.00m */
+ int which1 = 0, which2 = 0;
+
+ cp = ascii;
+ maxcp = cp + strlen(ascii);
+
+ lltemp1 = latlon2ul(&cp, &which1);
+
+ lltemp2 = latlon2ul(&cp, &which2);
+
+ switch (which1 + which2) {
+ case 3: /* 1 + 2, the only valid combination */
+ if ((which1 == 1) && (which2 == 2)) { /* normal case */
+ latit = lltemp1;
+ longit = lltemp2;
+ } else if ((which1 == 2) && (which2 == 1)) { /* reversed */
+ longit = lltemp1;
+ latit = lltemp2;
+ } else { /* some kind of brokenness */
+ return 0;
+ }
+ break;
+ default: /* we didn't get one of each */
+ return 0;
+ }
+
+ /* altitude */
+ if (*cp == '-') {
+ altsign = -1;
+ cp++;
+ }
+
+ if (*cp == '+')
+ cp++;
+
+ while (isdigit(*cp))
+ altmeters = altmeters * 10 + (*cp++ - '0');
+
+ if (*cp == '.') { /* decimal meters */
+ cp++;
+ if (isdigit(*cp)) {
+ altfrac = (*cp++ - '0') * 10;
+ if (isdigit(*cp)) {
+ altfrac += (*cp++ - '0');
+ }
+ }
+ }
+
+ alt = (10000000 + (altsign * (altmeters * 100 + altfrac)));
+
+ while (!isspace(*cp) && (cp < maxcp)) /* if trailing garbage or m */
+ cp++;
+
+ while (isspace(*cp) && (cp < maxcp))
+ cp++;
+
+ if (cp >= maxcp)
+ goto defaults;
+
+ siz = precsize_aton(&cp);
+
+ while (!isspace(*cp) && (cp < maxcp)) /* if trailing garbage or m */
+ cp++;
+
+ while (isspace(*cp) && (cp < maxcp))
+ cp++;
+
+ if (cp >= maxcp)
+ goto defaults;
+
+ hp = precsize_aton(&cp);
+
+ while (!isspace(*cp) && (cp < maxcp)) /* if trailing garbage or m */
+ cp++;
+
+ while (isspace(*cp) && (cp < maxcp))
+ cp++;
+
+ if (cp >= maxcp)
+ goto defaults;
+
+ vp = precsize_aton(&cp);
+
+ defaults:
+
+ bcp = binary;
+ *bcp++ = (u_int8_t) 0; /* version byte */
+ *bcp++ = siz;
+ *bcp++ = hp;
+ *bcp++ = vp;
+ PUTLONG(latit,bcp);
+ PUTLONG(longit,bcp);
+ PUTLONG(alt,bcp);
+
+ return (16); /* size of RR in octets */
+}
+
+/* takes an on-the-wire LOC RR and formats it in a human readable format. */
+char *
+loc_ntoa(binary, ascii)
+ const u_char *binary;
+ char *ascii;
+{
+ static char *error = "?";
+ register const u_char *cp = binary;
+
+ int latdeg, latmin, latsec, latsecfrac;
+ int longdeg, longmin, longsec, longsecfrac;
+ char northsouth, eastwest;
+ int altmeters, altfrac, altsign;
+
+ const int referencealt = 100000 * 100;
+
+ int32_t latval, longval, altval;
+ u_int32_t templ;
+ u_int8_t sizeval, hpval, vpval, versionval;
+
+ char *sizestr, *hpstr, *vpstr;
+
+ versionval = *cp++;
+
+ if (versionval) {
+ sprintf(ascii, "; error: unknown LOC RR version");
+ return (ascii);
+ }
+
+ sizeval = *cp++;
+
+ hpval = *cp++;
+ vpval = *cp++;
+
+ GETLONG(templ, cp);
+ latval = (templ - ((unsigned)1<<31));
+
+ GETLONG(templ, cp);
+ longval = (templ - ((unsigned)1<<31));
+
+ GETLONG(templ, cp);
+ if (templ < referencealt) { /* below WGS 84 spheroid */
+ altval = referencealt - templ;
+ altsign = -1;
+ } else {
+ altval = templ - referencealt;
+ altsign = 1;
+ }
+
+ if (latval < 0) {
+ northsouth = 'S';
+ latval = -latval;
+ } else
+ northsouth = 'N';
+
+ latsecfrac = latval % 1000;
+ latval = latval / 1000;
+ latsec = latval % 60;
+ latval = latval / 60;
+ latmin = latval % 60;
+ latval = latval / 60;
+ latdeg = latval;
+
+ if (longval < 0) {
+ eastwest = 'W';
+ longval = -longval;
+ } else
+ eastwest = 'E';
+
+ longsecfrac = longval % 1000;
+ longval = longval / 1000;
+ longsec = longval % 60;
+ longval = longval / 60;
+ longmin = longval % 60;
+ longval = longval / 60;
+ longdeg = longval;
+
+ altfrac = altval % 100;
+ altmeters = (altval / 100) * altsign;
+
+ if ((sizestr = strdup(precsize_ntoa(sizeval))) == NULL)
+ sizestr = error;
+ if ((hpstr = strdup(precsize_ntoa(hpval))) == NULL)
+ hpstr = error;
+ if ((vpstr = strdup(precsize_ntoa(vpval))) == NULL)
+ vpstr = error;
+
+ sprintf(ascii,
+ "%d %.2d %.2d.%.3d %c %d %.2d %.2d.%.3d %c %d.%.2dm %sm %sm %sm",
+ latdeg, latmin, latsec, latsecfrac, northsouth,
+ longdeg, longmin, longsec, longsecfrac, eastwest,
+ altmeters, altfrac, sizestr, hpstr, vpstr);
+
+ if (sizestr != error)
+ free(sizestr);
+ if (hpstr != error)
+ free(hpstr);
+ if (vpstr != error)
+ free(vpstr);
+
+ return (ascii);
+}
diff --git a/contrib/bind/res/res_init.c b/contrib/bind/res/res_init.c
new file mode 100644
index 0000000..ab06ecd
--- /dev/null
+++ b/contrib/bind/res/res_init.c
@@ -0,0 +1,651 @@
+/*
+ * ++Copyright++ 1985, 1989, 1993
+ * -
+ * Copyright (c) 1985, 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * -
+ * Portions Copyright (c) 1993 by Digital Equipment Corporation.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies, and that
+ * the name of Digital Equipment Corporation not be used in advertising or
+ * publicity pertaining to distribution of the document or software without
+ * specific, written prior permission.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
+ * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ * -
+ * --Copyright--
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)res_init.c 8.1 (Berkeley) 6/7/93";
+static char rcsid[] = "$Id: res_init.c,v 8.5 1996/08/05 08:31:35 vixie Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+
+#include <stdio.h>
+#include <ctype.h>
+#include <resolv.h>
+#if defined(BSD) && (BSD >= 199103)
+# include <unistd.h>
+# include <stdlib.h>
+# include <string.h>
+#else
+# include "../conf/portability.h"
+#endif
+
+/*-------------------------------------- info about "sortlist" --------------
+ * Marc Majka 1994/04/16
+ * Allan Nathanson 1994/10/29 (BIND 4.9.3.x)
+ *
+ * NetInfo resolver configuration directory support.
+ *
+ * Allow a NetInfo directory to be created in the hierarchy which
+ * contains the same information as the resolver configuration file.
+ *
+ * - The local domain name is stored as the value of the "domain" property.
+ * - The Internet address(es) of the name server(s) are stored as values
+ * of the "nameserver" property.
+ * - The name server addresses are stored as values of the "nameserver"
+ * property.
+ * - The search list for host-name lookup is stored as values of the
+ * "search" property.
+ * - The sortlist comprised of IP address netmask pairs are stored as
+ * values of the "sortlist" property. The IP address and optional netmask
+ * should be seperated by a slash (/) or ampersand (&) character.
+ * - Internal resolver variables can be set from the value of the "options"
+ * property.
+ */
+#if defined(NeXT)
+# include <netinfo/ni.h>
+# define NI_PATH_RESCONF "/locations/resolver"
+# define NI_TIMEOUT 10
+static int netinfo_res_init __P((int *haveenv, int *havesearch));
+#endif
+
+#if defined(USE_OPTIONS_H)
+# include "../conf/options.h"
+#endif
+
+static void res_setoptions __P((char *, char *));
+
+#ifdef RESOLVSORT
+static const char sort_mask[] = "/&";
+#define ISSORTMASK(ch) (strchr(sort_mask, ch) != NULL)
+static u_int32_t net_mask __P((struct in_addr));
+#endif
+
+#if !defined(isascii) /* XXX - could be a function */
+# define isascii(c) (!(c & 0200))
+#endif
+
+/*
+ * Resolver state default settings.
+ */
+
+struct __res_state _res;
+
+/*
+ * Set up default settings. If the configuration file exist, the values
+ * there will have precedence. Otherwise, the server address is set to
+ * INADDR_ANY and the default domain name comes from the gethostname().
+ *
+ * An interrim version of this code (BIND 4.9, pre-4.4BSD) used 127.0.0.1
+ * rather than INADDR_ANY ("0.0.0.0") as the default name server address
+ * since it was noted that INADDR_ANY actually meant ``the first interface
+ * you "ifconfig"'d at boot time'' and if this was a SLIP or PPP interface,
+ * it had to be "up" in order for you to reach your own name server. It
+ * was later decided that since the recommended practice is to always
+ * install local static routes through 127.0.0.1 for all your network
+ * interfaces, that we could solve this problem without a code change.
+ *
+ * The configuration file should always be used, since it is the only way
+ * to specify a default domain. If you are running a server on your local
+ * machine, you should say "nameserver 0.0.0.0" or "nameserver 127.0.0.1"
+ * in the configuration file.
+ *
+ * Return 0 if completes successfully, -1 on error
+ */
+int
+res_init()
+{
+ register FILE *fp;
+ register char *cp, **pp;
+ register int n;
+ char buf[BUFSIZ];
+ int nserv = 0; /* number of nameserver records read from file */
+ int haveenv = 0;
+ int havesearch = 0;
+#ifdef RESOLVSORT
+ int nsort = 0;
+ char *net;
+#endif
+#ifndef RFC1535
+ int dots;
+#endif
+
+ /*
+ * These three fields used to be statically initialized. This made
+ * it hard to use this code in a shared library. It is necessary,
+ * now that we're doing dynamic initialization here, that we preserve
+ * the old semantics: if an application modifies one of these three
+ * fields of _res before res_init() is called, res_init() will not
+ * alter them. Of course, if an application is setting them to
+ * _zero_ before calling res_init(), hoping to override what used
+ * to be the static default, we can't detect it and unexpected results
+ * will follow. Zero for any of these fields would make no sense,
+ * so one can safely assume that the applications were already getting
+ * unexpected results.
+ *
+ * _res.options is tricky since some apps were known to diddle the bits
+ * before res_init() was first called. We can't replicate that semantic
+ * with dynamic initialization (they may have turned bits off that are
+ * set in RES_DEFAULT). Our solution is to declare such applications
+ * "broken". They could fool us by setting RES_INIT but none do (yet).
+ */
+ if (!_res.retrans)
+ _res.retrans = RES_TIMEOUT;
+ if (!_res.retry)
+ _res.retry = 4;
+ if (!(_res.options & RES_INIT))
+ _res.options = RES_DEFAULT;
+
+ /*
+ * This one used to initialize implicitly to zero, so unless the app
+ * has set it to something in particular, we can randomize it now.
+ */
+ if (!_res.id)
+ _res.id = res_randomid();
+
+#ifdef USELOOPBACK
+ _res.nsaddr.sin_addr = inet_makeaddr(IN_LOOPBACKNET, 1);
+#else
+ _res.nsaddr.sin_addr.s_addr = INADDR_ANY;
+#endif
+ _res.nsaddr.sin_family = AF_INET;
+ _res.nsaddr.sin_port = htons(NAMESERVER_PORT);
+ _res.nscount = 1;
+ _res.ndots = 1;
+ _res.pfcode = 0;
+
+ /* Allow user to override the local domain definition */
+ if ((cp = getenv("LOCALDOMAIN")) != NULL) {
+ (void)strncpy(_res.defdname, cp, sizeof(_res.defdname) - 1);
+ haveenv++;
+
+ /*
+ * Set search list to be blank-separated strings
+ * from rest of env value. Permits users of LOCALDOMAIN
+ * to still have a search list, and anyone to set the
+ * one that they want to use as an individual (even more
+ * important now that the rfc1535 stuff restricts searches)
+ */
+ cp = _res.defdname;
+ pp = _res.dnsrch;
+ *pp++ = cp;
+ for (n = 0; *cp && pp < _res.dnsrch + MAXDNSRCH; cp++) {
+ if (*cp == '\n') /* silly backwards compat */
+ break;
+ else if (*cp == ' ' || *cp == '\t') {
+ *cp = 0;
+ n = 1;
+ } else if (n) {
+ *pp++ = cp;
+ n = 0;
+ havesearch = 1;
+ }
+ }
+ /* null terminate last domain if there are excess */
+ while (*cp != '\0' && *cp != ' ' && *cp != '\t' && *cp != '\n')
+ cp++;
+ *cp = '\0';
+ *pp++ = 0;
+ }
+
+#define MATCH(line, name) \
+ (!strncmp(line, name, sizeof(name) - 1) && \
+ (line[sizeof(name) - 1] == ' ' || \
+ line[sizeof(name) - 1] == '\t'))
+
+#ifdef NeXT
+ if (netinfo_res_init(&haveenv, &havesearch) == 0)
+#endif
+ if ((fp = fopen(_PATH_RESCONF, "r")) != NULL) {
+ /* read the config file */
+ while (fgets(buf, sizeof(buf), fp) != NULL) {
+ /* skip comments */
+ if (*buf == ';' || *buf == '#')
+ continue;
+ /* read default domain name */
+ if (MATCH(buf, "domain")) {
+ if (haveenv) /* skip if have from environ */
+ continue;
+ cp = buf + sizeof("domain") - 1;
+ while (*cp == ' ' || *cp == '\t')
+ cp++;
+ if ((*cp == '\0') || (*cp == '\n'))
+ continue;
+ strncpy(_res.defdname, cp, sizeof(_res.defdname) - 1);
+ if ((cp = strpbrk(_res.defdname, " \t\n")) != NULL)
+ *cp = '\0';
+ havesearch = 0;
+ continue;
+ }
+ /* set search list */
+ if (MATCH(buf, "search")) {
+ if (haveenv) /* skip if have from environ */
+ continue;
+ cp = buf + sizeof("search") - 1;
+ while (*cp == ' ' || *cp == '\t')
+ cp++;
+ if ((*cp == '\0') || (*cp == '\n'))
+ continue;
+ strncpy(_res.defdname, cp, sizeof(_res.defdname) - 1);
+ if ((cp = strchr(_res.defdname, '\n')) != NULL)
+ *cp = '\0';
+ /*
+ * Set search list to be blank-separated strings
+ * on rest of line.
+ */
+ cp = _res.defdname;
+ pp = _res.dnsrch;
+ *pp++ = cp;
+ for (n = 0; *cp && pp < _res.dnsrch + MAXDNSRCH; cp++) {
+ if (*cp == ' ' || *cp == '\t') {
+ *cp = 0;
+ n = 1;
+ } else if (n) {
+ *pp++ = cp;
+ n = 0;
+ }
+ }
+ /* null terminate last domain if there are excess */
+ while (*cp != '\0' && *cp != ' ' && *cp != '\t')
+ cp++;
+ *cp = '\0';
+ *pp++ = 0;
+ havesearch = 1;
+ continue;
+ }
+ /* read nameservers to query */
+ if (MATCH(buf, "nameserver") && nserv < MAXNS) {
+ struct in_addr a;
+
+ cp = buf + sizeof("nameserver") - 1;
+ while (*cp == ' ' || *cp == '\t')
+ cp++;
+ if ((*cp != '\0') && (*cp != '\n') && inet_aton(cp, &a)) {
+ _res.nsaddr_list[nserv].sin_addr = a;
+ _res.nsaddr_list[nserv].sin_family = AF_INET;
+ _res.nsaddr_list[nserv].sin_port =
+ htons(NAMESERVER_PORT);
+ nserv++;
+ }
+ continue;
+ }
+#ifdef RESOLVSORT
+ if (MATCH(buf, "sortlist")) {
+ struct in_addr a;
+
+ cp = buf + sizeof("sortlist") - 1;
+ while (nsort < MAXRESOLVSORT) {
+ while (*cp == ' ' || *cp == '\t')
+ cp++;
+ if (*cp == '\0' || *cp == '\n' || *cp == ';')
+ break;
+ net = cp;
+ while (*cp && !ISSORTMASK(*cp) && *cp != ';' &&
+ isascii(*cp) && !isspace(*cp))
+ cp++;
+ n = *cp;
+ *cp = 0;
+ if (inet_aton(net, &a)) {
+ _res.sort_list[nsort].addr = a;
+ if (ISSORTMASK(n)) {
+ *cp++ = n;
+ net = cp;
+ while (*cp && *cp != ';' &&
+ isascii(*cp) && !isspace(*cp))
+ cp++;
+ n = *cp;
+ *cp = 0;
+ if (inet_aton(net, &a)) {
+ _res.sort_list[nsort].mask = a.s_addr;
+ } else {
+ _res.sort_list[nsort].mask =
+ net_mask(_res.sort_list[nsort].addr);
+ }
+ } else {
+ _res.sort_list[nsort].mask =
+ net_mask(_res.sort_list[nsort].addr);
+ }
+ nsort++;
+ }
+ *cp = n;
+ }
+ continue;
+ }
+#endif
+ if (MATCH(buf, "options")) {
+ res_setoptions(buf + sizeof("options") - 1, "conf");
+ continue;
+ }
+ }
+ if (nserv > 1)
+ _res.nscount = nserv;
+#ifdef RESOLVSORT
+ _res.nsort = nsort;
+#endif
+ (void) fclose(fp);
+ }
+ if (_res.defdname[0] == 0 &&
+ gethostname(buf, sizeof(_res.defdname) - 1) == 0 &&
+ (cp = strchr(buf, '.')) != NULL)
+ strcpy(_res.defdname, cp + 1);
+
+ /* find components of local domain that might be searched */
+ if (havesearch == 0) {
+ pp = _res.dnsrch;
+ *pp++ = _res.defdname;
+ *pp = NULL;
+
+#ifndef RFC1535
+ dots = 0;
+ for (cp = _res.defdname; *cp; cp++)
+ dots += (*cp == '.');
+
+ cp = _res.defdname;
+ while (pp < _res.dnsrch + MAXDFLSRCH) {
+ if (dots < LOCALDOMAINPARTS)
+ break;
+ cp = strchr(cp, '.') + 1; /* we know there is one */
+ *pp++ = cp;
+ dots--;
+ }
+ *pp = NULL;
+#ifdef DEBUG
+ if (_res.options & RES_DEBUG) {
+ printf(";; res_init()... default dnsrch list:\n");
+ for (pp = _res.dnsrch; *pp; pp++)
+ printf(";;\t%s\n", *pp);
+ printf(";;\t..END..\n");
+ }
+#endif /* DEBUG */
+#endif /* !RFC1535 */
+ }
+
+ if ((cp = getenv("RES_OPTIONS")) != NULL)
+ res_setoptions(cp, "env");
+ _res.options |= RES_INIT;
+ return (0);
+}
+
+static void
+res_setoptions(options, source)
+ char *options, *source;
+{
+ char *cp = options;
+ int i;
+
+#ifdef DEBUG
+ if (_res.options & RES_DEBUG)
+ printf(";; res_setoptions(\"%s\", \"%s\")...\n",
+ options, source);
+#endif
+ while (*cp) {
+ /* skip leading and inner runs of spaces */
+ while (*cp == ' ' || *cp == '\t')
+ cp++;
+ /* search for and process individual options */
+ if (!strncmp(cp, "ndots:", sizeof("ndots:") - 1)) {
+ i = atoi(cp + sizeof("ndots:") - 1);
+ if (i <= RES_MAXNDOTS)
+ _res.ndots = i;
+ else
+ _res.ndots = RES_MAXNDOTS;
+#ifdef DEBUG
+ if (_res.options & RES_DEBUG)
+ printf(";;\tndots=%d\n", _res.ndots);
+#endif
+ } else if (!strncmp(cp, "debug", sizeof("debug") - 1)) {
+#ifdef DEBUG
+ if (!(_res.options & RES_DEBUG)) {
+ printf(";; res_setoptions(\"%s\", \"%s\")..\n",
+ options, source);
+ _res.options |= RES_DEBUG;
+ }
+ printf(";;\tdebug\n");
+#endif
+ } else if (!strncmp(cp, "inet6", sizeof("inet6") - 1)) {
+ _res.options |= RES_USE_INET6;
+ } else {
+ /* XXX - print a warning here? */
+ }
+ /* skip to next run of spaces */
+ while (*cp && *cp != ' ' && *cp != '\t')
+ cp++;
+ }
+}
+
+#ifdef RESOLVSORT
+/* XXX - should really support CIDR which means explicit masks always. */
+static u_int32_t
+net_mask(in) /* XXX - should really use system's version of this */
+ struct in_addr in;
+{
+ register u_int32_t i = ntohl(in.s_addr);
+
+ if (IN_CLASSA(i))
+ return (htonl(IN_CLASSA_NET));
+ else if (IN_CLASSB(i))
+ return (htonl(IN_CLASSB_NET));
+ return (htonl(IN_CLASSC_NET));
+}
+#endif
+
+#ifdef NeXT
+static int
+netinfo_res_init(haveenv, havesearch)
+ int *haveenv;
+ int *havesearch;
+{
+ register int n;
+ void *domain, *parent;
+ ni_id dir;
+ ni_status status;
+ ni_namelist nl;
+ int nserv = 0;
+#ifdef RESOLVSORT
+ int nsort = 0;
+#endif
+
+ status = ni_open(NULL, ".", &domain);
+ if (status == NI_OK) {
+ ni_setreadtimeout(domain, NI_TIMEOUT);
+ ni_setabort(domain, 1);
+
+ /* climb the NetInfo hierarchy to find a resolver directory */
+ while (status == NI_OK) {
+ status = ni_pathsearch(domain, &dir, NI_PATH_RESCONF);
+ if (status == NI_OK) {
+ /* found a resolver directory */
+
+ if (*haveenv == 0) {
+ /* get the default domain name */
+ status = ni_lookupprop(domain, &dir, "domain", &nl);
+ if (status == NI_OK && nl.ni_namelist_len > 0) {
+ (void)strncpy(_res.defdname,
+ nl.ni_namelist_val[0],
+ sizeof(_res.defdname) - 1);
+ _res.defdname[sizeof(_res.defdname) - 1] = '\0';
+ ni_namelist_free(&nl);
+ *havesearch = 0;
+ }
+
+ /* get search list */
+ status = ni_lookupprop(domain, &dir, "search", &nl);
+ if (status == NI_OK && nl.ni_namelist_len > 0) {
+ (void)strncpy(_res.defdname,
+ nl.ni_namelist_val[0],
+ sizeof(_res.defdname) - 1);
+ _res.defdname[sizeof(_res.defdname) - 1] = '\0';
+ /* copy */
+ for (n = 0;
+ n < nl.ni_namelist_len && n < MAXDNSRCH;
+ n++) {
+ /* duplicate up to MAXDNSRCH servers */
+ char *cp = nl.ni_namelist_val[n];
+ _res.dnsrch[n] =
+ strcpy((char *)malloc(strlen(cp) + 1), cp);
+ }
+ ni_namelist_free(&nl);
+ *havesearch = 1;
+ }
+ }
+
+ /* get list of nameservers */
+ status = ni_lookupprop(domain, &dir, "nameserver", &nl);
+ if (status == NI_OK && nl.ni_namelist_len > 0) {
+ /* copy up to MAXNS servers */
+ for (n = 0;
+ n < nl.ni_namelist_len && nserv < MAXNS;
+ n++) {
+ struct in_addr a;
+
+ if (inet_aton(nl.ni_namelist_val[n], &a)) {
+ _res.nsaddr_list[nserv].sin_addr = a;
+ _res.nsaddr_list[nserv].sin_family = AF_INET;
+ _res.nsaddr_list[nserv].sin_port =
+ htons(NAMESERVER_PORT);
+ nserv++;
+ }
+ }
+ ni_namelist_free(&nl);
+ }
+
+ if (nserv > 1)
+ _res.nscount = nserv;
+
+#ifdef RESOLVSORT
+ /* get sort order */
+ status = ni_lookupprop(domain, &dir, "sortlist", &nl);
+ if (status == NI_OK && nl.ni_namelist_len > 0) {
+
+ /* copy up to MAXRESOLVSORT address/netmask pairs */
+ for (n = 0;
+ n < nl.ni_namelist_len && nsort < MAXRESOLVSORT;
+ n++) {
+ char ch;
+ char *cp;
+ const char *sp;
+ struct in_addr a;
+
+ cp = NULL;
+ for (sp = sort_mask; *sp; sp++) {
+ char *cp1;
+ cp1 = strchr(nl.ni_namelist_val[n], *sp);
+ if (cp && cp1)
+ cp = (cp < cp1)? cp : cp1;
+ else if (cp1)
+ cp = cp1;
+ }
+ if (cp != NULL) {
+ ch = *cp;
+ *cp = '\0';
+ break;
+ }
+ if (inet_aton(nl.ni_namelist_val[n], &a)) {
+ _res.sort_list[nsort].addr = a;
+ if (*cp && ISSORTMASK(ch)) {
+ *cp++ = ch;
+ if (inet_aton(cp, &a)) {
+ _res.sort_list[nsort].mask = a.s_addr;
+ } else {
+ _res.sort_list[nsort].mask =
+ net_mask(_res.sort_list[nsort].addr);
+ }
+ } else {
+ _res.sort_list[nsort].mask =
+ net_mask(_res.sort_list[nsort].addr);
+ }
+ nsort++;
+ }
+ }
+ ni_namelist_free(&nl);
+ }
+
+ _res.nsort = nsort;
+#endif
+
+ /* get resolver options */
+ status = ni_lookupprop(domain, &dir, "options", &nl);
+ if (status == NI_OK && nl.ni_namelist_len > 0) {
+ res_setoptions(nl.ni_namelist_val[0], "conf");
+ ni_namelist_free(&nl);
+ }
+
+ ni_free(domain);
+ return(1); /* using DNS configuration from NetInfo */
+ }
+
+ status = ni_open(domain, "..", &parent);
+ ni_free(domain);
+ if (status == NI_OK)
+ domain = parent;
+ }
+ }
+ return(0); /* if not using DNS configuration from NetInfo */
+}
+#endif /* NeXT */
+
+u_int16_t
+res_randomid()
+{
+ struct timeval now;
+
+ gettimeofday(&now, NULL);
+ return (0xffff & (now.tv_sec ^ now.tv_usec ^ getpid()));
+}
diff --git a/contrib/bind/res/res_mkquery.c b/contrib/bind/res/res_mkquery.c
new file mode 100644
index 0000000..17d6219
--- /dev/null
+++ b/contrib/bind/res/res_mkquery.c
@@ -0,0 +1,250 @@
+/*
+ * ++Copyright++ 1985, 1993
+ * -
+ * Copyright (c) 1985, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * -
+ * Portions Copyright (c) 1993 by Digital Equipment Corporation.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies, and that
+ * the name of Digital Equipment Corporation not be used in advertising or
+ * publicity pertaining to distribution of the document or software without
+ * specific, written prior permission.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
+ * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ * -
+ * --Copyright--
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)res_mkquery.c 8.1 (Berkeley) 6/4/93";
+static char rcsid[] = "$Id: res_mkquery.c,v 8.4 1996/08/05 08:31:35 vixie Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+
+#include <stdio.h>
+#include <netdb.h>
+#include <resolv.h>
+#if defined(BSD) && (BSD >= 199103)
+# include <string.h>
+#else
+# include "../conf/portability.h"
+#endif
+
+#if defined(USE_OPTIONS_H)
+# include <../conf/options.h>
+#endif
+
+/*
+ * Form all types of queries.
+ * Returns the size of the result or -1.
+ */
+int
+res_mkquery(op, dname, class, type, data, datalen, newrr_in, buf, buflen)
+ int op; /* opcode of query */
+ const char *dname; /* domain name */
+ int class, type; /* class and type of query */
+ const u_char *data; /* resource record data */
+ int datalen; /* length of data */
+ const u_char *newrr_in; /* new rr for modify or append */
+ u_char *buf; /* buffer to put query */
+ int buflen; /* size of buffer */
+{
+ register HEADER *hp;
+ register u_char *cp;
+ register int n;
+#ifdef ALLOW_UPDATES
+ struct rrec *newrr = (struct rrec *) newrr_in;
+#endif
+ u_char *dnptrs[20], **dpp, **lastdnptr;
+
+ if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
+ h_errno = NETDB_INTERNAL;
+ return (-1);
+ }
+#ifdef DEBUG
+ if (_res.options & RES_DEBUG)
+ printf(";; res_mkquery(%d, %s, %d, %d)\n",
+ op, dname, class, type);
+#endif
+ /*
+ * Initialize header fields.
+ */
+ if ((buf == NULL) || (buflen < HFIXEDSZ))
+ return (-1);
+ bzero(buf, HFIXEDSZ);
+ hp = (HEADER *) buf;
+ hp->id = htons(++_res.id);
+ hp->opcode = op;
+ hp->rd = (_res.options & RES_RECURSE) != 0;
+ hp->rcode = NOERROR;
+ cp = buf + HFIXEDSZ;
+ buflen -= HFIXEDSZ;
+ dpp = dnptrs;
+ *dpp++ = buf;
+ *dpp++ = NULL;
+ lastdnptr = dnptrs + sizeof dnptrs / sizeof dnptrs[0];
+ /*
+ * perform opcode specific processing
+ */
+ switch (op) {
+ case QUERY: /*FALLTHROUGH*/
+ case NS_NOTIFY_OP:
+ if ((buflen -= QFIXEDSZ) < 0)
+ return (-1);
+ if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0)
+ return (-1);
+ cp += n;
+ buflen -= n;
+ __putshort(type, cp);
+ cp += INT16SZ;
+ __putshort(class, cp);
+ cp += INT16SZ;
+ hp->qdcount = htons(1);
+ if (op == QUERY || data == NULL)
+ break;
+ /*
+ * Make an additional record for completion domain.
+ */
+ buflen -= RRFIXEDSZ;
+ n = dn_comp((char *)data, cp, buflen, dnptrs, lastdnptr);
+ if (n < 0)
+ return (-1);
+ cp += n;
+ buflen -= n;
+ __putshort(T_NULL, cp);
+ cp += INT16SZ;
+ __putshort(class, cp);
+ cp += INT16SZ;
+ __putlong(0, cp);
+ cp += INT32SZ;
+ __putshort(0, cp);
+ cp += INT16SZ;
+ hp->arcount = htons(1);
+ break;
+
+ case IQUERY:
+ /*
+ * Initialize answer section
+ */
+ if (buflen < 1 + RRFIXEDSZ + datalen)
+ return (-1);
+ *cp++ = '\0'; /* no domain name */
+ __putshort(type, cp);
+ cp += INT16SZ;
+ __putshort(class, cp);
+ cp += INT16SZ;
+ __putlong(0, cp);
+ cp += INT32SZ;
+ __putshort(datalen, cp);
+ cp += INT16SZ;
+ if (datalen) {
+ bcopy(data, cp, datalen);
+ cp += datalen;
+ }
+ hp->ancount = htons(1);
+ break;
+
+#ifdef ALLOW_UPDATES
+ /*
+ * For UPDATEM/UPDATEMA, do UPDATED/UPDATEDA followed by UPDATEA
+ * (Record to be modified is followed by its replacement in msg.)
+ */
+ case UPDATEM:
+ case UPDATEMA:
+
+ case UPDATED:
+ /*
+ * The res code for UPDATED and UPDATEDA is the same; user
+ * calls them differently: specifies data for UPDATED; server
+ * ignores data if specified for UPDATEDA.
+ */
+ case UPDATEDA:
+ buflen -= RRFIXEDSZ + datalen;
+ if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0)
+ return (-1);
+ cp += n;
+ __putshort(type, cp);
+ cp += INT16SZ;
+ __putshort(class, cp);
+ cp += INT16SZ;
+ __putlong(0, cp);
+ cp += INT32SZ;
+ __putshort(datalen, cp);
+ cp += INT16SZ;
+ if (datalen) {
+ bcopy(data, cp, datalen);
+ cp += datalen;
+ }
+ if ( (op == UPDATED) || (op == UPDATEDA) ) {
+ hp->ancount = htons(0);
+ break;
+ }
+ /* Else UPDATEM/UPDATEMA, so drop into code for UPDATEA */
+
+ case UPDATEA: /* Add new resource record */
+ buflen -= RRFIXEDSZ + datalen;
+ if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0)
+ return (-1);
+ cp += n;
+ __putshort(newrr->r_type, cp);
+ cp += INT16SZ;
+ __putshort(newrr->r_class, cp);
+ cp += INT16SZ;
+ __putlong(0, cp);
+ cp += INT32SZ;
+ __putshort(newrr->r_size, cp);
+ cp += INT16SZ;
+ if (newrr->r_size) {
+ bcopy(newrr->r_data, cp, newrr->r_size);
+ cp += newrr->r_size;
+ }
+ hp->ancount = htons(0);
+ break;
+#endif /* ALLOW_UPDATES */
+ default:
+ return (-1);
+ }
+ return (cp - buf);
+}
diff --git a/contrib/bind/res/res_query.c b/contrib/bind/res/res_query.c
new file mode 100644
index 0000000..dcc06cc
--- /dev/null
+++ b/contrib/bind/res/res_query.c
@@ -0,0 +1,392 @@
+/*
+ * ++Copyright++ 1988, 1993
+ * -
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * -
+ * Portions Copyright (c) 1993 by Digital Equipment Corporation.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies, and that
+ * the name of Digital Equipment Corporation not be used in advertising or
+ * publicity pertaining to distribution of the document or software without
+ * specific, written prior permission.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
+ * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ * -
+ * --Copyright--
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)res_query.c 8.1 (Berkeley) 6/4/93";
+static char rcsid[] = "$Id: res_query.c,v 8.7 1996/08/05 08:31:35 vixie Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+
+#include <stdio.h>
+#include <netdb.h>
+#include <resolv.h>
+#include <ctype.h>
+#include <errno.h>
+#if defined(BSD) && (BSD >= 199306)
+# include <stdlib.h>
+# include <string.h>
+#else
+# include "../conf/portability.h"
+#endif
+
+#if defined(USE_OPTIONS_H)
+# include <../conf/options.h>
+#endif
+
+#if PACKETSZ > 1024
+#define MAXPACKET PACKETSZ
+#else
+#define MAXPACKET 1024
+#endif
+
+char *__hostalias __P((const char *));
+int h_errno;
+
+/*
+ * Formulate a normal query, send, and await answer.
+ * Returned answer is placed in supplied buffer "answer".
+ * Perform preliminary check of answer, returning success only
+ * if no error is indicated and the answer count is nonzero.
+ * Return the size of the response on success, -1 on error.
+ * Error number is left in h_errno.
+ *
+ * Caller must parse answer and determine whether it answers the question.
+ */
+int
+res_query(name, class, type, answer, anslen)
+ const char *name; /* domain name */
+ int class, type; /* class and type of query */
+ u_char *answer; /* buffer to put answer */
+ int anslen; /* size of answer buffer */
+{
+ u_char buf[MAXPACKET];
+ register HEADER *hp = (HEADER *) answer;
+ int n;
+
+ hp->rcode = NOERROR; /* default */
+
+ if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
+ h_errno = NETDB_INTERNAL;
+ return (-1);
+ }
+#ifdef DEBUG
+ if (_res.options & RES_DEBUG)
+ printf(";; res_query(%s, %d, %d)\n", name, class, type);
+#endif
+
+ n = res_mkquery(QUERY, name, class, type, NULL, 0, NULL,
+ buf, sizeof(buf));
+ if (n <= 0) {
+#ifdef DEBUG
+ if (_res.options & RES_DEBUG)
+ printf(";; res_query: mkquery failed\n");
+#endif
+ h_errno = NO_RECOVERY;
+ return (n);
+ }
+ n = res_send(buf, n, answer, anslen);
+ if (n < 0) {
+#ifdef DEBUG
+ if (_res.options & RES_DEBUG)
+ printf(";; res_query: send error\n");
+#endif
+ h_errno = TRY_AGAIN;
+ return (n);
+ }
+
+ if (hp->rcode != NOERROR || ntohs(hp->ancount) == 0) {
+#ifdef DEBUG
+ if (_res.options & RES_DEBUG)
+ printf(";; rcode = %d, ancount=%d\n", hp->rcode,
+ ntohs(hp->ancount));
+#endif
+ switch (hp->rcode) {
+ case NXDOMAIN:
+ h_errno = HOST_NOT_FOUND;
+ break;
+ case SERVFAIL:
+ h_errno = TRY_AGAIN;
+ break;
+ case NOERROR:
+ h_errno = NO_DATA;
+ break;
+ case FORMERR:
+ case NOTIMP:
+ case REFUSED:
+ default:
+ h_errno = NO_RECOVERY;
+ break;
+ }
+ return (-1);
+ }
+ return (n);
+}
+
+/*
+ * Formulate a normal query, send, and retrieve answer in supplied buffer.
+ * Return the size of the response on success, -1 on error.
+ * If enabled, implement search rules until answer or unrecoverable failure
+ * is detected. Error code, if any, is left in h_errno.
+ */
+int
+res_search(name, class, type, answer, anslen)
+ const char *name; /* domain name */
+ int class, type; /* class and type of query */
+ u_char *answer; /* buffer to put answer */
+ int anslen; /* size of answer */
+{
+ register const char *cp, * const *domain;
+ HEADER *hp = (HEADER *) answer;
+ u_int dots;
+ int trailing_dot, ret, saved_herrno;
+ int got_nodata = 0, got_servfail = 0, tried_as_is = 0;
+
+ if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
+ h_errno = NETDB_INTERNAL;
+ return (-1);
+ }
+ errno = 0;
+ h_errno = HOST_NOT_FOUND; /* default, if we never query */
+ dots = 0;
+ for (cp = name; *cp; cp++)
+ dots += (*cp == '.');
+ trailing_dot = 0;
+ if (cp > name && *--cp == '.')
+ trailing_dot++;
+
+ /*
+ * if there aren't any dots, it could be a user-level alias
+ */
+ if (!dots && (cp = __hostalias(name)) != NULL)
+ return (res_query(cp, class, type, answer, anslen));
+
+ /*
+ * If there are dots in the name already, let's just give it a try
+ * 'as is'. The threshold can be set with the "ndots" option.
+ */
+ saved_herrno = -1;
+ if (dots >= _res.ndots) {
+ ret = res_querydomain(name, NULL, class, type, answer, anslen);
+ if (ret > 0)
+ return (ret);
+ saved_herrno = h_errno;
+ tried_as_is++;
+ }
+
+ /*
+ * We do at least one level of search if
+ * - there is no dot and RES_DEFNAME is set, or
+ * - there is at least one dot, there is no trailing dot,
+ * and RES_DNSRCH is set.
+ */
+ if ((!dots && (_res.options & RES_DEFNAMES)) ||
+ (dots && !trailing_dot && (_res.options & RES_DNSRCH))) {
+ int done = 0;
+
+ for (domain = (const char * const *)_res.dnsrch;
+ *domain && !done;
+ domain++) {
+
+ ret = res_querydomain(name, *domain, class, type,
+ answer, anslen);
+ if (ret > 0)
+ return (ret);
+
+ /*
+ * If no server present, give up.
+ * If name isn't found in this domain,
+ * keep trying higher domains in the search list
+ * (if that's enabled).
+ * On a NO_DATA error, keep trying, otherwise
+ * a wildcard entry of another type could keep us
+ * from finding this entry higher in the domain.
+ * If we get some other error (negative answer or
+ * server failure), then stop searching up,
+ * but try the input name below in case it's
+ * fully-qualified.
+ */
+ if (errno == ECONNREFUSED) {
+ h_errno = TRY_AGAIN;
+ return (-1);
+ }
+
+ switch (h_errno) {
+ case NO_DATA:
+ got_nodata++;
+ /* FALLTHROUGH */
+ case HOST_NOT_FOUND:
+ /* keep trying */
+ break;
+ case TRY_AGAIN:
+ if (hp->rcode == SERVFAIL) {
+ /* try next search element, if any */
+ got_servfail++;
+ break;
+ }
+ /* FALLTHROUGH */
+ default:
+ /* anything else implies that we're done */
+ done++;
+ }
+
+ /* if we got here for some reason other than DNSRCH,
+ * we only wanted one iteration of the loop, so stop.
+ */
+ if (!(_res.options & RES_DNSRCH))
+ done++;
+ }
+ }
+
+ /* if we have not already tried the name "as is", do that now.
+ * note that we do this regardless of how many dots were in the
+ * name or whether it ends with a dot.
+ */
+ if (!tried_as_is) {
+ ret = res_querydomain(name, NULL, class, type, answer, anslen);
+ if (ret > 0)
+ return (ret);
+ }
+
+ /* if we got here, we didn't satisfy the search.
+ * if we did an initial full query, return that query's h_errno
+ * (note that we wouldn't be here if that query had succeeded).
+ * else if we ever got a nodata, send that back as the reason.
+ * else send back meaningless h_errno, that being the one from
+ * the last DNSRCH we did.
+ */
+ if (saved_herrno != -1)
+ h_errno = saved_herrno;
+ else if (got_nodata)
+ h_errno = NO_DATA;
+ else if (got_servfail)
+ h_errno = TRY_AGAIN;
+ return (-1);
+}
+
+/*
+ * Perform a call on res_query on the concatenation of name and domain,
+ * removing a trailing dot from name if domain is NULL.
+ */
+int
+res_querydomain(name, domain, class, type, answer, anslen)
+ const char *name, *domain;
+ int class, type; /* class and type of query */
+ u_char *answer; /* buffer to put answer */
+ int anslen; /* size of answer */
+{
+ char nbuf[2*MAXDNAME+2];
+ const char *longname = nbuf;
+ int n;
+
+ if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
+ h_errno = NETDB_INTERNAL;
+ return (-1);
+ }
+#ifdef DEBUG
+ if (_res.options & RES_DEBUG)
+ printf(";; res_querydomain(%s, %s, %d, %d)\n",
+ name, domain?domain:"<Nil>", class, type);
+#endif
+ if (domain == NULL) {
+ /*
+ * Check for trailing '.';
+ * copy without '.' if present.
+ */
+ n = strlen(name) - 1;
+ if (n != (0 - 1) && name[n] == '.' && n < sizeof(nbuf) - 1) {
+ bcopy(name, nbuf, n);
+ nbuf[n] = '\0';
+ } else
+ longname = name;
+ } else
+ sprintf(nbuf, "%.*s.%.*s", MAXDNAME, name, MAXDNAME, domain);
+
+ return (res_query(longname, class, type, answer, anslen));
+}
+
+char *
+__hostalias(name)
+ register const char *name;
+{
+ register char *cp1, *cp2;
+ FILE *fp;
+ char *file;
+ char buf[BUFSIZ];
+ static char abuf[MAXDNAME];
+
+ if (_res.options & RES_NOALIASES)
+ return (NULL);
+ file = getenv("HOSTALIASES");
+ if (file == NULL || (fp = fopen(file, "r")) == NULL)
+ return (NULL);
+ setbuf(fp, NULL);
+ buf[sizeof(buf) - 1] = '\0';
+ while (fgets(buf, sizeof(buf), fp)) {
+ for (cp1 = buf; *cp1 && !isspace(*cp1); ++cp1)
+ ;
+ if (!*cp1)
+ break;
+ *cp1 = '\0';
+ if (!strcasecmp(buf, name)) {
+ while (isspace(*++cp1))
+ ;
+ if (!*cp1)
+ break;
+ for (cp2 = cp1 + 1; *cp2 && !isspace(*cp2); ++cp2)
+ ;
+ abuf[sizeof(abuf) - 1] = *cp2 = '\0';
+ strncpy(abuf, cp1, sizeof(abuf) - 1);
+ fclose(fp);
+ return (abuf);
+ }
+ }
+ fclose(fp);
+ return (NULL);
+}
diff --git a/contrib/bind/res/res_send.c b/contrib/bind/res/res_send.c
new file mode 100644
index 0000000..22712ac
--- /dev/null
+++ b/contrib/bind/res/res_send.c
@@ -0,0 +1,783 @@
+/*
+ * ++Copyright++ 1985, 1989, 1993
+ * -
+ * Copyright (c) 1985, 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * -
+ * Portions Copyright (c) 1993 by Digital Equipment Corporation.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies, and that
+ * the name of Digital Equipment Corporation not be used in advertising or
+ * publicity pertaining to distribution of the document or software without
+ * specific, written prior permission.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
+ * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ * -
+ * --Copyright--
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)res_send.c 8.1 (Berkeley) 6/4/93";
+static char rcsid[] = "$Id: res_send.c,v 8.9 1996/08/05 08:31:35 vixie Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+ /* change this to "0"
+ * if you talk to a lot
+ * of multi-homed SunOS
+ * ("broken") name servers.
+ */
+#define CHECK_SRVR_ADDR 1 /* XXX - should be in options.h */
+
+/*
+ * Send query to name server and wait for reply.
+ */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <arpa/inet.h>
+
+#include <stdio.h>
+#include <netdb.h>
+#include <errno.h>
+#include <resolv.h>
+#if defined(BSD) && (BSD >= 199306)
+# include <stdlib.h>
+# include <string.h>
+# include <unistd.h>
+#else
+# include "../conf/portability.h"
+#endif
+
+#if defined(USE_OPTIONS_H)
+# include <../conf/options.h>
+#endif
+
+void _res_close __P((void));
+
+static int s = -1; /* socket used for communications */
+static int connected = 0; /* is the socket connected */
+static int vc = 0; /* is the socket a virtual ciruit? */
+
+#ifndef FD_SET
+/* XXX - should be in portability.h */
+#define NFDBITS 32
+#define FD_SETSIZE 32
+#define FD_SET(n, p) ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
+#define FD_CLR(n, p) ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))
+#define FD_ISSET(n, p) ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))
+#define FD_ZERO(p) bzero((char *)(p), sizeof(*(p)))
+#endif
+
+/* XXX - this should be done in portability.h */
+#if (defined(BSD) && (BSD >= 199103)) || defined(linux)
+# define CAN_RECONNECT 1
+#else
+# define CAN_RECONNECT 0
+#endif
+
+#ifndef DEBUG
+# define Dprint(cond, args) /*empty*/
+# define DprintQ(cond, args, query, size) /*empty*/
+# define Aerror(file, string, error, address) /*empty*/
+# define Perror(file, string, error) /*empty*/
+#else
+# define Dprint(cond, args) if (cond) {fprintf args;} else {}
+# define DprintQ(cond, args, query, size) if (cond) {\
+ fprintf args;\
+ __fp_nquery(query, size, stdout);\
+ } else {}
+ static void
+ Aerror(file, string, error, address)
+ FILE *file;
+ char *string;
+ int error;
+ struct sockaddr_in address;
+ {
+ int save = errno;
+
+ if (_res.options & RES_DEBUG) {
+ fprintf(file, "res_send: %s ([%s].%u): %s\n",
+ string,
+ inet_ntoa(address.sin_addr),
+ ntohs(address.sin_port),
+ strerror(error));
+ }
+ errno = save;
+ }
+ static void
+ Perror(file, string, error)
+ FILE *file;
+ char *string;
+ int error;
+ {
+ int save = errno;
+
+ if (_res.options & RES_DEBUG) {
+ fprintf(file, "res_send: %s: %s\n",
+ string, strerror(error));
+ }
+ errno = save;
+ }
+#endif
+
+static res_send_qhook Qhook = NULL;
+static res_send_rhook Rhook = NULL;
+
+void
+res_send_setqhook(hook)
+ res_send_qhook hook;
+{
+
+ Qhook = hook;
+}
+
+void
+res_send_setrhook(hook)
+ res_send_rhook hook;
+{
+
+ Rhook = hook;
+}
+
+/* int
+ * res_isourserver(ina)
+ * looks up "ina" in _res.ns_addr_list[]
+ * returns:
+ * 0 : not found
+ * >0 : found
+ * author:
+ * paul vixie, 29may94
+ */
+int
+res_isourserver(inp)
+ const struct sockaddr_in *inp;
+{
+ struct sockaddr_in ina;
+ register int ns, ret;
+
+ ina = *inp;
+ ret = 0;
+ for (ns = 0; ns < _res.nscount; ns++) {
+ register const struct sockaddr_in *srv = &_res.nsaddr_list[ns];
+
+ if (srv->sin_family == ina.sin_family &&
+ srv->sin_port == ina.sin_port &&
+ (srv->sin_addr.s_addr == INADDR_ANY ||
+ srv->sin_addr.s_addr == ina.sin_addr.s_addr)) {
+ ret++;
+ break;
+ }
+ }
+ return (ret);
+}
+
+/* int
+ * res_nameinquery(name, type, class, buf, eom)
+ * look for (name,type,class) in the query section of packet (buf,eom)
+ * returns:
+ * -1 : format error
+ * 0 : not found
+ * >0 : found
+ * author:
+ * paul vixie, 29may94
+ */
+int
+res_nameinquery(name, type, class, buf, eom)
+ const char *name;
+ register int type, class;
+ const u_char *buf, *eom;
+{
+ register const u_char *cp = buf + HFIXEDSZ;
+ int qdcount = ntohs(((HEADER*)buf)->qdcount);
+
+ while (qdcount-- > 0) {
+ char tname[MAXDNAME+1];
+ register int n, ttype, tclass;
+
+ n = dn_expand(buf, eom, cp, tname, sizeof tname);
+ if (n < 0)
+ return (-1);
+ cp += n;
+ ttype = _getshort(cp); cp += INT16SZ;
+ tclass = _getshort(cp); cp += INT16SZ;
+ if (ttype == type &&
+ tclass == class &&
+ strcasecmp(tname, name) == 0)
+ return (1);
+ }
+ return (0);
+}
+
+/* int
+ * res_queriesmatch(buf1, eom1, buf2, eom2)
+ * is there a 1:1 mapping of (name,type,class)
+ * in (buf1,eom1) and (buf2,eom2)?
+ * returns:
+ * -1 : format error
+ * 0 : not a 1:1 mapping
+ * >0 : is a 1:1 mapping
+ * author:
+ * paul vixie, 29may94
+ */
+int
+res_queriesmatch(buf1, eom1, buf2, eom2)
+ const u_char *buf1, *eom1;
+ const u_char *buf2, *eom2;
+{
+ register const u_char *cp = buf1 + HFIXEDSZ;
+ int qdcount = ntohs(((HEADER*)buf1)->qdcount);
+
+ if (qdcount != ntohs(((HEADER*)buf2)->qdcount))
+ return (0);
+ while (qdcount-- > 0) {
+ char tname[MAXDNAME+1];
+ register int n, ttype, tclass;
+
+ n = dn_expand(buf1, eom1, cp, tname, sizeof tname);
+ if (n < 0)
+ return (-1);
+ cp += n;
+ ttype = _getshort(cp); cp += INT16SZ;
+ tclass = _getshort(cp); cp += INT16SZ;
+ if (!res_nameinquery(tname, ttype, tclass, buf2, eom2))
+ return (0);
+ }
+ return (1);
+}
+
+int
+res_send(buf, buflen, ans, anssiz)
+ const u_char *buf;
+ int buflen;
+ u_char *ans;
+ int anssiz;
+{
+ HEADER *hp = (HEADER *) buf;
+ HEADER *anhp = (HEADER *) ans;
+ int gotsomewhere, connreset, terrno, try, v_circuit, resplen, ns;
+ register int n;
+ u_int badns; /* XXX NSMAX can't exceed #/bits in this var */
+
+ if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
+ /* errno should have been set by res_init() in this case. */
+ return (-1);
+ }
+ DprintQ((_res.options & RES_DEBUG) || (_res.pfcode & RES_PRF_QUERY),
+ (stdout, ";; res_send()\n"), buf, buflen);
+ v_circuit = (_res.options & RES_USEVC) || buflen > PACKETSZ;
+ gotsomewhere = 0;
+ connreset = 0;
+ terrno = ETIMEDOUT;
+ badns = 0;
+
+ /*
+ * Send request, RETRY times, or until successful
+ */
+ for (try = 0; try < _res.retry; try++) {
+ for (ns = 0; ns < _res.nscount; ns++) {
+ struct sockaddr_in *nsap = &_res.nsaddr_list[ns];
+ same_ns:
+ if (badns & (1 << ns)) {
+ _res_close();
+ goto next_ns;
+ }
+
+ if (Qhook) {
+ int done = 0, loops = 0;
+
+ do {
+ res_sendhookact act;
+
+ act = (*Qhook)(&nsap, &buf, &buflen,
+ ans, anssiz, &resplen);
+ switch (act) {
+ case res_goahead:
+ done = 1;
+ break;
+ case res_nextns:
+ _res_close();
+ goto next_ns;
+ case res_done:
+ return (resplen);
+ case res_modified:
+ /* give the hook another try */
+ if (++loops < 42) /*doug adams*/
+ break;
+ /*FALLTHROUGH*/
+ case res_error:
+ /*FALLTHROUGH*/
+ default:
+ return (-1);
+ }
+ } while (!done);
+ }
+
+ Dprint(_res.options & RES_DEBUG,
+ (stdout, ";; Querying server (# %d) address = %s\n",
+ ns + 1, inet_ntoa(nsap->sin_addr)));
+
+ if (v_circuit) {
+ int truncated;
+ struct iovec iov[2];
+ u_short len;
+ u_char *cp;
+
+ /*
+ * Use virtual circuit;
+ * at most one attempt per server.
+ */
+ try = _res.retry;
+ truncated = 0;
+ if ((s < 0) || (!vc)) {
+ if (s >= 0)
+ _res_close();
+
+ s = socket(PF_INET, SOCK_STREAM, 0);
+ if (s < 0) {
+ terrno = errno;
+ Perror(stderr, "socket(vc)", errno);
+ return (-1);
+ }
+ errno = 0;
+ if (connect(s, (struct sockaddr *)nsap,
+ sizeof(struct sockaddr)) < 0) {
+ terrno = errno;
+ Aerror(stderr, "connect/vc",
+ errno, *nsap);
+ badns |= (1 << ns);
+ _res_close();
+ goto next_ns;
+ }
+ vc = 1;
+ }
+ /*
+ * Send length & message
+ */
+ putshort((u_short)buflen, (u_char*)&len);
+ iov[0].iov_base = (caddr_t)&len;
+ iov[0].iov_len = INT16SZ;
+ iov[1].iov_base = (caddr_t)buf;
+ iov[1].iov_len = buflen;
+ if (writev(s, iov, 2) != (INT16SZ + buflen)) {
+ terrno = errno;
+ Perror(stderr, "write failed", errno);
+ badns |= (1 << ns);
+ _res_close();
+ goto next_ns;
+ }
+ /*
+ * Receive length & response
+ */
+read_len:
+ cp = ans;
+ len = INT16SZ;
+ while ((n = read(s, (char *)cp, (int)len)) > 0) {
+ cp += n;
+ if ((len -= n) <= 0)
+ break;
+ }
+ if (n <= 0) {
+ terrno = errno;
+ Perror(stderr, "read failed", errno);
+ _res_close();
+ /*
+ * A long running process might get its TCP
+ * connection reset if the remote server was
+ * restarted. Requery the server instead of
+ * trying a new one. When there is only one
+ * server, this means that a query might work
+ * instead of failing. We only allow one reset
+ * per query to prevent looping.
+ */
+ if (terrno == ECONNRESET && !connreset) {
+ connreset = 1;
+ _res_close();
+ goto same_ns;
+ }
+ _res_close();
+ goto next_ns;
+ }
+ resplen = _getshort(ans);
+ if (resplen > anssiz) {
+ Dprint(_res.options & RES_DEBUG,
+ (stdout, ";; response truncated\n")
+ );
+ truncated = 1;
+ len = anssiz;
+ } else
+ len = resplen;
+ cp = ans;
+ while (len != 0 &&
+ (n = read(s, (char *)cp, (int)len)) > 0) {
+ cp += n;
+ len -= n;
+ }
+ if (n <= 0) {
+ terrno = errno;
+ Perror(stderr, "read(vc)", errno);
+ _res_close();
+ goto next_ns;
+ }
+ if (truncated) {
+ /*
+ * Flush rest of answer
+ * so connection stays in synch.
+ */
+ anhp->tc = 1;
+ len = resplen - anssiz;
+ while (len != 0) {
+ char junk[PACKETSZ];
+
+ n = (len > sizeof(junk)
+ ? sizeof(junk)
+ : len);
+ if ((n = read(s, junk, n)) > 0)
+ len -= n;
+ else
+ break;
+ }
+ }
+ /*
+ * The calling applicating has bailed out of
+ * a previous call and failed to arrange to have
+ * the circuit closed or the server has got
+ * itself confused. Anyway drop the packet and
+ * wait for the correct one.
+ */
+ if (hp->id != anhp->id) {
+ DprintQ((_res.options & RES_DEBUG) ||
+ (_res.pfcode & RES_PRF_REPLY),
+ (stdout, ";; old answer (unexpected):\n"),
+ ans, (resplen>anssiz)?anssiz:resplen);
+ goto read_len;
+ }
+ } else {
+ /*
+ * Use datagrams.
+ */
+ struct timeval timeout;
+ fd_set dsmask;
+ struct sockaddr_in from;
+ int fromlen;
+
+ if ((s < 0) || vc) {
+ if (vc)
+ _res_close();
+ s = socket(PF_INET, SOCK_DGRAM, 0);
+ if (s < 0) {
+#if !CAN_RECONNECT
+ bad_dg_sock:
+#endif
+ terrno = errno;
+ Perror(stderr, "socket(dg)", errno);
+ return (-1);
+ }
+ connected = 0;
+ }
+ /*
+ * On a 4.3BSD+ machine (client and server,
+ * actually), sending to a nameserver datagram
+ * port with no nameserver will cause an
+ * ICMP port unreachable message to be returned.
+ * If our datagram socket is "connected" to the
+ * server, we get an ECONNREFUSED error on the next
+ * socket operation, and select returns if the
+ * error message is received. We can thus detect
+ * the absence of a nameserver without timing out.
+ * If we have sent queries to at least two servers,
+ * however, we don't want to remain connected,
+ * as we wish to receive answers from the first
+ * server to respond.
+ */
+ if (_res.nscount == 1 || (try == 0 && ns == 0)) {
+ /*
+ * Connect only if we are sure we won't
+ * receive a response from another server.
+ */
+ if (!connected) {
+ if (connect(s, (struct sockaddr *)nsap,
+ sizeof(struct sockaddr)
+ ) < 0) {
+ Aerror(stderr,
+ "connect(dg)",
+ errno, *nsap);
+ badns |= (1 << ns);
+ _res_close();
+ goto next_ns;
+ }
+ connected = 1;
+ }
+ if (send(s, (char*)buf, buflen, 0) != buflen) {
+ Perror(stderr, "send", errno);
+ badns |= (1 << ns);
+ _res_close();
+ goto next_ns;
+ }
+ } else {
+ /*
+ * Disconnect if we want to listen
+ * for responses from more than one server.
+ */
+ if (connected) {
+#if CAN_RECONNECT
+ struct sockaddr_in no_addr;
+
+ no_addr.sin_family = AF_INET;
+ no_addr.sin_addr.s_addr = INADDR_ANY;
+ no_addr.sin_port = 0;
+ (void) connect(s,
+ (struct sockaddr *)
+ &no_addr,
+ sizeof(no_addr));
+#else
+ int s1 = socket(PF_INET, SOCK_DGRAM,0);
+ if (s1 < 0)
+ goto bad_dg_sock;
+ (void) dup2(s1, s);
+ (void) close(s1);
+ Dprint(_res.options & RES_DEBUG,
+ (stdout, ";; new DG socket\n"))
+#endif
+ connected = 0;
+ errno = 0;
+ }
+ if (sendto(s, (char*)buf, buflen, 0,
+ (struct sockaddr *)nsap,
+ sizeof(struct sockaddr))
+ != buflen) {
+ Aerror(stderr, "sendto", errno, *nsap);
+ badns |= (1 << ns);
+ _res_close();
+ goto next_ns;
+ }
+ }
+
+ /*
+ * Wait for reply
+ */
+ timeout.tv_sec = (_res.retrans << try);
+ if (try > 0)
+ timeout.tv_sec /= _res.nscount;
+ if ((long) timeout.tv_sec <= 0)
+ timeout.tv_sec = 1;
+ timeout.tv_usec = 0;
+ wait:
+ FD_ZERO(&dsmask);
+ FD_SET(s, &dsmask);
+ n = select(s+1, &dsmask, (fd_set *)NULL,
+ (fd_set *)NULL, &timeout);
+ if (n < 0) {
+ if (errno == EINTR)
+ goto wait;
+ Perror(stderr, "select", errno);
+ _res_close();
+ goto next_ns;
+ }
+ if (n == 0) {
+ /*
+ * timeout
+ */
+ Dprint(_res.options & RES_DEBUG,
+ (stdout, ";; timeout\n"));
+ gotsomewhere = 1;
+ _res_close();
+ goto next_ns;
+ }
+ errno = 0;
+ fromlen = sizeof(struct sockaddr_in);
+ resplen = recvfrom(s, (char*)ans, anssiz, 0,
+ (struct sockaddr *)&from, &fromlen);
+ if (resplen <= 0) {
+ Perror(stderr, "recvfrom", errno);
+ _res_close();
+ goto next_ns;
+ }
+ gotsomewhere = 1;
+ if (hp->id != anhp->id) {
+ /*
+ * response from old query, ignore it.
+ * XXX - potential security hazard could
+ * be detected here.
+ */
+ DprintQ((_res.options & RES_DEBUG) ||
+ (_res.pfcode & RES_PRF_REPLY),
+ (stdout, ";; old answer:\n"),
+ ans, (resplen>anssiz)?anssiz:resplen);
+ goto wait;
+ }
+#if CHECK_SRVR_ADDR
+ if (!(_res.options & RES_INSECURE1) &&
+ !res_isourserver(&from)) {
+ /*
+ * response from wrong server? ignore it.
+ * XXX - potential security hazard could
+ * be detected here.
+ */
+ DprintQ((_res.options & RES_DEBUG) ||
+ (_res.pfcode & RES_PRF_REPLY),
+ (stdout, ";; not our server:\n"),
+ ans, (resplen>anssiz)?anssiz:resplen);
+ goto wait;
+ }
+#endif
+ if (!(_res.options & RES_INSECURE2) &&
+ !res_queriesmatch(buf, buf + buflen,
+ ans, ans + anssiz)) {
+ /*
+ * response contains wrong query? ignore it.
+ * XXX - potential security hazard could
+ * be detected here.
+ */
+ DprintQ((_res.options & RES_DEBUG) ||
+ (_res.pfcode & RES_PRF_REPLY),
+ (stdout, ";; wrong query name:\n"),
+ ans, (resplen>anssiz)?anssiz:resplen);
+ goto wait;
+ }
+ if (anhp->rcode == SERVFAIL ||
+ anhp->rcode == NOTIMP ||
+ anhp->rcode == REFUSED) {
+ DprintQ(_res.options & RES_DEBUG,
+ (stdout, "server rejected query:\n"),
+ ans, (resplen>anssiz)?anssiz:resplen);
+ badns |= (1 << ns);
+ _res_close();
+ /* don't retry if called from dig */
+ if (!_res.pfcode)
+ goto next_ns;
+ }
+ if (!(_res.options & RES_IGNTC) && anhp->tc) {
+ /*
+ * get rest of answer;
+ * use TCP with same server.
+ */
+ Dprint(_res.options & RES_DEBUG,
+ (stdout, ";; truncated answer\n"));
+ v_circuit = 1;
+ _res_close();
+ goto same_ns;
+ }
+ } /*if vc/dg*/
+ Dprint((_res.options & RES_DEBUG) ||
+ ((_res.pfcode & RES_PRF_REPLY) &&
+ (_res.pfcode & RES_PRF_HEAD1)),
+ (stdout, ";; got answer:\n"));
+ DprintQ((_res.options & RES_DEBUG) ||
+ (_res.pfcode & RES_PRF_REPLY),
+ (stdout, ""),
+ ans, (resplen>anssiz)?anssiz:resplen);
+ /*
+ * If using virtual circuits, we assume that the first server
+ * is preferred over the rest (i.e. it is on the local
+ * machine) and only keep that one open.
+ * If we have temporarily opened a virtual circuit,
+ * or if we haven't been asked to keep a socket open,
+ * close the socket.
+ */
+ if ((v_circuit && (!(_res.options & RES_USEVC) || ns != 0)) ||
+ !(_res.options & RES_STAYOPEN)) {
+ _res_close();
+ }
+ if (Rhook) {
+ int done = 0, loops = 0;
+
+ do {
+ res_sendhookact act;
+
+ act = (*Rhook)(nsap, buf, buflen,
+ ans, anssiz, &resplen);
+ switch (act) {
+ case res_goahead:
+ case res_done:
+ done = 1;
+ break;
+ case res_nextns:
+ _res_close();
+ goto next_ns;
+ case res_modified:
+ /* give the hook another try */
+ if (++loops < 42) /*doug adams*/
+ break;
+ /*FALLTHROUGH*/
+ case res_error:
+ /*FALLTHROUGH*/
+ default:
+ return (-1);
+ }
+ } while (!done);
+
+ }
+ return (resplen);
+ next_ns: ;
+ } /*foreach ns*/
+ } /*foreach retry*/
+ _res_close();
+ if (!v_circuit)
+ if (!gotsomewhere)
+ errno = ECONNREFUSED; /* no nameservers found */
+ else
+ errno = ETIMEDOUT; /* no answer obtained */
+ else
+ errno = terrno;
+ return (-1);
+}
+
+/*
+ * This routine is for closing the socket if a virtual circuit is used and
+ * the program wants to close it. This provides support for endhostent()
+ * which expects to close the socket.
+ *
+ * This routine is not expected to be user visible.
+ */
+void
+_res_close()
+{
+ if (s >= 0) {
+ (void) close(s);
+ s = -1;
+ connected = 0;
+ vc = 0;
+ }
+}
diff --git a/contrib/bind/res/sethostent.c b/contrib/bind/res/sethostent.c
new file mode 100644
index 0000000..555bf35
--- /dev/null
+++ b/contrib/bind/res/sethostent.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 1985, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)sethostent.c 8.1 (Berkeley) 6/4/93";
+static char rcsid[] = "$Id: sethostent.c,v 8.4 1996/08/05 08:31:35 vixie Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <netdb.h>
+#include <resolv.h>
+
+void _res_close __P((void));
+
+void
+sethostent(stayopen)
+ int stayopen;
+{
+ if ((_res.options & RES_INIT) == 0 && res_init() == -1)
+ return;
+ if (stayopen)
+ _res.options |= RES_STAYOPEN | RES_USEVC;
+}
+
+void
+endhostent()
+{
+ _res.options &= ~(RES_STAYOPEN | RES_USEVC);
+ _res_close();
+}
diff --git a/contrib/bind/tools/Makefile b/contrib/bind/tools/Makefile
new file mode 100644
index 0000000..63a2467
--- /dev/null
+++ b/contrib/bind/tools/Makefile
@@ -0,0 +1,163 @@
+#
+# @(#)Makefile 4.9 (Berkeley) 10/10/88
+# $Id: Makefile,v 8.7 1996/05/20 15:10:04 vixie Exp $
+#
+
+## ++Copyright++ 1987
+## -
+## Copyright (c) 1987
+## The Regents of the University of California. All rights reserved.
+##
+## Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions
+## are met:
+## 1. Redistributions of source code must retain the above copyright
+## notice, this list of conditions and the following disclaimer.
+## 2. Redistributions in binary form must reproduce the above copyright
+## notice, this list of conditions and the following disclaimer in the
+## documentation and/or other materials provided with the distribution.
+## 3. All advertising materials mentioning features or use of this software
+## must display the following acknowledgement:
+## This product includes software developed by the University of
+## California, Berkeley and its contributors.
+## 4. Neither the name of the University nor the names of its contributors
+## may be used to endorse or promote products derived from this software
+## without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+## ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+## ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+## FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+## OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+## HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+## LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+## OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+## SUCH DAMAGE.
+## -
+## Portions Copyright (c) 1993 by Digital Equipment Corporation.
+##
+## Permission to use, copy, modify, and distribute this software for any
+## purpose with or without fee is hereby granted, provided that the above
+## copyright notice and this permission notice appear in all copies, and that
+## the name of Digital Equipment Corporation not be used in advertising or
+## publicity pertaining to distribution of the document or software without
+## specific, written prior permission.
+##
+## THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
+## WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
+## OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
+## CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+## DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+## PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+## ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+## SOFTWARE.
+## -
+## --Copyright--
+
+DESTDIR=
+CC= cc
+SHELL= /bin/sh
+
+CDEBUG= -g
+
+INCL = ../include
+RES= ../res/libresolv.a
+COMPLIB= ../compat/lib/lib44bsd.a
+
+LEX= lex
+LIBS= -ll
+PIDDIR = /etc
+DESTBIN = /usr/bin
+DESTSBIN = /usr/etc
+DESTEXEC = /usr/etc
+DESTMAN = /usr/man
+COMPINCL = ../compat/include
+DESTHELP= /usr/lib
+
+#(net2 and its descendents)
+#LEX = lex -I
+#LIBS = -ll -lutil
+#PIDDIR = /var/run
+#DESTBIN = /usr/bin
+#DESTSBIN = /usr/sbin
+#DESTEXEC = /usr/libexec
+#DESTMAN = /usr/share/man
+#COMPINCL = .
+#DESTHELP= /usr/share/misc
+
+LDFLAGS=
+MARGS = "CC=$(CC)" "LEX=$(LEX)" "CDEBUG=$(CDEBUG)" "SHELL=$(SHELL)" \
+ "INCL=../$(INCL)" "RES=../$(RES)" "LIBS=$(LIBS)" "LDFLAGS=$(LDFLAGS)" \
+ "DESTDIR=$(DESTDIR)" "PIDDIR=${PIDDIR}" "DESTMAN=${DESTMAN}" \
+ "DESTBIN=${DESTBIN}" "DESTSBIN=${DESTSBIN}" "DESTEXEC=${DESTEXEC}" \
+ "DESTLIB=${DESTLIB}" "DESTINC=${DESTINC}" "RANLIB=${RANLIB}" \
+ "COMPINCL=../${COMPINCL}" "DESTHELP=${DESTHELP}" \
+ "COMPLIB=../${COMPLIB}" "INSTALL=${INSTALL}" \
+ "CPPFLAGS=${CPPFLAGS}"
+
+CFLAGS= $(CDEBUG) -I$(INCL) -I$(COMPINCL)
+SRCS= host.c dig.c dnsquery.c addr.c
+HOST_O= host.o
+DIG_O= dig.o nslookup/list.o nslookup/subr.o nslookup/debug.o nslookup/send.o
+DNSQUERY_O= dnsquery.o
+ADDR_O= addr.o
+
+SUBDIRS = nslookup
+BINARIES = host dig dnsquery addr
+
+all: ${SUBDIRS} ${BINARIES}
+
+host: ${HOST_O} ${RES} ${COMPLIB} Makefile
+ ${CC} ${CFLAGS} ${LDFLAGS} -o $@ ${HOST_O} \
+ ${RES} ${COMPLIB} ${LIBS}
+
+dig: ${DIG_O} ${RES} ${COMPLIB} Makefile
+ ${CC} ${CFLAGS} ${LDFLAGS} -o $@ ${DIG_O} \
+ ${RES} ${COMPLIB} ${LIBS}
+
+dnsquery: ${DNSQUERY_O} ${RES} ${COMPLIB} Makefile
+ ${CC} ${CFLAGS} ${LDFLAGS} -o $@ ${DNSQUERY_O} \
+ ${RES} ${COMPLIB} ${LIBS}
+
+addr: ${ADDR_O} ${RES} ${COMPLIB} Makefile
+ ${CC} ${CFLAGS} ${LDFLAGS} -o $@ ${ADDR_O} \
+ ${RES} ${COMPLIB} ${LIBS}
+
+${SUBDIRS}: FRC
+ cd $@; ${MAKE} ${MARGS}
+
+clean: FRC
+ @for x in ${SUBDIRS}; do \
+ (cd $$x; pwd; ${MAKE} ${MARGS} clean); \
+ done
+ rm -f ${BINARIES} core .depend
+ rm -f *.BAK *.CKP *~ *.o *.orig
+
+depend: ${SRCS}
+ @for x in ${SUBDIRS}; do \
+ (cd $$x; pwd; ${MAKE} ${MARGS} depend); \
+ done
+ mkdep -p ${CPPFLAGS} -I${INCL} -I${COMPINCL} ${SRCS}
+
+install: FRC
+ @for x in ${SUBDIRS}; do \
+ (cd $$x; pwd; ${MAKE} ${MARGS} DESTDIR=${DESTDIR} install); \
+ done
+ @set -x; for x in ${BINARIES}; do \
+ ${INSTALL} -s -c -m 755 $$x ${DESTDIR}${DESTBIN}/$$x; \
+ done
+
+lint: ${SRCS}
+ @(cd nslookup; pwd; ${MAKE} ${MARGS} lint)
+ lint ${CFLAGS} ${SRCS}
+
+tags: ${SRCS}
+ cd nslookup; ${MAKE} ${MARGS} tags
+ ctags ${SRCS}
+
+FRC:
+
+# DO NOT DELETE THIS LINE -- mkdep uses it.
+# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY.
diff --git a/contrib/bind/tools/addr.c b/contrib/bind/tools/addr.c
new file mode 100644
index 0000000..98a505c
--- /dev/null
+++ b/contrib/bind/tools/addr.c
@@ -0,0 +1,173 @@
+#if !defined(lint) && !defined(SABER)
+static char rcsid[] = "$Id: addr.c,v 8.4 1996/05/23 08:21:28 vixie Exp $";
+#endif /* not lint */
+
+/* Copyright (c) 1996 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#include <sys/param.h>
+#include <sys/file.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <arpa/inet.h>
+#include <string.h>
+#include <stdio.h>
+#include <ctype.h>
+#include "../conf/portability.h"
+
+extern char *optarg;
+extern int optind;
+extern int opterr;
+extern int optopt;
+
+static const char *prog = "addr";
+
+#define BIGGEST_ADDRESS IN6ADDRSZ
+
+static void
+usage() {
+ fprintf(stderr,
+ "usage: %s [-4] [-6] [-n hexstring] [-p address]\n",
+ prog);
+ exit(1);
+}
+
+/* Warning: this scribbles on `dst' even if it's going to return `0'. */
+static int
+hexstring(src, dst, len)
+ const char *src;
+ u_char *dst;
+ int len;
+{
+ static const char xdigits[] = "0123456789abcdef";
+ u_char *ptr = dst, *end = dst + len;
+ u_int val;
+ int ch, digits;
+
+ val = 0;
+ digits = 0;
+ bzero((void*)dst, len);
+ while ((ch = *src++) != '\0') {
+ if (ch == '0' && (*src == 'x' || *src == 'X')) {
+ src++;
+ continue;
+ }
+ if (isascii(ch) && (isspace(ch) || ispunct(ch))) {
+ if (digits > 0) {
+ if (ptr == end)
+ return (0);
+ *ptr++ = (u_char) (val & 0xff);
+ val = 0;
+ digits = 0;
+ }
+ digits = 0;
+ continue;
+ }
+ if (!isascii(ch) || !isxdigit(ch))
+ return (0);
+ if (isupper(ch))
+ ch = tolower(ch);
+ /* Clock it in using little endian arithmetic. */
+ val <<= 4;
+ val |= (strchr(xdigits, ch) - xdigits);
+ if (++digits == 2) {
+ if (ptr == end)
+ return (0);
+ *ptr++ = (u_char) (val & 0xff);
+ digits = 0;
+ val = 0;
+ }
+ }
+ if (digits > 0) {
+ if (ptr == end)
+ return (0);
+ *ptr++ = (u_char) (val & 0xff);
+ }
+ return ((ptr - dst) == len);
+}
+
+static void
+display(input, af, addr, len)
+ const char *input;
+ int af;
+ const u_char *addr;
+ int len;
+{
+ static int before = 0;
+ char p[sizeof "xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255"];
+ int i;
+
+ if (before)
+ putchar('\n');
+ else
+ before++;
+
+ printf("Input: \"%s\"\n", input);
+ printf("Network: [af%d len%d]", af, len);
+ for (i = 0; i < len; i++)
+ printf(" %02x", addr[i]);
+ putchar('\n');
+ printf("Presentation: \"%s\"\n", inet_ntop(af, addr, p, sizeof p));
+}
+
+int
+main(argc, argv)
+ int argc;
+ char *argv[];
+{
+ u_char addr[BIGGEST_ADDRESS];
+ int optchr, af, len;
+
+ prog = argv[0];
+ af = AF_INET;
+ len = INADDRSZ;
+ while ((optchr = getopt(argc, argv, "46n:p:")) != -1) {
+ switch (optchr) {
+ case '4':
+ af = AF_INET;
+ len = INADDRSZ;
+ break;
+ case '6':
+ af = AF_INET6;
+ len = IN6ADDRSZ;
+ break;
+ case 'n':
+ if (!hexstring(optarg, addr, len)) {
+ fprintf(stderr, "bad hex string: \"%s\"\n",
+ optarg);
+ usage();
+ /* NOTREACHED */
+ }
+ display(optarg, af, addr, len);
+ break;
+ case 'p':
+ if (inet_pton(af, optarg, addr) <= 0) {
+ fprintf(stderr, "bad address: \"%s\"\n",
+ optarg);
+ usage();
+ /* NOTREACHED */
+ }
+ display(optarg, af, addr, len);
+ break;
+ default:
+ usage();
+ /* NOTREACHED */
+ }
+ }
+ exit(0);
+ /* NOTREACHED */
+}
diff --git a/contrib/bind/tools/dig.c b/contrib/bind/tools/dig.c
new file mode 100644
index 0000000..e2cef9a
--- /dev/null
+++ b/contrib/bind/tools/dig.c
@@ -0,0 +1,1236 @@
+#ifndef lint
+static char rcsid[] = "$Id: dig.c,v 8.8 1996/05/21 07:32:40 vixie Exp $";
+#endif
+
+/*
+ * ++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--
+ */
+
+/*********************** Notes for the BIND 4.9 release (Paul Vixie, DEC)
+ * dig 2.0 was written by copying sections of libresolv.a and nslookup
+ * and modifying them to be more useful for a general lookup utility.
+ * as of BIND 4.9, the changes needed to support dig have mostly been
+ * incorporated into libresolv.a and nslookup; dig now links against
+ * some of nslookup's .o files rather than #including them or maintaining
+ * local copies of them. in some sense, dig belongs in the nslookup
+ * subdirectory rather than up here in "tools", but that's for arc@sgi.com
+ * (owner of nslookup) to decide.
+ *
+ * while merging dig back into the BIND release, i made a number of
+ * structural changes. for one thing, i put all of dig's private
+ * library routines into this file rather than maintaining them in
+ * separate, #included, files. i don't like to #include ".c" files.
+ * i removed all calls to "bcopy", replacing them with structure
+ * assignments. i removed all "extern"'s of standard functions,
+ * replacing them with #include's of standard header files. this
+ * version of dig is probably as portable as the rest of BIND.
+ *
+ * i had to remove the query-time and packet-count statistics since
+ * the current libresolv.a is a lot harder to modify to maintain these
+ * than the 4.8 one (used in the original dig) was. for consolation,
+ * i added a "usage" message with extensive help text.
+ *
+ * to save my (limited, albeit) sanity, i ran "indent" over the source.
+ * i also added the standard berkeley/DEC copyrights, since this file now
+ * contains a fair amount of non-USC code. note that the berkeley and
+ * DEC copyrights do not prohibit redistribution, with or without fee;
+ * we add them only to protect ourselves (you have to claim copyright
+ * in order to disclaim liability and warranty).
+ *
+ * Paul Vixie, Palo Alto, CA, April 1993
+ ****************************************************************************
+
+ /*******************************************************************
+ ** DiG -- Domain Information Groper **
+ ** **
+ ** dig.c - Version 2.1 (7/12/94) ("BIND takeover") **
+ ** **
+ ** Developed by: Steve Hotz & Paul Mockapetris **
+ ** USC Information Sciences Institute (USC-ISI) **
+ ** Marina del Rey, California **
+ ** 1989 **
+ ** **
+ ** dig.c - **
+ ** Version 2.0 (9/1/90) **
+ ** o renamed difftime() difftv() to avoid **
+ ** clash with ANSI C **
+ ** o fixed incorrect # args to strcmp,gettimeofday **
+ ** o incorrect length specified to strncmp **
+ ** o fixed broken -sticky -envsa -envset functions **
+ ** o print options/flags redefined & modified **
+ ** **
+ ** Version 2.0.beta (5/9/90) **
+ ** o output format - helpful to `doc` **
+ ** o minor cleanup **
+ ** o release to beta testers **
+ ** **
+ ** Version 1.1.beta (10/26/89) **
+ ** o hanging zone transer (when REFUSED) fixed **
+ ** o trailing dot added to domain names in RDATA **
+ ** o ISI internal **
+ ** **
+ ** Version 1.0.tmp (8/27/89) **
+ ** o Error in prnttime() fixed **
+ ** o no longer dumps core on large pkts **
+ ** o zone transfer (axfr) added **
+ ** o -x added for inverse queries **
+ ** (i.e. "dig -x 128.9.0.32") **
+ ** o give address of default server **
+ ** o accept broadcast to server @255.255.255.255 **
+ ** **
+ ** Version 1.0 (3/27/89) **
+ ** o original release **
+ ** **
+ ** DiG is Public Domain, and may be used for any purpose as **
+ ** long as this notice is not removed. **
+ **** ****
+ **** NOTE: Version 2.0.beta is not for public distribution ****
+ **** ****
+ *******************************************************************/
+
+
+#define VERSION 22
+#define VSTRING "2.2"
+
+#include <sys/types.h>
+#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 <arpa/inet.h>
+#include <arpa/nameser.h>
+
+#include <netdb.h>
+#include <stdio.h>
+#include <resolv.h>
+#include <ctype.h>
+#include <errno.h>
+#include <string.h>
+#include <setjmp.h>
+#include <fcntl.h>
+
+#include "nslookup/res.h"
+#include "../conf/portability.h"
+
+#define PRF_DEF 0x2ff9
+#define PRF_MIN 0xA930
+#define PRF_ZONE 0x24f9
+
+#ifndef MAXHOSTNAMELEN
+#define MAXHOSTNAMELEN 256
+#endif
+
+int eecode = 0;
+
+FILE *qfp;
+int sockFD;
+
+#define SAVEENV "DiG.env"
+#define DIG_MAXARGS 30
+
+char *defsrv, *srvmsg;
+char defbuf[40] = "default -- ";
+char srvbuf[60];
+
+static void Usage();
+static int SetOption(), printZone(), printRR();
+static struct timeval difftv();
+static void prnttime();
+static int xstrtonum();
+static void res_re_init();
+
+/* stuff for nslookup modules */
+FILE *filePtr;
+jmp_buf env;
+HostInfo *defaultPtr = NULL;
+HostInfo curHostInfo, defaultRec;
+int curHostValid = FALSE;
+int queryType, queryClass;
+extern int StringToClass(), StringToType(); /* subr.c */
+#if defined(BSD) && BSD >= 199006 && !defined(RISCOS_BSD)
+FILE *yyin = NULL;
+void yyrestart(f) { }
+#endif
+char *pager = NULL;
+/* end of nslookup stuff */
+
+ /*
+ ** Take arguments appearing in simple string (from file or command line)
+ ** place in char**.
+ */
+void
+stackarg(y, l)
+ char *l;
+ char **y;
+{
+ int done=0;
+
+ while (!done) {
+ switch (*l) {
+ case '\t':
+ case ' ':
+ l++; break;
+ case '\0':
+ case '\n':
+ done++;
+ *y = NULL;
+ break;
+ default:
+ *y++=l;
+ while (!isspace(*l))
+ l++;
+ if (*l == '\n')
+ done++;
+ *l++ = '\0';
+ *y = NULL;
+ }
+ }
+}
+
+char myhostname[MAXHOSTNAMELEN];
+
+int
+main(argc, argv)
+ int argc;
+ char **argv;
+{
+ struct hostent *hp;
+ short port = htons(NAMESERVER_PORT);
+ /* Wierd stuff for SPARC alignment, hurts nothing else. */
+ union {
+ HEADER header_;
+ u_char packet_[PACKETSZ];
+ } packet_;
+#define packet (packet_.packet_)
+ u_char answer[8*1024];
+ int n;
+ char doping[90];
+ char pingstr[50];
+ char *afile;
+ char *addrc, *addrend, *addrbegin;
+
+ struct timeval exectime, tv1, tv2, start_time, end_time, query_time;
+
+ char *srv;
+ int anyflag = 0;
+ int sticky = 0;
+ int tmp;
+ int qtypeSet;
+ int addrflag = 0;
+ int zone = 0;
+ int bytes_out, bytes_in;
+
+ char cmd[256];
+ char domain[MAXDNAME];
+ char msg[120], *msgptr;
+ char **vtmp;
+ char *args[DIG_MAXARGS];
+ char **ax;
+ char **ay;
+ int once = 1, dofile = 0; /* batch -vs- interactive control */
+ char fileq[100];
+ char *qptr;
+ int fp;
+ int wait=0, delay;
+ int envset=0, envsave=0;
+ struct __res_state res_x, res_t;
+ char *pp;
+
+ res_init();
+ _res.pfcode = PRF_DEF;
+ qtypeSet = 0;
+ bzero(domain, (sizeof domain));
+ gethostname(myhostname, (sizeof myhostname));
+ defsrv = strcat(defbuf, inet_ntoa(_res.nsaddr.sin_addr));
+ res_x = _res;
+
+ /*
+ ** If LOCALDEF in environment, should point to file
+ ** containing local favourite defaults. Also look for file
+ ** DiG.env (i.e. SAVEENV) in local directory.
+ */
+
+ if ((((afile = (char *) getenv("LOCALDEF")) != (char *) NULL) &&
+ ((fp = open(afile, O_RDONLY)) > 0)) ||
+ ((fp = open(SAVEENV, O_RDONLY)) > 0)) {
+ read(fp, (char *)&res_x, (sizeof res_x));
+ close(fp);
+ _res = res_x;
+ }
+ /*
+ ** check for batch-mode DiG; also pre-scan for 'help'
+ */
+ vtmp = argv;
+ ax = args;
+ while (*vtmp != NULL) {
+ if (strcmp(*vtmp, "-h") == 0 ||
+ strcmp(*vtmp, "-help") == 0 ||
+ strcmp(*vtmp, "-usage") == 0 ||
+ strcmp(*vtmp, "help") == 0) {
+ Usage();
+ exit(0);
+ }
+
+ if (strcmp(*vtmp, "-f") == 0) {
+ dofile++; once=0;
+ if ((qfp = fopen(*++vtmp, "r")) == NULL) {
+ fflush(stdout);
+ perror("file open");
+ fflush(stderr);
+ exit(10);
+ }
+ } else {
+ if (ax - args == DIG_MAXARGS) {
+ fprintf(stderr, "dig: too many arguments\n");
+ exit(10);
+ }
+ *ax++ = *vtmp;
+ }
+ vtmp++;
+ }
+
+ _res.id = 1;
+ gettimeofday(&tv1, NULL);
+
+ /*
+ ** Main section: once if cmd-line query
+ ** while !EOF if batch mode
+ */
+ *fileq = '\0';
+ while ((dofile && (fgets(fileq,100,qfp) != NULL)) ||
+ ((!dofile) && (once--)))
+ {
+ if ((*fileq=='\n') || (*fileq=='#') || (*fileq==';')) {
+ continue; /* ignore blank lines & comments */
+ }
+
+/*
+ * "sticky" requests that before current parsing args
+ * return to current "working" environment (X******)
+ */
+ if (sticky) {
+ printf(";; (using sticky settings)\n");
+ _res = res_x;
+ }
+
+/* concat cmd-line and file args */
+ ay = ax;
+ qptr = fileq;
+ stackarg(ay, qptr);
+
+ /* defaults */
+ queryType = T_NS;
+ queryClass = C_IN;
+ zone = 0;
+ *pingstr = 0;
+ srv = NULL;
+
+ sprintf(cmd,"\n; <<>> DiG %s <<>> ",VSTRING);
+ argv = args;
+ argc = ax - args;
+/*
+ * More cmd-line options than anyone should ever have to
+ * deal with ....
+ */
+ while (*(++argv) != NULL && **argv != '\0') {
+ strcat(cmd,*argv); strcat(cmd," ");
+ if (**argv == '@') {
+ srv = (*argv+1);
+ continue;
+ }
+ if (**argv == '%')
+ continue;
+ if (**argv == '+') {
+ SetOption(*argv+1);
+ continue;
+ }
+
+ if (strncmp(*argv,"-nost",5) == 0) {
+ sticky = 0;
+ continue;
+ } else if (strncmp(*argv,"-st",3) == 0) {
+ sticky++;
+ continue;
+ } else if (strncmp(*argv,"-envsa",6) == 0) {
+ envsave++;
+ continue;
+ } else if (strncmp(*argv,"-envse",6) == 0) {
+ envset++;
+ continue;
+ }
+
+ if (**argv == '-') {
+ switch (argv[0][1]) {
+ case 'T': wait = atoi(*++argv);
+ break;
+ case 'c':
+ if ((tmp = atoi(*++argv))
+ || *argv[0]=='0') {
+ queryClass = tmp;
+ } else if (tmp = StringToClass(*argv,
+ 0, NULL)
+ ) {
+ queryClass = tmp;
+ } else {
+ printf(
+ "; invalid class specified\n"
+ );
+ }
+ break;
+ case 't':
+ if ((tmp = atoi(*++argv))
+ || *argv[0]=='0') {
+ queryType = tmp;
+ qtypeSet++;
+ } else if (tmp = StringToType(*argv,
+ 0, NULL)
+ ) {
+ queryType = tmp;
+ qtypeSet++;
+ } else {
+ printf(
+ "; invalid type specified\n"
+ );
+ }
+ break;
+ case 'x':
+ if (!qtypeSet) {
+ queryType = T_ANY;
+ qtypeSet++;
+ }
+ if (!(addrc = *++argv)) {
+ printf(
+ "; no arg for -x?\n"
+ );
+ break;
+ }
+ addrend = addrc + strlen(addrc);
+ if (*addrend == '.')
+ *addrend = '\0';
+ *domain = '\0';
+ while (addrbegin = strrchr(addrc,'.')) {
+ strcat(domain, addrbegin+1);
+ strcat(domain, ".");
+ *addrbegin = '\0';
+ }
+ strcat(domain, addrc);
+ strcat(domain, ".in-addr.arpa.");
+ break;
+ case 'p': port = htons(atoi(*++argv)); break;
+ case 'P':
+ if (argv[0][2] != '\0')
+ strcpy(pingstr,&argv[0][2]);
+ else
+ strcpy(pingstr,"ping -s");
+ break;
+#if defined(__RES) && (__RES >= 19931104)
+ case 'n':
+ _res.ndots = atoi(&argv[0][2]);
+ break;
+#endif /*__RES*/
+ } /* switch - */
+ continue;
+ } /* if '-' */
+
+ if ((tmp = StringToType(*argv, -1, NULL)) != -1) {
+ if ((T_ANY == tmp) && anyflag++) {
+ queryClass = C_ANY;
+ continue;
+ }
+ if (T_AXFR == tmp) {
+ _res.pfcode = PRF_ZONE;
+ zone++;
+ } else {
+ queryType = tmp;
+ qtypeSet++;
+ }
+ } else if ((tmp = StringToClass(*argv, -1, NULL))
+ != -1) {
+ queryClass = tmp;
+ } else {
+ bzero(domain, (sizeof domain));
+ sprintf(domain,"%s",*argv);
+ }
+ } /* while argv remains */
+
+ if (_res.pfcode & 0x80000)
+ printf("; pfcode: %08lx, options: %08lx\n",
+ _res.pfcode, _res.options);
+
+/*
+ * Current env. (after this parse) is to become the
+ * new "working environmnet. Used in conj. with sticky.
+ */
+ if (envset) {
+ res_x = _res;
+ envset = 0;
+ }
+
+/*
+ * Current env. (after this parse) is to become the
+ * new default saved environmnet. Save in user specified
+ * file if exists else is SAVEENV (== "DiG.env").
+ */
+ if (envsave) {
+ afile = (char *) getenv("LOCALDEF");
+ if ((afile &&
+ ((fp = open(afile,
+ O_WRONLY|O_CREAT|O_TRUNC,
+ S_IREAD|S_IWRITE)) > 0))
+ ||
+ ((fp = open(SAVEENV,
+ O_WRONLY|O_CREAT|O_TRUNC,
+ S_IREAD|S_IWRITE)) > 0)) {
+ write(fp, (char *)&_res, (sizeof _res));
+ close(fp);
+ }
+ envsave = 0;
+ }
+
+ if (_res.pfcode & RES_PRF_CMD)
+ printf("%s\n", cmd);
+
+ addrflag = anyflag = 0;
+
+/*
+ * Find address of server to query. If not dot-notation, then
+ * try to resolve domain-name (if so, save and turn off print
+ * options, this domain-query is not the one we want. Restore
+ * user options when done.
+ * Things get a bit wierd since we need to use resolver to be
+ * able to "put the resolver to work".
+ */
+
+ srvbuf[0] = 0;
+ srvmsg = defsrv;
+ if (srv != NULL) {
+ struct in_addr addr;
+
+ if (inet_aton(srv, &addr)) {
+ _res.nscount = 1;
+ _res.nsaddr.sin_addr = addr;
+ srvmsg = strcat(srvbuf, srv);
+ } else {
+ res_t = _res;
+ _res.pfcode = 0;
+ _res.options = RES_DEFAULT;
+ res_init();
+ hp = gethostbyname(srv);
+ _res = res_t;
+ if (hp == NULL
+ || hp->h_addr_list == NULL
+ || *hp->h_addr_list == NULL) {
+ fflush(stdout);
+ fprintf(stderr,
+ "; Bad server: %s -- using default server and timer opts\n",
+ srv);
+ fflush(stderr);
+ srvmsg = defsrv;
+ srv = NULL;
+ } else {
+ u_int32_t **addr;
+
+ _res.nscount = 0;
+ for (addr = (u_int32_t**)hp->h_addr_list;
+ *addr && (_res.nscount < MAXNS);
+ addr++) {
+ _res.nsaddr_list[
+ _res.nscount++
+ ].sin_addr.s_addr = **addr;
+ }
+
+ srvmsg = strcat(srvbuf,srv);
+ strcat(srvbuf, " ");
+ strcat(srvmsg,
+ inet_ntoa(_res.nsaddr.sin_addr)
+ );
+ }
+ }
+ printf("; (%d server%s found)\n",
+ _res.nscount, (_res.nscount==1)?"":"s");
+ _res.id += _res.retry;
+ }
+
+ {
+ int i;
+
+ for (i = 0; i < _res.nscount; i++) {
+ _res.nsaddr_list[i].sin_family = AF_INET;
+ _res.nsaddr_list[i].sin_port = port;
+ }
+ _res.id += _res.retry;
+ }
+
+ if (zone) {
+ int i;
+
+ for (i = 0; i < _res.nscount; i++) {
+ int x = printZone(domain,
+ &_res.nsaddr_list[i]);
+ if (_res.pfcode & RES_PRF_STATS) {
+ struct timeval exectime;
+
+ gettimeofday(&exectime,NULL);
+ printf(";; FROM: %s to SERVER: %s\n",
+ myhostname,
+ inet_ntoa(_res.nsaddr_list[i]
+ .sin_addr));
+ printf(";; WHEN: %s",
+ ctime(&(exectime.tv_sec)));
+ }
+ if (!x)
+ break; /* success */
+ }
+ fflush(stdout);
+ continue;
+ }
+
+ if (*domain && !qtypeSet) {
+ queryType = T_A;
+ qtypeSet++;
+ }
+
+ bytes_out = n = res_mkquery(QUERY, domain,
+ queryClass, queryType,
+ NULL, 0, NULL,
+ packet, sizeof(packet));
+ if (n < 0) {
+ fflush(stderr);
+ printf(";; res_mkquery: buffer too small\n\n");
+ continue;
+ }
+ eecode = 0;
+ if (_res.pfcode & RES_PRF_HEAD1)
+ __fp_resstat(NULL, stdout);
+ (void) gettimeofday(&start_time, NULL);
+ if ((bytes_in = n = res_send(packet, n,
+ answer, sizeof(answer))) < 0) {
+ fflush(stdout);
+ n = 0 - n;
+ msg[0]=0;
+ strcat(msg,";; res_send to server ");
+ strcat(msg,srvmsg);
+ perror(msg);
+ fflush(stderr);
+
+ if (!dofile) {
+ if (eecode)
+ exit(eecode);
+ else
+ exit(9);
+ }
+ }
+ (void) gettimeofday(&end_time, NULL);
+
+ if (_res.pfcode & RES_PRF_STATS) {
+ query_time = difftv(start_time, end_time);
+ printf(";; Total query time: ");
+ prnttime(query_time);
+ putchar('\n');
+ gettimeofday(&exectime,NULL);
+ printf(";; FROM: %s to SERVER: %s\n",
+ myhostname, srvmsg);
+ printf(";; WHEN: %s",
+ ctime(&(exectime.tv_sec)));
+ printf(";; MSG SIZE sent: %d rcvd: %d\n",
+ bytes_out, bytes_in);
+ }
+
+ fflush(stdout);
+/*
+ * Argh ... not particularly elegant. Should put in *real* ping code.
+ * Would necessitate root priviledges for icmp port though!
+ */
+ if (*pingstr) {
+ sprintf(doping,"%s %s 56 3 | tail -3",pingstr,
+ (srv==NULL)?(defsrv+10):srv);
+ system(doping);
+ }
+ putchar('\n');
+
+/*
+ * Fairly crude method and low overhead method of keeping two
+ * batches started at different sites somewhat synchronized.
+ */
+ gettimeofday(&tv2, NULL);
+ delay = (int)(tv2.tv_sec - tv1.tv_sec);
+ if (delay < wait) {
+ sleep(wait - delay);
+ }
+ }
+ return(eecode);
+}
+
+
+static void
+Usage()
+{
+ fputs("\
+usage: dig [@server] [domain] [q-type] [q-class] {q-opt} {d-opt} [%comment]\n\
+where: server,\n\
+ domain are names in the Domain Name System\n\
+ q-class is one of (in,any,...) [default: in]\n\
+ q-type is one of (a,any,mx,ns,soa,hinfo,axfr,txt,...) [default: a]\n\
+", stderr);
+ fputs("\
+ q-opt is one of:\n\
+ -x dot-notation-address (shortcut to in-addr.arpa lookups)\n\
+ -f file (batch mode input file name)\n\
+ -T time (batch mode time delay, per query)\n\
+ -p port (nameserver is on this port) [53]\n\
+ -Pping-string (see man page)\n\
+ -t query-type (synonym for q-type)\n\
+ -c query-class (synonym for q-class)\n\
+ -envsav,-envset (see man page)\n\
+ -[no]stick (see man page)\n\
+", stderr);
+ fputs("\
+ d-opt is of the form ``+keyword=value'' where keyword is one of:\n\
+ [no]debug [no]d2 [no]recurse retry=# time=# [no]ko [no]vc\n\
+ [no]defname [no]search domain=NAME [no]ignore [no]primary\n\
+ [no]aaonly [no]sort [no]cmd [no]stats [no]Header [no]header\n\
+ [no]ttlid [no]cl [no]qr [no]reply [no]ques [no]answer\n\
+ [no]author [no]addit pfdef pfmin pfset=# pfand=# pfor=#\n\
+", stderr);
+ fputs("\
+notes: defname and search don't work; use fully-qualified names.\n\
+", stderr);
+}
+
+
+static int
+SetOption(string)
+ char *string;
+{
+ char option[NAME_LEN];
+ char type[NAME_LEN];
+ char *ptr;
+ int i;
+
+ i = sscanf(string, " %s", option);
+ if (i != 1) {
+ fprintf(stderr, ";*** Invalid option: %s\n", option);
+ return(ERROR);
+ }
+
+ if (strncmp(option, "aa", 2) == 0) { /* aaonly */
+ _res.options |= RES_AAONLY;
+ } else if (strncmp(option, "noaa", 4) == 0) {
+ _res.options &= ~RES_AAONLY;
+ } else if (strncmp(option, "deb", 3) == 0) { /* debug */
+ _res.options |= RES_DEBUG;
+ } else if (strncmp(option, "nodeb", 5) == 0) {
+ _res.options &= ~(RES_DEBUG | RES_DEBUG2);
+ } else if (strncmp(option, "ko", 2) == 0) { /* keepopen */
+ _res.options |= (RES_STAYOPEN | RES_USEVC);
+ } else if (strncmp(option, "noko", 4) == 0) {
+ _res.options &= ~RES_STAYOPEN;
+ } else if (strncmp(option, "d2", 2) == 0) { /* d2 (more debug) */
+ _res.options |= (RES_DEBUG | RES_DEBUG2);
+ } else if (strncmp(option, "nod2", 4) == 0) {
+ _res.options &= ~RES_DEBUG2;
+ } else if (strncmp(option, "def", 3) == 0) { /* defname */
+ _res.options |= RES_DEFNAMES;
+ } else if (strncmp(option, "nodef", 5) == 0) {
+ _res.options &= ~RES_DEFNAMES;
+ } else if (strncmp(option, "sea", 3) == 0) { /* search list */
+ _res.options |= RES_DNSRCH;
+ } else if (strncmp(option, "nosea", 5) == 0) {
+ _res.options &= ~RES_DNSRCH;
+ } else if (strncmp(option, "do", 2) == 0) { /* domain */
+ ptr = strchr(option, '=');
+ if (ptr != NULL) {
+ sscanf(++ptr, "%s", _res.defdname);
+ }
+ } else if (strncmp(option, "ti", 2) == 0) { /* timeout */
+ ptr = strchr(option, '=');
+ if (ptr != NULL) {
+ sscanf(++ptr, "%d", &_res.retrans);
+ }
+
+ } else if (strncmp(option, "ret", 3) == 0) { /* retry */
+ ptr = strchr(option, '=');
+ if (ptr != NULL) {
+ sscanf(++ptr, "%d", &_res.retry);
+ }
+
+ } else if (strncmp(option, "i", 1) == 0) { /* ignore */
+ _res.options |= RES_IGNTC;
+ } else if (strncmp(option, "noi", 3) == 0) {
+ _res.options &= ~RES_IGNTC;
+ } else if (strncmp(option, "pr", 2) == 0) { /* primary */
+ _res.options |= RES_PRIMARY;
+ } else if (strncmp(option, "nop", 3) == 0) {
+ _res.options &= ~RES_PRIMARY;
+ } else if (strncmp(option, "rec", 3) == 0) { /* recurse */
+ _res.options |= RES_RECURSE;
+ } else if (strncmp(option, "norec", 5) == 0) {
+ _res.options &= ~RES_RECURSE;
+ } else if (strncmp(option, "v", 1) == 0) { /* vc */
+ _res.options |= RES_USEVC;
+ } else if (strncmp(option, "nov", 3) == 0) {
+ _res.options &= ~RES_USEVC;
+ } else if (strncmp(option, "pfset", 5) == 0) {
+ ptr = strchr(option, '=');
+ if (ptr != NULL) {
+ _res.pfcode = xstrtonum(++ptr);
+ }
+ } else if (strncmp(option, "pfand", 5) == 0) {
+ ptr = strchr(option, '=');
+ if (ptr != NULL) {
+ _res.pfcode = _res.pfcode & xstrtonum(++ptr);
+ }
+ } else if (strncmp(option, "pfor", 4) == 0) {
+ ptr = strchr(option, '=');
+ if (ptr != NULL) {
+ _res.pfcode |= xstrtonum(++ptr);
+ }
+ } else if (strncmp(option, "pfmin", 5) == 0) {
+ _res.pfcode = PRF_MIN;
+ } else if (strncmp(option, "pfdef", 5) == 0) {
+ _res.pfcode = PRF_DEF;
+ } else if (strncmp(option, "an", 2) == 0) { /* answer section */
+ _res.pfcode |= RES_PRF_ANS;
+ } else if (strncmp(option, "noan", 4) == 0) {
+ _res.pfcode &= ~RES_PRF_ANS;
+ } else if (strncmp(option, "qu", 2) == 0) { /* question section */
+ _res.pfcode |= RES_PRF_QUES;
+ } else if (strncmp(option, "noqu", 4) == 0) {
+ _res.pfcode &= ~RES_PRF_QUES;
+ } else if (strncmp(option, "au", 2) == 0) { /* authority section */
+ _res.pfcode |= RES_PRF_AUTH;
+ } else if (strncmp(option, "noau", 4) == 0) {
+ _res.pfcode &= ~RES_PRF_AUTH;
+ } else if (strncmp(option, "ad", 2) == 0) { /* addition section */
+ _res.pfcode |= RES_PRF_ADD;
+ } else if (strncmp(option, "noad", 4) == 0) {
+ _res.pfcode &= ~RES_PRF_ADD;
+ } else if (strncmp(option, "tt", 2) == 0) { /* TTL & ID */
+ _res.pfcode |= RES_PRF_TTLID;
+ } else if (strncmp(option, "nott", 4) == 0) {
+ _res.pfcode &= ~RES_PRF_TTLID;
+ } else if (strncmp(option, "he", 2) == 0) { /* head flags stats */
+ _res.pfcode |= RES_PRF_HEAD2;
+ } else if (strncmp(option, "nohe", 4) == 0) {
+ _res.pfcode &= ~RES_PRF_HEAD2;
+ } else if (strncmp(option, "H", 1) == 0) { /* header all */
+ _res.pfcode |= RES_PRF_HEADX;
+ } else if (strncmp(option, "noH", 3) == 0) {
+ _res.pfcode &= ~(RES_PRF_HEADX);
+ } else if (strncmp(option, "qr", 2) == 0) { /* query */
+ _res.pfcode |= RES_PRF_QUERY;
+ } else if (strncmp(option, "noqr", 4) == 0) {
+ _res.pfcode &= ~RES_PRF_QUERY;
+ } else if (strncmp(option, "rep", 3) == 0) { /* reply */
+ _res.pfcode |= RES_PRF_REPLY;
+ } else if (strncmp(option, "norep", 5) == 0) {
+ _res.pfcode &= ~RES_PRF_REPLY;
+ } else if (strncmp(option, "cm", 2) == 0) { /* command line */
+ _res.pfcode |= RES_PRF_CMD;
+ } else if (strncmp(option, "nocm", 4) == 0) {
+ _res.pfcode &= ~RES_PRF_CMD;
+ } else if (strncmp(option, "cl", 2) == 0) { /* class mnemonic */
+ _res.pfcode |= RES_PRF_CLASS;
+ } else if (strncmp(option, "nocl", 4) == 0) {
+ _res.pfcode &= ~RES_PRF_CLASS;
+ } else if (strncmp(option, "st", 2) == 0) { /* stats*/
+ _res.pfcode |= RES_PRF_STATS;
+ } else if (strncmp(option, "nost", 4) == 0) {
+ _res.pfcode &= ~RES_PRF_STATS;
+ } else {
+ fprintf(stderr, "; *** Invalid option: %s\n", option);
+ return(ERROR);
+ }
+ res_re_init();
+ return(SUCCESS);
+}
+
+
+
+/*
+ * Force a reinitialization when the domain is changed.
+ */
+static void
+res_re_init()
+{
+ static char localdomain[] = "LOCALDOMAIN";
+ char *buf;
+ long pfcode = _res.pfcode;
+#if defined(__RES) && (__RES >= 19931104)
+ long ndots = _res.ndots;
+#endif
+
+ /* this is ugly but putenv() is more portable than setenv() */
+ buf = malloc((sizeof localdomain) +strlen(_res.defdname) +10/*fuzz*/);
+ sprintf(buf, "%s=%s", localdomain, _res.defdname);
+ putenv(buf); /* keeps the argument, so we won't free it */
+ res_init();
+ _res.pfcode = pfcode;
+#if defined(__RES) && (__RES >= 19931104)
+ _res.ndots = ndots;
+#endif
+}
+
+
+/*
+ * convert char string (decimal, octal, or hex) to integer
+ */
+static int
+xstrtonum(p)
+ char *p;
+{
+ int v = 0;
+ int i;
+ int b = 10;
+ int flag = 0;
+ while (*p != 0) {
+ if (!flag++)
+ if (*p == '0') {
+ b = 8; p++;
+ continue;
+ }
+ if (isupper(*p))
+ *p=tolower(*p);
+ if (*p == 'x') {
+ b = 16; p++;
+ continue;
+ }
+ if (isdigit(*p)) {
+ i = *p - '0';
+ } else if (isxdigit(*p)) {
+ i = *p - 'a' + 10;
+ } else {
+ fprintf(stderr,
+ "; *** Bad char in numeric string..ignored\n");
+ i = -1;
+ }
+ if (i >= b) {
+ fprintf(stderr,
+ "; *** Bad char in numeric string..ignored\n");
+ i = -1;
+ }
+ if (i >= 0)
+ v = v * b + i;
+ p++;
+ }
+ return(v);
+}
+
+/* this code was cloned from nslookup/list.c */
+
+extern char *_res_resultcodes[]; /* res_debug.c */
+
+typedef union {
+ HEADER qb1;
+ u_char qb2[PACKETSZ];
+} querybuf;
+
+static int
+printZone(zone, sin)
+ char *zone;
+ struct sockaddr_in *sin;
+{
+ querybuf buf;
+ HEADER *headerPtr;
+ int msglen;
+ int amtToRead;
+ int numRead;
+ int numAnswers = 0;
+ int numRecords = 0;
+ int result;
+ int soacnt = 0;
+ int sockFD;
+ int count, type, class, rlen, done, n;
+ u_short len;
+ u_char *cp;
+ char dname[2][NAME_LEN];
+ char file[NAME_LEN];
+ static u_char *answer = NULL;
+ static int answerLen = 0;
+ enum {
+ NO_ERRORS,
+ ERR_READING_LEN,
+ ERR_READING_MSG,
+ ERR_PRINTING
+ } error = NO_ERRORS;
+
+ /*
+ * Create a query packet for the requested zone name.
+ */
+ msglen = res_mkquery(QUERY, zone, queryClass, T_AXFR, NULL,
+ 0, 0, buf.qb2, sizeof(buf));
+ if (msglen < 0) {
+ if (_res.options & RES_DEBUG) {
+ fprintf(stderr, ";; res_mkquery failed\n");
+ }
+ return (ERROR);
+ }
+
+ /*
+ * Set up a virtual circuit to the server.
+ */
+ if ((sockFD = socket(sin->sin_family, SOCK_STREAM, 0)) < 0) {
+ int e = errno;
+ perror(";; socket");
+ return(e);
+ }
+ if (connect(sockFD, (struct sockaddr *)sin, sizeof(*sin)) < 0) {
+ int e = errno;
+ perror(";; connect");
+ (void) close(sockFD);
+ sockFD = -1;
+ return e;
+ }
+
+ /*
+ * Send length & message for zone transfer
+ */
+
+ __putshort(msglen, (u_char *)&len);
+
+ if (write(sockFD, (char *)&len, INT16SZ) != INT16SZ ||
+ write(sockFD, (char *)&buf, msglen) != msglen) {
+ int e = errno;
+ perror(";; write");
+ (void) close(sockFD);
+ sockFD = -1;
+ return(e);
+ }
+
+ dname[0][0] = '\0';
+ for (done = 0; !done; NULL) {
+ u_int16_t tmp;
+
+ /*
+ * Read the length of the response.
+ */
+
+ cp = (u_char *) &tmp;
+ amtToRead = INT16SZ;
+ while (amtToRead > 0 && (numRead=read(sockFD, cp, amtToRead)) > 0){
+ cp += numRead;
+ amtToRead -= numRead;
+ }
+ if (numRead <= 0) {
+ error = ERR_READING_LEN;
+ break;
+ }
+
+ if ((len = _getshort((u_char*)&tmp)) == 0) {
+ break; /* nothing left to read */
+ }
+
+ /*
+ * The server sent too much data to fit the existing buffer --
+ * allocate a new one.
+ */
+ if (len > (u_int)answerLen) {
+ if (answerLen != 0) {
+ free(answer);
+ }
+ answerLen = len;
+ answer = (u_char *)Malloc(answerLen);
+ }
+
+ /*
+ * Read the response.
+ */
+
+ amtToRead = len;
+ cp = answer;
+ while (amtToRead > 0 && (numRead=read(sockFD, cp, amtToRead)) > 0) {
+ cp += numRead;
+ amtToRead -= numRead;
+ }
+ if (numRead <= 0) {
+ error = ERR_READING_MSG;
+ break;
+ }
+
+ result = printRR(stdout, answer, cp);
+ if (result != 0) {
+ error = ERR_PRINTING;
+ break;
+ }
+ numRecords += htons(((HEADER *)answer)->ancount);
+ numAnswers++;
+
+ /* Header. */
+ cp = answer + HFIXEDSZ;
+ /* Question. */
+ for (count = ntohs(((HEADER *)answer)->qdcount);
+ count > 0;
+ count--)
+ cp += dn_skipname(cp, answer + len) + QFIXEDSZ;
+ /* Answer. */
+ for (count = ntohs(((HEADER *)answer)->ancount);
+ count > 0;
+ count--) {
+ n = dn_expand(answer, answer + len, cp,
+ dname[soacnt], sizeof dname[0]);
+ if (n < 0) {
+ error = ERR_PRINTING;
+ done++;
+ break;
+ }
+ cp += n;
+ GETSHORT(type, cp);
+ GETSHORT(class, cp);
+ cp += INT32SZ; /* ttl */
+ GETSHORT(rlen, cp);
+ cp += rlen;
+ if (type == T_SOA && soacnt++ &&
+ !strcasecmp(dname[0], dname[1])) {
+ done++;
+ break;
+ }
+ }
+ }
+
+ printf(";; Received %d answer%s (%d record%s).\n",
+ numAnswers, (numAnswers != 1) ? "s" : "",
+ numRecords, (numRecords != 1) ? "s" : "");
+
+ (void) close(sockFD);
+ sockFD = -1;
+
+ switch (error) {
+ case NO_ERRORS:
+ return (0);
+
+ case ERR_READING_LEN:
+ return(EMSGSIZE);
+
+ case ERR_PRINTING:
+ return(result);
+
+ case ERR_READING_MSG:
+ return(EMSGSIZE);
+
+ default:
+ return(EFAULT);
+ }
+}
+
+static int
+printRR(file, msg, eom)
+ FILE *file;
+ u_char *msg, *eom;
+{
+ register u_char *cp;
+ HEADER *headerPtr;
+ int type, class, dlen, nameLen;
+ u_int32_t ttl;
+ int n, pref;
+ struct in_addr inaddr;
+ char name[NAME_LEN];
+ char name2[NAME_LEN];
+ Boolean stripped;
+
+ /*
+ * Read the header fields.
+ */
+ headerPtr = (HEADER *)msg;
+ cp = msg + HFIXEDSZ;
+ if (headerPtr->rcode != NOERROR) {
+ return(headerPtr->rcode);
+ }
+
+ /*
+ * We are looking for info from answer resource records.
+ * If there aren't any, return with an error. We assume
+ * there aren't any question records.
+ */
+
+ if (ntohs(headerPtr->ancount) == 0) {
+ return(NO_INFO);
+ }
+ for (n = ntohs(headerPtr->qdcount); n > 0; n--) {
+ nameLen = dn_skipname(cp, eom);
+ if (nameLen < 0)
+ return (ERROR);
+ cp += nameLen + QFIXEDSZ;
+ }
+#ifdef PROTOCOLDEBUG
+ printf(";;; (message of %d octets has %d answers)\n",
+ eom - msg, ntohs(headerPtr->ancount));
+#endif
+ for (n = ntohs(headerPtr->ancount); n > 0; n--)
+ cp = (u_char*) p_rr(cp, msg, stdout);
+ return(SUCCESS);
+}
+
+static struct timeval
+difftv(a, b)
+ struct timeval a, b;
+{
+ static struct timeval diff;
+
+ diff.tv_sec = b.tv_sec - a.tv_sec;
+ if ((diff.tv_usec = b.tv_usec - a.tv_usec) < 0) {
+ diff.tv_sec--;
+ diff.tv_usec += 1000000;
+ }
+ return(diff);
+}
+
+static void
+prnttime(t)
+ struct timeval t;
+{
+ printf("%lu msec", (u_long)(t.tv_sec * 1000 + (t.tv_usec / 1000)));
+}
diff --git a/contrib/bind/tools/dnsquery.c b/contrib/bind/tools/dnsquery.c
new file mode 100644
index 0000000..48ef9f1
--- /dev/null
+++ b/contrib/bind/tools/dnsquery.c
@@ -0,0 +1,239 @@
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <netdb.h>
+#include <resolv.h>
+#include <errno.h>
+
+#include "../conf/portability.h"
+
+extern int errno;
+extern int h_errno;
+extern char *h_errlist[];
+
+main(argc, argv)
+int argc;
+char *argv[];
+{
+ char name[MAXDNAME];
+ u_char answer[8*1024];
+ register int c, i = 0;
+ unsigned long ul;
+ int nameservers = 0, class, type, len;
+ struct in_addr q_nsaddr[MAXNS];
+ struct hostent *q_nsname;
+ extern int optind, opterr;
+ extern char *optarg;
+ HEADER *hp;
+ int stream = 0, debug = 0;
+
+ /* set defaults */
+ len = MAXDNAME;
+ gethostname(name, len);
+ class = C_IN;
+ type = T_ANY;
+
+ /* if no args, exit */
+ if (argc == 1) {
+ fprintf(stderr, "Usage: %s [-h] host [-n ns] [-t type] [-c class] [-r retry] [-p period] [-s] [-v] [-d] [-a]\n", argv[0]);
+ exit(-1);
+ }
+
+ /* handle args */
+ while ((c = getopt(argc, argv, "c:dh:n:p:r:st:u:v")) != EOF) {
+ switch (c) {
+
+ case 'r' : _res.retry = atoi(optarg);
+ break;
+
+ case 'p' : _res.retrans = atoi(optarg);
+ break;
+
+ case 'h' : strcpy(name, optarg);
+ break;
+
+ case 'c' : if (!strcasecmp(optarg, "IN"))
+ class = C_IN;
+ else if (!strcasecmp(optarg, "HS"))
+ class = C_HS;
+ else if (!strcasecmp(optarg, "CHAOS"))
+ class = C_CHAOS;
+ else if (!strcasecmp(optarg, "ANY"))
+ class = C_ANY;
+ else {
+ class = T_ANY;
+ fprintf(stderr, "optarg=%s\n", optarg);
+ }
+ break;
+
+ case 't' : if (!strcasecmp(optarg, "A"))
+ type = T_A;
+ else if (!strcasecmp(optarg, "NS"))
+ type = T_NS;
+ else if (!strcasecmp(optarg, "MD"))
+ type = T_MD;
+ else if (!strcasecmp(optarg, "MF"))
+ type = T_MF;
+ else if (!strcasecmp(optarg, "CNAME"))
+ type = T_CNAME;
+ else if (!strcasecmp(optarg, "SOA"))
+ type = T_SOA;
+ else if (!strcasecmp(optarg, "MB"))
+ type = T_MB;
+ else if (!strcasecmp(optarg, "MG"))
+ type = T_MG;
+ else if (!strcasecmp(optarg, "MR"))
+ type = T_MR;
+ else if (!strcasecmp(optarg, "NULL"))
+ type = T_NULL;
+ else if (!strcasecmp(optarg, "WKS"))
+ type = T_WKS;
+ else if (!strcasecmp(optarg, "PTR"))
+ type = T_PTR;
+ else if (!strcasecmp(optarg, "HINFO"))
+ type = T_HINFO;
+ else if (!strcasecmp(optarg, "MINFO"))
+ type = T_MINFO;
+ else if (!strcasecmp(optarg, "MX"))
+ type = T_MX;
+ else if (!strcasecmp(optarg, "TXT"))
+ type = T_TXT;
+ else if (!strcasecmp(optarg, "RP"))
+ type = T_RP;
+ else if (!strcasecmp(optarg, "AFSDB"))
+ type = T_AFSDB;
+ else if (!strcasecmp(optarg, "ANY"))
+ type = T_ANY;
+ else if (!strcasecmp(optarg, "X25"))
+ type = T_X25;
+ else if (!strcasecmp(optarg, "ISDN"))
+ type = T_ISDN;
+ else if (!strcasecmp(optarg, "RT"))
+ type = T_RT;
+ else if (!strcasecmp(optarg, "NSAP"))
+ type = T_NSAP;
+ else if (!strcasecmp(optarg, "SIG"))
+ type = T_SIG;
+ else if (!strcasecmp(optarg, "KEY"))
+ type = T_KEY;
+ else if (!strcasecmp(optarg, "PX"))
+ type = T_PX;
+ else if (!strcasecmp(optarg, "GPOS"))
+ type = T_GPOS;
+ else if (!strcasecmp(optarg, "AAAA"))
+ type = T_AAAA;
+ else if (!strcasecmp(optarg, "LOC"))
+ type = T_LOC;
+ else {
+ fprintf(stderr, "Bad type (%s)\n", optarg);
+ exit(-1);
+ }
+ break;
+
+ case 'd' : debug++;
+ break;
+
+ case 's' :
+ case 'v' : stream++;
+ break;
+
+ case 'n' :
+ /*
+ * If we set some nameservers here without
+ * using gethostbyname() first, then they will
+ * get overwritten when we do the first query.
+ * So, we must init the resolver before any
+ * of this.
+ */
+ if (!(_res.options & RES_INIT))
+ if (res_init() == -1) {
+ fprintf(stderr,
+ "res_init() failed\n");
+ exit(-1);
+ }
+ if (nameservers >= MAXNS) break;
+ (void) inet_aton(optarg,
+ &q_nsaddr[nameservers]);
+ if (!inet_aton(optarg, &ul)) {
+ q_nsname = gethostbyname(optarg);
+ if (q_nsname == 0) {
+ fprintf(stderr,
+ "Bad nameserver (%s)\n",
+ optarg);
+ exit(-1);
+ }
+ bcopy((char *) q_nsname->h_addr,
+ (char *) &q_nsaddr[nameservers],
+ INADDRSZ);
+ }
+ else
+ q_nsaddr[nameservers].s_addr = ul;
+ nameservers++;
+ break;
+
+ default : fprintf(stderr,
+ "\tUsage: %s [-n ns] [-h host] [-t type] [-c class] [-r retry] [-p period] [-s] [-v] [-d] [-a]\n", argv[0]);
+ exit(-1);
+ }
+ }
+ if (optind < argc)
+ strcpy(name, argv[optind]);
+
+ len = sizeof(answer);
+
+ /*
+ * set these here so they aren't set for a possible call to
+ * gethostbyname above
+ */
+ if (debug || stream) {
+ if (!(_res.options & RES_INIT))
+ if (res_init() == -1) {
+ fprintf(stderr, "res_init() failed\n");
+ exit(-1);
+ }
+ if (debug)
+ _res.options |= RES_DEBUG;
+ if (stream)
+ _res.options |= RES_USEVC;
+ }
+
+ /* if the -n flag was used, add them to the resolver's list */
+ if (nameservers != 0) {
+ _res.nscount = nameservers;
+ for (i = nameservers - 1; i >= 0; i--) {
+ _res.nsaddr_list[i].sin_addr.s_addr = q_nsaddr[i].s_addr;
+ _res.nsaddr_list[i].sin_family = AF_INET;
+ _res.nsaddr_list[i].sin_port = htons(NAMESERVER_PORT);
+ }
+ }
+
+ /*
+ * if the -h arg is fully-qualified, use res_query() since
+ * using res_search() will lead to use of res_querydomain()
+ * which will strip the trailing dot
+ */
+ if (name[strlen(name) - 1] == '.') {
+ if (res_query(name, class, type, answer, len) < 0) {
+ hp = (HEADER *) answer;
+ if ((hp->rcode == 0) && (hp->ancount > 0))
+ __p_query(answer);
+ else
+ fprintf(stderr, "Query failed (h_errno = %d) : %s\n",
+ h_errno, h_errlist[h_errno]);
+ exit(-1);
+ }
+ }
+ else if (res_search(name, class, type, answer, len) < 0) {
+ hp = (HEADER *) answer;
+ if ((hp->rcode == 0) && (hp->ancount > 0))
+ __p_query(answer);
+ else
+ fprintf(stderr, "Query failed (h_errno = %d) : %s\n",
+ h_errno, h_errlist[h_errno]);
+ exit(-1);
+ }
+ __p_query(answer);
+ exit(0);
+}
diff --git a/contrib/bind/tools/host.c b/contrib/bind/tools/host.c
new file mode 100644
index 0000000..b4abb22
--- /dev/null
+++ b/contrib/bind/tools/host.c
@@ -0,0 +1,1471 @@
+/*
+ * ++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 */
+
+/*
+ * Actually, this program is from Rutgers University, however it is
+ * based on nslookup and other pieces of named tools, so it needs
+ * that copyright notice.
+ */
+
+#ifndef lint
+static char rcsid[] = "$Id: host.c,v 8.8 1995/12/06 20:34:52 vixie Exp $";
+#endif /* not lint */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+
+#include <stdio.h>
+#include <netdb.h>
+#include <resolv.h>
+#include <ctype.h>
+
+#include "../conf/portability.h"
+
+extern int h_errno;
+
+#define NUMMX 50
+
+#define SUCCESS 0
+#define TIME_OUT -1
+#define NO_INFO -2
+#define ERROR -3
+#define NONAUTH -4
+
+#define NAME_LEN 256
+
+#ifndef T_TXT
+#define T_TXT 16
+#endif
+#ifndef NO_DATA
+#define NO_DATA NO_ADDRESS
+#endif
+#ifndef C_HS
+#define C_HS 4
+#endif
+
+int sockFD;
+FILE *filePtr;
+char *DecodeError();
+
+static struct __res_state orig;
+extern struct __res_state _res;
+static char *cname = NULL;
+int getclass = C_IN;
+int gettype;
+int verbose = 0;
+int list = 0;
+int server_specified = 0;
+
+u_char *pr_cdname();
+char *pr_class(), *pr_rr(), *pr_type();
+extern char *hostalias();
+
+main(c, v)
+ int c;
+ char **v;
+{
+ unsigned addr;
+ register struct hostent *hp;
+ register char *s;
+ register inverse = 0;
+ register waitmode = 0;
+ char *oldcname;
+ int ncnames;
+
+ res_init();
+ _res.retrans = 5;
+
+ if (c < 2) {
+ fprintf(stderr, "Usage: host [-w] [-v] [-r] [-d] [-t querytype] [-c class] [-a] host [server]\n -w to wait forever until reply\n -v for verbose output\n -r to disable recursive processing\n -d to turn on debugging output\n -t querytype to look for a specific type of information\n -c class to look for non-Internet data\n -a is equivalent to '-v -t *'\n");
+ exit(1);
+ }
+ while (c > 2 && v[1][0] == '-') {
+ if (strcmp (v[1], "-w") == 0) {
+ _res.retry = 1;
+ _res.retrans = 15;
+ waitmode = 1;
+ v++;
+ c--;
+ }
+ else if (strcmp (v[1], "-r") == 0) {
+ _res.options &= ~RES_RECURSE;
+ v++;
+ c--;
+ }
+ else if (strcmp (v[1], "-d") == 0) {
+ _res.options |= RES_DEBUG;
+ v++;
+ c--;
+ }
+ else if (strcmp (v[1], "-v") == 0) {
+ verbose = 1;
+ v++;
+ c--;
+ }
+ else if (strcmp (v[1], "-l") == 0) {
+ list = 1;
+ v++;
+ c--;
+ }
+ else if (strncmp (v[1], "-t", 2) == 0) {
+ v++;
+ c--;
+ gettype = parsetype(v[1]);
+ v++;
+ c--;
+ }
+ else if (strncmp (v[1], "-c", 2) == 0) {
+ v++;
+ c--;
+ getclass = parseclass(v[1]);
+ v++;
+ c--;
+ }
+ else if (strcmp (v[1], "-a") == 0) {
+ verbose = 1;
+ gettype = T_ANY;
+ v++;
+ c--;
+ }
+ }
+ if (c > 2) {
+ s = v[2];
+ server_specified++;
+
+ if (!inet_aton(s, (struct in_addr *)&addr)) {
+ hp = gethostbyname(s);
+ if (hp == NULL) {
+ fprintf(stderr,"Error in looking up server name:\n");
+ hperror(h_errno);
+ exit(1);
+ }
+ _res.nsaddr.sin_addr = *(struct in_addr *)hp->h_addr;
+ printf("Using domain server:\n");
+ printanswer(hp);
+ }
+ else {
+ _res.nsaddr.sin_family = AF_INET;
+ _res.nsaddr.sin_addr.s_addr = addr;
+ _res.nsaddr.sin_port = htons(NAMESERVER_PORT);
+ printf("Using domain server %s:\n",
+ inet_ntoa(_res.nsaddr.sin_addr));
+ }
+ _res.nscount = 1;
+ _res.retry = 2;
+ }
+ if (strcmp (v[1], ".") == 0 ||
+ !inet_aton(v[1], (struct in_addr *)&addr))
+ addr = -1;
+ hp = NULL;
+ h_errno = TRY_AGAIN;
+/*
+ * we handle default domains ourselves, thank you
+ */
+ _res.options &= ~RES_DEFNAMES;
+
+ if (list)
+ exit(ListHosts(v[1], gettype ? gettype : T_A));
+ oldcname = NULL;
+ ncnames = 5;
+ while (hp == NULL && h_errno == TRY_AGAIN) {
+ if (addr == -1) {
+ cname = NULL;
+ if (oldcname == NULL)
+ hp = (struct hostent *)gethostinfo(v[1]);
+ else
+ hp = (struct hostent *)gethostinfo(oldcname);
+ if (cname) {
+ if (ncnames-- == 0) {
+ printf("Too many cnames. Possible loop.\n");
+ exit(1);
+ }
+ strcat(cname, ".");
+ oldcname = cname;
+ hp = NULL;
+ h_errno = TRY_AGAIN;
+ continue;
+ }
+ }
+ else {
+ hp = gethostbyaddr((char*)&addr, 4, AF_INET);
+ if (hp)
+ printanswer(hp);
+ }
+ if (!waitmode)
+ break;
+ }
+
+ if (hp == NULL) {
+ hperror(h_errno);
+ exit(1);
+ }
+
+ exit(0);
+
+}
+
+parsetype(s)
+ char *s;
+{
+if (strcmp(s,"a") == 0)
+ return(T_A);
+if (strcmp(s,"ns") == 0)
+ return(T_NS);
+if (strcmp(s,"md") == 0)
+ return(T_MD);
+if (strcmp(s,"mf") == 0)
+ return(T_MF);
+if (strcmp(s,"cname") == 0)
+ return(T_CNAME);
+if (strcmp(s,"soa") == 0)
+ return(T_SOA);
+if (strcmp(s,"mb") == 0)
+ return(T_MB);
+if (strcmp(s,"mg") == 0)
+ return(T_MG);
+if (strcmp(s,"mr") == 0)
+ return(T_MR);
+if (strcmp(s,"null") == 0)
+ return(T_NULL);
+if (strcmp(s,"wks") == 0)
+ return(T_WKS);
+if (strcmp(s,"ptr") == 0)
+ return(T_PTR);
+if (strcmp(s,"hinfo") == 0)
+ return(T_HINFO);
+if (strcmp(s,"minfo") == 0)
+ return(T_MINFO);
+if (strcmp(s,"mx") == 0)
+ return(T_MX);
+if (strcmp(s,"txt") == 0)
+ return(T_TXT);
+if (strcmp(s,"rp") == 0)
+ return(T_RP);
+if (strcmp(s,"afsdb") == 0)
+ return(T_AFSDB);
+if (strcmp(s,"x25") == 0)
+ return(T_X25);
+if (strcmp(s,"isdn") == 0)
+ return(T_ISDN);
+if (strcmp(s,"rt") == 0)
+ return(T_RT);
+if (strcmp(s,"uinfo") == 0)
+ return(T_UINFO);
+if (strcmp(s,"uid") == 0)
+ return(T_UID);
+if (strcmp(s,"gid") == 0)
+ return(T_GID);
+if (strcmp(s,"unspec") == 0)
+ return(T_UNSPEC);
+if (strcmp(s,"any") == 0)
+ return(T_ANY);
+if (strcmp(s,"*") == 0)
+ return(T_ANY);
+if (atoi(s))
+ return(atoi(s));
+fprintf(stderr, "Invalid query type: %s\n", s);
+exit(2);
+}
+
+parseclass(s)
+ char *s;
+{
+if (strcmp(s,"in") == 0)
+ return(C_IN);
+if (strcmp(s,"hs") == 0)
+ return(C_HS);
+if (strcmp(s,"any") == 0)
+ return(C_ANY);
+if (atoi(s))
+ return(atoi(s));
+fprintf(stderr, "Invalid query class: %s\n", s);
+exit(2);
+}
+
+printanswer(hp)
+ register struct hostent *hp;
+{
+ register char **cp;
+ register long **hptr;
+
+ printf("Name: %s\n", hp->h_name);
+ printf("Address:");
+ for (hptr = (long **)hp->h_addr_list; *hptr; hptr++)
+ printf(" %s", inet_ntoa(*(struct in_addr *)*hptr));
+ printf("\nAliases:");
+ for (cp = hp->h_aliases; cp && *cp && **cp; cp++)
+ printf(" %s", *cp);
+ printf("\n\n");
+}
+
+hperror(errnum)
+int errnum;
+{
+switch(errnum) {
+ case HOST_NOT_FOUND:
+ fprintf(stderr,"Host not found.\n");
+ break;
+ case TRY_AGAIN:
+ fprintf(stderr,"Host not found, try again.\n");
+ break;
+ case NO_RECOVERY:
+ fprintf(stderr,"No recovery, Host not found.\n");
+ break;
+ case NO_ADDRESS:
+ fprintf(stderr,"There is an entry for this host, but it doesn't have ");
+ switch (gettype) {
+ case T_A:
+ fprintf(stderr,"an Internet address.\n");
+ break;
+ case T_NS:
+ fprintf(stderr,"a Name Server.\n");
+ break;
+ case T_MD:
+ fprintf(stderr,"a Mail Destination.\n");
+ break;
+ case T_MF:
+ fprintf(stderr,"a Mail Forwarder.\n");
+ break;
+ case T_CNAME:
+ fprintf(stderr,"a Canonical Name.\n");
+ break;
+ case T_SOA:
+ fprintf(stderr,"a Start of Authority record.\n");
+ break;
+ case T_MB:
+ fprintf(stderr,"a Mailbox Domain Name.\n");
+ break;
+ case T_MG:
+ fprintf(stderr,"a Mail Group Member.\n");
+ break;
+ case T_MR:
+ fprintf(stderr,"a Mail Rename Name.\n");
+ break;
+ case T_NULL:
+ fprintf(stderr,"a Null Resource record.\n");
+ break;
+ case T_WKS:
+ fprintf(stderr,"any Well Known Service information.\n");
+ break;
+ case T_PTR:
+ fprintf(stderr,"a Pointer record.\n");
+ break;
+ case T_HINFO:
+ fprintf(stderr,"any Host Information.\n");
+ break;
+ case T_MINFO:
+ fprintf(stderr,"any Mailbox Information.\n");
+ break;
+ case T_MX:
+ fprintf(stderr,"a Mail Exchanger record.\n");
+ break;
+ case T_TXT:
+ fprintf(stderr,"a Text record.\n");
+ break;
+ case T_RP:
+ fprintf(stderr,"a Responsible Person.\n");
+ break;
+ case T_UINFO:
+ fprintf(stderr,"any User Information.\n");
+ break;
+ case T_UID:
+ fprintf(stderr,"a User ID.\n");
+ break;
+ case T_GID:
+ fprintf(stderr,"a Group ID.\n");
+ break;
+ case T_UNSPEC:
+ fprintf(stderr,"any Unspecified Format data.\n");
+ break;
+ default:
+ fprintf(stderr,"the information you requested.\n");
+ break;
+ }
+ break;
+ }
+}
+
+
+typedef union {
+ HEADER qb1;
+ u_char qb2[PACKETSZ];
+} querybuf;
+
+static u_char hostbuf[BUFSIZ+1];
+
+gethostinfo(name)
+ char *name;
+{
+ register char *cp, **domain;
+ u_int n;
+ int hp;
+ int nDomain;
+ int asis = 0;
+
+ if (strcmp(name, ".") == 0)
+ return(getdomaininfo(name, NULL));
+ for (cp = name, n = 0; *cp; cp++)
+ if (*cp == '.')
+ n++;
+ if (n && cp[-1] == '.') {
+ if (cp[-1] == '.')
+ cp[-1] = 0;
+ hp = getdomaininfo(name, (char *)NULL);
+ if (cp[-1] == 0)
+ cp[-1] = '.';
+ return (hp);
+ }
+ if (n == 0 && (cp = hostalias(name))) {
+ if (verbose)
+ printf("Aliased to \"%s\"\n", cp);
+ _res.options |= RES_DEFNAMES;
+ return (getdomaininfo(cp, (char *)NULL));
+ }
+ if (n >= _res.ndots) {
+ asis = 1;
+ if (verbose)
+ printf("Trying null domain\n");
+ if(hp = getdomaininfo(name, (char*)NULL))
+ return(hp);
+ }
+#ifdef MAXDS
+ for (nDomain = 0;
+ _res.defdname_list[nDomain][0] != 0;
+ nDomain++) {
+ for (domain = _res.dnsrch_list[nDomain]; *domain; domain++) {
+ if (verbose)
+ printf("Trying domain \"%s\"\n", *domain);
+ hp = getdomaininfo(name, *domain);
+ if (hp)
+ return (hp);
+ }
+ }
+#else
+ for (domain = _res.dnsrch; *domain; domain++) {
+ if (verbose)
+ printf("Trying domain \"%s\"\n", *domain);
+ hp = getdomaininfo(name, *domain);
+ if (hp)
+ return (hp);
+ }
+#endif
+ if (h_errno != HOST_NOT_FOUND ||
+ (_res.options & RES_DNSRCH) == 0)
+ return (0);
+ if (!asis)
+ return (0);
+ if (verbose)
+ printf("Trying null domain\n");
+ return (getdomaininfo(name, (char *)NULL));
+}
+
+getdomaininfo(name, domain)
+ char *name, *domain;
+{
+ int val1, val2;
+
+ if (gettype)
+ return getinfo(name, domain, gettype);
+ else {
+ val1 = getinfo(name, domain, T_A);
+ if (cname || verbose)
+ return val1;
+ val2 = getinfo(name, domain, T_MX);
+ return val1 || val2;
+ }
+}
+
+getinfo(name, domain, type)
+ char *name, *domain;
+ int type;
+{
+
+ HEADER *hp;
+ char *eom, *bp, *cp;
+ querybuf buf, answer;
+ int n, n1, i, j, nmx, ancount, nscount, arcount, qdcount, buflen;
+ u_short pref, class;
+ char host[2*MAXDNAME+2];
+
+ if (domain == NULL)
+ (void)sprintf(host, "%.*s", MAXDNAME, name);
+ else
+ (void)sprintf(host, "%.*s.%.*s", MAXDNAME, name, MAXDNAME, domain);
+
+ n = res_mkquery(QUERY, host, getclass, type, NULL, 0, NULL,
+ buf.qb2, sizeof(buf));
+ if (n < 0) {
+ if (_res.options & RES_DEBUG)
+ printf("res_mkquery failed\n");
+ h_errno = NO_RECOVERY;
+ return(0);
+ }
+ n = res_send(buf.qb2, n, answer.qb2, sizeof answer);
+ if (n < 0) {
+ if (_res.options & RES_DEBUG)
+ printf("res_send failed\n");
+ h_errno = TRY_AGAIN;
+ return (0);
+ }
+ eom = (char *)&answer + n;
+ return(printinfo(&answer, eom, T_ANY, 0));
+ }
+
+printinfo(answer, eom, filter, isls)
+ querybuf *answer;
+ u_char *eom;
+ int filter;
+ int isls;
+{
+ HEADER *hp;
+ u_char *bp, *cp;
+ int n, n1, i, j, nmx, ancount, nscount, arcount, qdcount, buflen;
+ u_short pref, class;
+
+ /*
+ * find first satisfactory answer
+ */
+ hp = (HEADER *) answer;
+ ancount = ntohs(hp->ancount);
+ qdcount = ntohs(hp->qdcount);
+ nscount = ntohs(hp->nscount);
+ arcount = ntohs(hp->arcount);
+ if (_res.options & RES_DEBUG || (verbose && isls == 0))
+ printf("rcode = %d (%s), ancount=%d\n",
+ hp->rcode, DecodeError(hp->rcode), ancount);
+ if (hp->rcode != NOERROR || (ancount+nscount+arcount) == 0) {
+ switch (hp->rcode) {
+ case NXDOMAIN:
+ h_errno = HOST_NOT_FOUND;
+ return(0);
+ case SERVFAIL:
+ h_errno = TRY_AGAIN;
+ return(0);
+#ifdef OLDJEEVES
+ /*
+ * Jeeves (TOPS-20 server) still does not
+ * support MX records. For the time being,
+ * we must accept FORMERRs as the same as
+ * NOERROR.
+ */
+ case FORMERR:
+#endif /*OLDJEEVES*/
+ case NOERROR:
+/* TpB - set a return error for this case. NO_DATA */
+ h_errno = NO_DATA;
+ return(0); /* was 1,but now indicates exception */
+#ifndef OLDJEEVES
+ case FORMERR:
+#endif /*OLDJEEVES*/
+ case NOTIMP:
+ case REFUSED:
+ h_errno = NO_RECOVERY;
+ return(0);
+ }
+ return (0);
+ }
+ bp = hostbuf;
+ nmx = 0;
+ buflen = sizeof(hostbuf);
+ cp = (u_char *)answer + HFIXEDSZ;
+ if (qdcount) {
+ cp += dn_skipname(cp, eom) + QFIXEDSZ;
+ while (--qdcount > 0)
+ cp += dn_skipname(cp, eom) + QFIXEDSZ;
+ }
+ if (ancount) {
+ if (!hp->aa)
+ if (verbose && isls == 0)
+ printf("The following answer is not authoritative:\n");
+ while (--ancount >= 0 && cp && cp < eom) {
+ cp = (u_char *)pr_rr(cp, answer, stdout, filter);
+/*
+ * When we ask for address and there is a CNAME, it seems to return
+ * both the CNAME and the address. Since we trace down the CNAME
+ * chain ourselves, we don't really want to print the address at
+ * this point.
+ */
+ if (cname && ! verbose)
+ return (1);
+ }
+ }
+ if (! verbose)
+ return (1);
+ if (nscount) {
+ printf("For authoritative answers, see:\n");
+ while (--nscount >= 0 && cp && cp < eom) {
+ cp = (u_char *)pr_rr(cp, answer, stdout, filter);
+ }
+ }
+ if (arcount) {
+ printf("Additional information:\n");
+ while (--arcount >= 0 && cp && cp < eom) {
+ cp = (u_char *)pr_rr(cp, answer, stdout, filter);
+ }
+ }
+ return(1);
+ }
+
+static char cnamebuf[MAXDNAME];
+
+/*
+ * Print resource record fields in human readable form.
+ */
+char *
+pr_rr(cp, msg, file, filter)
+ u_char *cp, *msg;
+ FILE *file;
+ int filter;
+{
+ int type, class, dlen, n, c, proto, ttl;
+ struct in_addr inaddr;
+ u_char *cp1;
+ struct protoent *protop;
+ struct servent *servp;
+ char punc;
+ int doprint;
+ char name[MAXDNAME];
+
+ if ((cp = (u_char *)pr_cdname(cp, msg, name, sizeof(name))) == NULL)
+ return (NULL); /* compression error */
+
+ type = _getshort(cp);
+ cp += INT16SZ;
+
+ class = _getshort(cp);
+ cp += INT16SZ;
+
+ ttl = _getlong(cp);
+ cp += INT32SZ;
+
+ if (filter == type || filter == T_ANY ||
+ (filter == T_A && (type == T_PTR || type == T_NS)))
+ doprint = 1;
+ else
+ doprint = 0;
+
+ if (doprint)
+ if (verbose)
+ fprintf(file,"%s\t%d%s\t%s",
+ name, ttl, pr_class(class), pr_type(type));
+ else
+ fprintf(file,"%s%s %s",name, pr_class(class), pr_type(type));
+ if (verbose)
+ punc = '\t';
+ else
+ punc = ' ';
+
+ dlen = _getshort(cp);
+ cp += INT16SZ;
+ cp1 = cp;
+ /*
+ * Print type specific data, if appropriate
+ */
+ switch (type) {
+ case T_A:
+ switch (class) {
+ case C_IN:
+ bcopy(cp, (char *)&inaddr, INADDRSZ);
+ if (dlen == 4) {
+ if (doprint)
+ fprintf(file,"%c%s", punc,
+ inet_ntoa(inaddr));
+ cp += dlen;
+ } else if (dlen == 7) {
+ if (doprint) {
+ fprintf(file,"%c%s", punc,
+ inet_ntoa(inaddr));
+ fprintf(file,", protocol = %d", cp[4]);
+ fprintf(file,", port = %d",
+ (cp[5] << 8) + cp[6]);
+ }
+ cp += dlen;
+ }
+ break;
+ }
+ break;
+ case T_CNAME:
+ if (dn_expand(msg, msg + 512, cp, cnamebuf,
+ sizeof(cnamebuf)) >= 0)
+ cname = cnamebuf;
+ case T_MB:
+#ifdef OLDRR
+ case T_MD:
+ case T_MF:
+#endif /* OLDRR */
+ case T_MG:
+ case T_MR:
+ case T_NS:
+ case T_PTR:
+ cp = (u_char *)pr_cdname(cp, msg, name, sizeof(name));
+ if (doprint)
+ fprintf(file,"%c%s",punc, name);
+ break;
+
+ case T_HINFO:
+ case T_ISDN:
+ {
+ u_char *cp2 = cp + dlen;
+ if (n = *cp++) {
+ if (doprint)
+ fprintf(file,"%c%.*s", punc, n, cp);
+ cp += n;
+ }
+ if ((cp < cp2) && (n = *cp++)) {
+ if (doprint)
+ fprintf(file,"%c%.*s", punc, n, cp);
+ cp += n;
+ } else if (type == T_HINFO)
+ if (doprint)
+ fprintf(file,"\n; *** Warning *** OS-type missing");
+ }
+ break;
+
+ case T_SOA:
+ cp = (u_char *)pr_cdname(cp, msg, name, sizeof(name));
+ if (doprint)
+ fprintf(file,"\t%s", name);
+ cp = (u_char *)pr_cdname(cp, msg, name, sizeof(name));
+ if (doprint)
+ fprintf(file," %s", name);
+ if (doprint)
+ fprintf(file,"(\n\t\t\t%ld\t;serial (version)", _getlong(cp));
+ cp += INT32SZ;
+ if (doprint)
+ fprintf(file,"\n\t\t\t%ld\t;refresh period", _getlong(cp));
+ cp += INT32SZ;
+ if (doprint)
+ fprintf(file,"\n\t\t\t%ld\t;retry refresh this often", _getlong(cp));
+ cp += INT32SZ;
+ if (doprint)
+ fprintf(file,"\n\t\t\t%ld\t;expiration period", _getlong(cp));
+ cp += INT32SZ;
+ if (doprint)
+ fprintf(file,"\n\t\t\t%ld\t;minimum TTL\n\t\t\t)", _getlong(cp));
+ cp += INT32SZ;
+ break;
+
+ case T_MX:
+ case T_AFSDB:
+ case T_RT:
+ if (doprint)
+ if (type == T_MX && !verbose)
+ fprintf(file," (pri=%d) by ", _getshort(cp));
+ else
+ if (verbose)
+ fprintf(file,"\t%d ", _getshort(cp));
+ else
+ fprintf(file," ");
+ cp += sizeof(u_short);
+ cp = (u_char *)pr_cdname(cp, msg, name, sizeof(name));
+ if (doprint)
+ fprintf(file, "%s", name);
+ break;
+
+ case T_MINFO:
+ case T_RP:
+ cp = (u_char *)pr_cdname(cp, msg, name, sizeof(name));
+ if (doprint){
+ if (type == T_RP) {
+ char * p;
+ if (p = strchr(name, '.')) *p = '@';
+ }
+
+ fprintf(file, "%c%s", punc, name);
+ }
+ cp = (u_char *)pr_cdname(cp, msg, name, sizeof(name));
+ if (doprint)
+ fprintf(file, " %s", name);
+ break;
+
+ case T_TXT:
+ case T_X25:
+ {
+ int n,j;
+ u_char * end = cp + dlen;
+
+ if (doprint)
+ (void) fputs(" \"", file);
+ while (cp < end) {
+ if (n = *cp++) {
+ for (j = n; j > 0 && cp < end ; j --)
+ if ((*cp == '\n') || (*cp == '"')) {
+ if (doprint){
+ (void) putc('\\', file);
+ (void) putc(*cp++, file);
+ }
+ } else
+ if (doprint)
+ (void) putc(*cp++, file);
+ }
+ }
+ if (doprint)
+ (void) fputs("\"", file);
+ break;
+ }
+ case T_UINFO:
+ if (doprint)
+ fprintf(file,"%c%s", punc, cp);
+ cp += dlen;
+ break;
+
+ case T_UID:
+ case T_GID:
+ if (dlen == 4) {
+ if (doprint)
+ fprintf(file,"%c%ld", punc, _getlong(cp));
+ cp += INT32SZ;
+ }
+ break;
+
+ case T_WKS:
+ if (dlen < INT32SZ + 1)
+ break;
+ bcopy(cp, (char *)&inaddr, INADDRSZ);
+ cp += INT32SZ;
+ proto = *cp++;
+ protop = getprotobynumber(proto);
+ if (doprint)
+ if (protop)
+ fprintf(file,"%c%s %s", punc,
+ inet_ntoa(inaddr), protop->p_name);
+ else
+ fprintf(file,"%c%s %d", punc,
+ inet_ntoa(inaddr), proto);
+
+ n = 0;
+ while (cp < cp1 + dlen) {
+ c = *cp++;
+ do {
+ if (c & 0200) {
+ servp = NULL;
+ if (protop)
+ servp = getservbyport (htons(n),
+ protop->p_name);
+ if (doprint)
+ if (servp)
+ fprintf(file, " %s", servp->s_name);
+ else
+ fprintf(file, " %d", n);
+ }
+ c <<= 1;
+ } while (++n & 07);
+ }
+ break;
+
+ default:
+ if (doprint)
+ fprintf(file,"%c???", punc);
+ cp += dlen;
+ }
+ if (cp != cp1 + dlen)
+ fprintf(file,"packet size error (%#x != %#x)\n", cp, cp1+dlen);
+ if (doprint)
+ fprintf(file,"\n");
+ return (char *)cp;
+}
+
+static char nbuf[20];
+
+/*
+ * Return a string for the type
+ */
+char *
+pr_type(type)
+ int type;
+{
+ switch (type) {
+ case T_A:
+ return(verbose? "A" : "has address");
+ case T_NS: /* authoritative server */
+ return("NS");
+#ifdef OLDRR
+ case T_MD: /* mail destination */
+ return("MD");
+ case T_MF: /* mail forwarder */
+ return("MF");
+#endif /* OLDRR */
+ case T_CNAME: /* connonical name */
+ return(verbose? "CNAME" : "is a nickname for");
+ case T_SOA: /* start of authority zone */
+ return("SOA");
+ case T_MB: /* mailbox domain name */
+ return("MB");
+ case T_MG: /* mail group member */
+ return("MG");
+ case T_MX: /* mail routing info */
+ return(verbose? "MX" : "mail is handled");
+ case T_TXT: /* TXT - descriptive info */
+ return(verbose? "TXT" : "descriptive text");
+ case T_AFSDB: /* AFS/DCE info */
+ return(verbose? "AFSDB" : "DCE or AFS service from");
+ case T_X25: /* X25 */
+ return(verbose? "X25" : "X25 address");
+ case T_ISDN: /* ISDN */
+ return(verbose? "ISDN" : "ISDN address");
+ case T_RT: /* Router */
+ return(verbose? "RT" : "router");
+ case T_MR: /* mail rename name */
+ return("MR");
+ case T_NULL: /* null resource record */
+ return("NULL");
+ case T_WKS: /* well known service */
+ return("WKS");
+ case T_PTR: /* domain name pointer */
+ return("PTR");
+ case T_HINFO: /* host information */
+ return("HINFO");
+ case T_MINFO: /* mailbox information */
+ return("MINFO");
+ case T_RP: /* responsible person */
+ return(verbose?"RP":"responsible person");
+ case T_AXFR: /* zone transfer */
+ return("AXFR");
+ case T_MAILB: /* mail box */
+ return("MAILB");
+ case T_MAILA: /* mail address */
+ return("MAILA");
+ case T_ANY: /* matches any type */
+ return("ANY");
+ case T_UINFO:
+ return("UINFO");
+ case T_UID:
+ return("UID");
+ case T_GID:
+ return("GID");
+ default:
+ sprintf(nbuf, "%d", type);
+ return nbuf;
+ }
+}
+
+/*
+ * Return a mnemonic for class
+ */
+char *
+pr_class(class)
+ int class;
+{
+
+ switch (class) {
+ case C_IN: /* internet class */
+ return(verbose? " IN" : "");
+ case C_HS: /* internet class */
+ return(verbose? " HS" : "");
+ case C_ANY: /* matches any class */
+ return(" ANY");
+ default:
+ (void) sprintf(nbuf," %d", class);
+ return nbuf;
+ }
+}
+
+u_char *
+pr_cdname(cp, msg, name, namelen)
+ u_char *cp, *msg;
+ char *name;
+ int namelen;
+{
+ int n;
+
+ if ((n = dn_expand(msg, msg + 512, cp, name, namelen - 2)) < 0)
+ return (NULL);
+ if (name[0] == '\0') {
+ name[0] = '.';
+ name[1] = '\0';
+ }
+ return (cp + n);
+}
+
+char *resultcodes[] = {
+ "NOERROR",
+ "FORMERR",
+ "SERVFAIL",
+ "NXDOMAIN",
+ "NOTIMP",
+ "REFUSED",
+ "6",
+ "7",
+ "8",
+ "9",
+ "10",
+ "11",
+ "12",
+ "13",
+ "14",
+ "NOCHANGE",
+};
+
+
+
+/*
+ ******************************************************************************
+ *
+ * ListHosts --
+ *
+ * Requests the name server to do a zone transfer so we
+ * find out what hosts it knows about.
+ *
+ * Results:
+ * SUCCESS the listing was successful.
+ * ERROR the server could not be contacted because
+ * a socket could not be obtained or an error
+ * occured while receiving, or the output file
+ * could not be opened.
+ *
+ ******************************************************************************
+ */
+
+int
+ListHosts(namePtr, queryType)
+ char *namePtr;
+ int queryType; /* e.g. T_A */
+{
+ querybuf buf, answer;
+ struct sockaddr_in sin;
+ HEADER *headerPtr;
+
+ int msglen;
+ int amtToRead;
+ int numRead;
+ int i;
+ int numAnswers = 0;
+ int result;
+ int soacnt = 0;
+ u_short len;
+ int dlen;
+ int type;
+ int nscount;
+ u_char *cp, *nmp;
+ char name[NAME_LEN];
+ char dname[2][NAME_LEN];
+ char domain[NAME_LEN];
+/* names and addresses of name servers to try */
+#define NUMNS 8
+ char nsname[NUMNS][NAME_LEN];
+ int nshaveaddr[NUMNS];
+#define IPADDRSIZE 4
+#define NUMNSADDR 16
+ char nsipaddr[NUMNSADDR][IPADDRSIZE];
+ int numns;
+ int numnsaddr;
+ int thisns;
+ struct hostent *hp;
+ enum {
+ NO_ERRORS,
+ ERR_READING_LEN,
+ ERR_READING_MSG,
+ ERR_PRINTING
+ } error = NO_ERRORS;
+
+/*
+ * normalize to not have trailing dot. We do string compares below
+ * of info from name server, and it won't have trailing dots.
+ */
+ i = strlen(namePtr);
+ if (namePtr[i-1] == '.')
+ namePtr[i-1] = 0;
+
+ if (server_specified) {
+ bcopy(&_res.nsaddr.sin_addr, nsipaddr[0], IPADDRSIZE);
+ numnsaddr = 1;
+ }
+ else {
+
+/*
+ * First we have to find out where to look. This needs a NS query,
+ * possibly followed by looking up addresses for some of the names.
+ */
+
+ msglen = res_mkquery(QUERY, namePtr, C_IN, T_NS, NULL,
+ 0, NULL, buf.qb2, sizeof buf);
+
+ if (msglen < 0) {
+ printf("res_mkquery failed\n");
+ return (ERROR);
+ }
+
+ msglen = res_send(buf.qb2, msglen, answer.qb2, sizeof answer);
+
+ if (msglen < 0) {
+ printf("Unable to get to nameserver -- try again later\n");
+ return (ERROR);
+ }
+ if (_res.options & RES_DEBUG || verbose)
+ printf("rcode = %d (%s), ancount=%d\n",
+ answer.qb1.rcode, DecodeError(answer.qb1.rcode),
+ ntohs(answer.qb1.ancount));
+
+/*
+ * Analyze response to our NS lookup
+ */
+
+ nscount = ntohs(answer.qb1.ancount) + ntohs(answer.qb1.nscount) +
+ ntohs(answer.qb1.arcount);
+
+ if (answer.qb1.rcode != NOERROR || nscount == 0) {
+ switch (answer.qb1.rcode) {
+ case NXDOMAIN:
+ /* Check if it's an authoritive answer */
+ if (answer.qb1.aa) {
+ printf("No such domain\n");
+ } else {
+ printf("Unable to get information about domain -- try again later.\n");
+ }
+ break;
+ case SERVFAIL:
+ printf("Unable to get information about that domain -- try again later.\n");
+ break;
+ case NOERROR:
+ printf("That domain exists, but seems to be a leaf node.\n");
+ break;
+ case FORMERR:
+ case NOTIMP:
+ case REFUSED:
+ printf("Unrecoverable error looking up domain name.\n");
+ break;
+ }
+ return (0);
+ }
+
+ cp = (u_char *)answer.qb2 + HFIXEDSZ;
+ if (ntohs(answer.qb1.qdcount) > 0)
+ cp += dn_skipname(cp, answer.qb2 + msglen) + QFIXEDSZ;
+
+ numns = 0;
+ numnsaddr = 0;
+
+/*
+ * Look at response from NS lookup for NS and A records.
+ */
+
+ for (;nscount; nscount--) {
+ cp += dn_expand(answer.qb2, answer.qb2 + msglen, cp,
+ domain, sizeof(domain));
+ type = _getshort(cp);
+ cp += INT16SZ + INT16SZ + INT32SZ;
+ dlen = _getshort(cp);
+ cp += INT16SZ;
+ if (type == T_NS) {
+ if (dn_expand(answer.qb2, answer.qb2 + msglen, cp,
+ name, sizeof(name)) >= 0) {
+ if (numns < NUMNS && strcasecmp((char *)domain, namePtr) == 0) {
+ for (i = 0; i < numns; i++)
+ if (strcasecmp(nsname[i], (char *)name) == 0)
+ break; /* duplicate */
+ if (i >= numns) {
+ strncpy(nsname[numns], (char *)name, sizeof(name));
+ nshaveaddr[numns] = 0;
+ numns++;
+ }
+ }
+ }
+ }
+ else if (type == T_A) {
+ if (numnsaddr < NUMNSADDR)
+ for (i = 0; i < numns; i++) {
+ if (strcasecmp(nsname[i], (char *)domain) == 0) {
+ nshaveaddr[i]++;
+ bcopy(cp, nsipaddr[numnsaddr],IPADDRSIZE);
+ numnsaddr++;
+ break;
+ }
+ }
+ }
+ cp += dlen;
+ }
+
+/*
+ * Usually we'll get addresses for all the servers in the additional
+ * info section. But in case we don't, look up their addresses.
+ */
+
+ for (i = 0; i < numns; i++) {
+ if (! nshaveaddr[i]) {
+ register long **hptr;
+ int numaddrs = 0;
+
+ hp = gethostbyname(nsname[i]);
+ if (hp) {
+ for (hptr = (long **)hp->h_addr_list; *hptr; hptr++)
+ if (numnsaddr < NUMNSADDR) {
+ bcopy((char *)*hptr, nsipaddr[numnsaddr],IPADDRSIZE);
+ numnsaddr++;
+ numaddrs++;
+ }
+ }
+ if (_res.options & RES_DEBUG || verbose)
+ printf("Found %d addresses for %s by extra query\n",
+ numaddrs, nsname[i]);
+ }
+ else
+ if (_res.options & RES_DEBUG || verbose)
+ printf("Found %d addresses for %s\n",
+ nshaveaddr[i], nsname[i]);
+ }
+ }
+/*
+ * Now nsipaddr has numnsaddr addresses for name servers that
+ * serve the requested domain. Now try to find one that will
+ * accept a zone transfer.
+ */
+
+ thisns = 0;
+
+again:
+
+ numAnswers = 0;
+ soacnt = 0;
+
+ /*
+ * Create a query packet for the requested domain name.
+ *
+ */
+ msglen = res_mkquery(QUERY, namePtr, getclass, T_AXFR, NULL,
+ 0, NULL, buf.qb2, sizeof buf);
+ if (msglen < 0) {
+ if (_res.options & RES_DEBUG) {
+ fprintf(stderr, "ListHosts: Res_mkquery failed\n");
+ }
+ return (ERROR);
+ }
+
+ bzero((char *)&sin, sizeof(sin));
+ sin.sin_family = AF_INET;
+ sin.sin_port = htons(NAMESERVER_PORT);
+
+ /*
+ * Set up a virtual circuit to the server.
+ */
+
+ for (;thisns < numnsaddr; thisns++) {
+ if ((sockFD = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
+ perror("ListHosts");
+ return(ERROR);
+ }
+ bcopy(nsipaddr[thisns], &sin.sin_addr, IPADDRSIZE);
+ if (_res.options & RES_DEBUG || verbose)
+ printf("Trying %s\n", inet_ntoa(sin.sin_addr));
+ if (connect(sockFD, (struct sockaddr *)&sin, sizeof(sin)) >= 0)
+ break;
+ if (verbose)
+ perror("Connection failed, trying next server");
+ (void) close(sockFD);
+ sockFD = -1;
+ }
+ if (thisns >= numnsaddr) {
+ printf("No server for that domain responded\n");
+ if (!verbose)
+ perror("Error from the last server was");
+ return (ERROR);
+ }
+
+ /*
+ * Send length & message for zone transfer
+ */
+
+ __putshort(msglen, (u_char *)&len);
+
+ if (write(sockFD, (char *)&len, INT16SZ) != INT16SZ ||
+ write(sockFD, (char *) &buf, msglen) != msglen) {
+ perror("ListHosts");
+ (void) close(sockFD);
+ sockFD = -1;
+ return (ERROR);
+ }
+
+ filePtr = stdout;
+
+ while (1) {
+
+ /*
+ * Read the length of the response.
+ */
+
+ cp = (u_char *) &buf;
+ amtToRead = INT16SZ;
+ while(amtToRead > 0 && (numRead = read(sockFD, cp, amtToRead)) > 0){
+ cp += numRead;
+ amtToRead -= numRead;
+ }
+ if (numRead <= 0) {
+ error = ERR_READING_LEN;
+ break;
+ }
+
+ if ((len = _getshort((u_char*)&buf)) == 0) {
+ break; /* nothing left to read */
+ }
+
+ /*
+ * Read the response.
+ */
+
+ amtToRead = len;
+ cp = (u_char *) &buf;
+ while(amtToRead > 0 && (numRead = read(sockFD, cp, amtToRead)) > 0){
+ cp += numRead;
+ amtToRead -= numRead;
+ }
+ if (numRead <= 0) {
+ error = ERR_READING_MSG;
+ break;
+ }
+
+ i = buf.qb1.rcode;
+ if (i != NOERROR || ntohs(buf.qb1.ancount) == 0) {
+ if ((thisns+1) < numnsaddr &&
+ (i == SERVFAIL || i == NOTIMP || i == REFUSED)) {
+ if (_res.options & RES_DEBUG || verbose)
+ printf("Server failed, trying next server: %s\n",
+ i != NOERROR ?
+ DecodeError(i) : "Premature end of data");
+ (void) close(sockFD);
+ sockFD = -1;
+ thisns++;
+ goto again;
+ }
+ printf("Server failed: %s\n",
+ i != NOERROR ? DecodeError(i) : "Premature end of data");
+ break;
+ }
+
+
+ result = printinfo(&buf, cp, queryType, 1);
+ if (! result) {
+ error = ERR_PRINTING;
+ break;
+ }
+ numAnswers++;
+ cp = buf.qb2 + HFIXEDSZ;
+ if (ntohs(buf.qb1.qdcount) > 0)
+ cp += dn_skipname(cp, buf.qb2 + len) + QFIXEDSZ;
+
+ nmp = cp;
+ cp += dn_skipname(cp, (u_char *)&buf + len);
+ if ((_getshort(cp) == T_SOA)) {
+ (void) dn_expand(buf.qb2, buf.qb2 + len, nmp,
+ dname[soacnt], sizeof dname[0]);
+ if (soacnt) {
+ if (strcmp((char *)dname[0], (char *)dname[1]) == 0)
+ break;
+ } else
+ soacnt++;
+ }
+ }
+
+ (void) close(sockFD);
+ sockFD = -1;
+
+ switch (error) {
+ case NO_ERRORS:
+ return (SUCCESS);
+
+ case ERR_READING_LEN:
+ return(ERROR);
+
+ case ERR_PRINTING:
+ fprintf(stderr,"*** Error during listing of %s: %s\n",
+ namePtr, DecodeError(result));
+ return(result);
+
+ case ERR_READING_MSG:
+ headerPtr = (HEADER *) &buf;
+ fprintf(stderr,"ListHosts: error receiving zone transfer:\n");
+ fprintf(stderr,
+ " result: %s, answers = %d, authority = %d, additional = %d\n",
+ resultcodes[headerPtr->rcode],
+ ntohs(headerPtr->ancount), ntohs(headerPtr->nscount),
+ ntohs(headerPtr->arcount));
+ return(ERROR);
+ default:
+ return(ERROR);
+ }
+}
+
+char *
+DecodeError(result)
+ int result;
+{
+ switch(result) {
+ case NOERROR: return("Success"); break;
+ case FORMERR: return("Format error"); break;
+ case SERVFAIL: return("Server failed"); break;
+ case NXDOMAIN: return("Non-existent domain"); break;
+ case NOTIMP: return("Not implemented"); break;
+ case REFUSED: return("Query refused"); break;
+#ifdef NOCHANGE
+ case NOCHANGE: return("No change"); break;
+#endif
+ case NO_INFO: return("No information"); break;
+ case ERROR: return("Unspecified error"); break;
+ case TIME_OUT: return("Timed out"); break;
+ case NONAUTH: return("Non-authoritative answer"); break;
+ default: break;
+ }
+ return("BAD ERROR VALUE");
+}
diff --git a/contrib/bind/tools/nslookup/Makefile b/contrib/bind/tools/nslookup/Makefile
new file mode 100644
index 0000000..31f3d16
--- /dev/null
+++ b/contrib/bind/tools/nslookup/Makefile
@@ -0,0 +1,129 @@
+#
+# @(#)Makefile 5.20 (Berkeley) 10/2/89
+# $Id: Makefile,v 8.4 1995/12/22 10:20:42 vixie Exp $
+#
+
+## ++Copyright++ 1987
+## -
+## Copyright (c) 1987
+## The Regents of the University of California. All rights reserved.
+##
+## Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions
+## are met:
+## 1. Redistributions of source code must retain the above copyright
+## notice, this list of conditions and the following disclaimer.
+## 2. Redistributions in binary form must reproduce the above copyright
+## notice, this list of conditions and the following disclaimer in the
+## documentation and/or other materials provided with the distribution.
+## 3. All advertising materials mentioning features or use of this software
+## must display the following acknowledgement:
+## This product includes software developed by the University of
+## California, Berkeley and its contributors.
+## 4. Neither the name of the University nor the names of its contributors
+## may be used to endorse or promote products derived from this software
+## without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+## ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+## ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+## FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+## OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+## HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+## LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+## OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+## SUCH DAMAGE.
+## -
+## Portions Copyright (c) 1993 by Digital Equipment Corporation.
+##
+## Permission to use, copy, modify, and distribute this software for any
+## purpose with or without fee is hereby granted, provided that the above
+## copyright notice and this permission notice appear in all copies, and that
+## the name of Digital Equipment Corporation not be used in advertising or
+## publicity pertaining to distribution of the document or software without
+## specific, written prior permission.
+##
+## THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
+## WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
+## OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
+## CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+## DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+## PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+## ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+## SOFTWARE.
+## -
+## --Copyright--
+
+DESTDIR =
+DESTBIN = /usr/bin
+COMPINCL = ../../compat/include
+CC= cc
+SHELL= /bin/sh
+CDEBUG= -O
+INCL = ../../include
+RES= ../../res/libresolv.a
+COMPLIB= ../../compat/lib/lib44bsd.a
+LDFLAGS =
+LIBS = -ll
+LEX = lex
+DESTHELP= /usr/lib
+DEFS= -D_PATH_HELPFILE=\"$(DESTHELP)/nslookup.help\"
+
+#(bsd/386, 4.4bsd, other net2 descendents)
+#DESTHELP= /usr/share/misc
+#COMPINCL= .
+#COMPLIB=
+#LIBS = -ll -lutil
+#LEX = lex -I
+
+#(sgi irix4)
+#DESTHELP= /usr/bsd
+#DEFS= -xansi -signed -D__STDC__ -D_BSD_SIGNALS \
+# -D_PATH_HELPFILE=\"$(DESTHELP)/nslookup.help\"
+#COMPLIB=
+
+#(sgi irix5)
+#DESTHELP= /usr/share/misc
+#DEFS= -xansi -signed -D__BIT_TYPES_DEFINED__ -D_BSD_SIGNALS \
+# -D_PATH_HELPFILE=\"$(DESTHELP)/nslookup.help\"
+#COMPLIB=
+
+CFLAGS= ${CDEBUG} -I${INCL} -I${COMPINCL} ${DEFS}
+CSRCS= main.c getinfo.c debug.c send.c skip.c list.c subr.c
+SRCS= ${CSRCS} commands.l
+OBJS= main.o getinfo.o debug.o send.o skip.o list.o subr.o commands.o
+
+all: nslookup
+
+nslookup: ${OBJS} ${RES} ${COMPLIB}
+ ${CC} ${CDEBUG} ${LDFLAGS} -o $@ ${OBJS} \
+ ${RES} ${COMPLIB} ${LIBS}
+
+clean:
+ rm -f ${OBJS} core nslookup commands.c lex.yy.c lex.yy.o
+ rm -f *.BAK *.CKP *~
+
+cleandir: clean
+ rm -f tags .depend
+
+depend: ${SRCS}
+ mkdep ${CPPFLAGS} -I${INCL} -I${COMPINCL} ${DEFS} ${SRCS}
+
+install:
+ ${INSTALL} -s -c -o bin -g bin -m 755 nslookup ${DESTDIR}${DESTBIN}/
+ ${INSTALL} -c -o bin -g bin -m 444 nslookup.help \
+ ${DESTDIR}${DESTHELP}/
+
+lint: ${CSRCS}
+ lint ${CSRCS}
+
+tags: ${CSRCS}
+ ctags ${CSRCS}
+
+commands.c: commands.l
+ $(LEX) -t $< > $@ || rm $@
+
+# DO NOT DELETE THIS LINE -- mkdep uses it.
+# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY.
diff --git a/contrib/bind/tools/nslookup/commands.l b/contrib/bind/tools/nslookup/commands.l
new file mode 100644
index 0000000..f70d1aa
--- /dev/null
+++ b/contrib/bind/tools/nslookup/commands.l
@@ -0,0 +1,219 @@
+%{
+
+/*
+ * ++Copyright++ 1985
+ * -
+ * Copyright (c) 1985
+ * 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
+static char sccsid[] = "@(#)commands.l 5.13 (Berkeley) 7/24/90";
+#endif /* not lint */
+
+/*
+ *******************************************************************************
+ *
+ * commands.l
+ *
+ * Andrew Cherenson CS298-26 Fall 1985
+ *
+ * Lex input file for the nslookup program command interpreter.
+ * When a sequence is recognized, the associated action
+ * routine is called. The action routine may need to
+ * parse the string for additional information.
+ *
+ * Recognized commands: (identifiers are shown in uppercase)
+ *
+ * server NAME - set default server to NAME, using default server
+ * lserver NAME - set default server to NAME, using initial server
+ * finger [NAME] - finger the optional NAME
+ * exit - exit the program
+ * root - set default server to the root
+ * ls NAME - list the domain NAME
+ * view FILE - sorts and view the file with more
+ * set OPTION - set an option
+ * help - print help information
+ * ? - print help information
+ * NAME - print info about the host/domain NAME
+ * using default server.
+ * NAME1 NAME2 - as above, but use NAME2 as server
+ *
+ *
+ * yylex Results:
+ * 0 upon end-of-file.
+ * 1 after each command.
+ *
+ *******************************************************************************
+ */
+
+#include "res.h"
+extern char rootServerName[];
+extern void PrintHelp();
+
+%}
+WS [ \t]
+FLET [A-Za-z0-9.*\\]
+LET [A-Za-z0-9.*]
+NAME [A-Za-z0-9.*=_/-]
+%%
+^{WS}*server{WS}+{LET}{NAME}*{WS}*$ {
+ /*
+ * 0 == use current server to find
+ * the new one.
+ * 1 == use original server to find
+ * the new one.
+ */
+ SetDefaultServer(yytext, 0);
+ return(1);
+ }
+^{WS}*lserver{WS}+{LET}{NAME}*{WS}*$ {
+ SetDefaultServer(yytext, 1);
+ return(1);
+ }
+^{WS}*exit{WS}*$ {
+ return(0);
+ }
+^{WS}*root{WS}*$ {
+ SetDefaultServer(rootServerName, 1);
+ return(1);
+ }
+^{WS}*finger({WS}+{LET}{NAME}*)?{WS}+>>?{WS}*{NAME}+{WS}*$ {
+ /*
+ * 2nd arg.
+ * 0 == output to stdout
+ * 1 == output to file
+ */
+ Finger(yytext, 1);
+ return(1);
+ }
+^{WS}*finger({WS}+{LET}{NAME}*)?{WS}*$ {
+ Finger(yytext, 0);
+ return(1);
+ }
+^{WS}*view{WS}+{NAME}+{WS}*$ {
+ ViewList(yytext);
+ return(1);
+ }
+^{WS}*ls{WS}+(("-a"|"-d"|"-h"|"-m"|"-s"){WS}+)?{LET}{NAME}*{WS}+>>?{WS}+{NAME}+{WS}*$ {
+ /*
+ * 2nd arg.
+ * 0 == output to stdout
+ * 1 == output to file
+ */
+ ListHosts(yytext, 1);
+ return(1);
+ }
+^{WS}*ls{WS}+(("-a"|"-d"|"-h"|"-m"|"-s"){WS}+)?{LET}{NAME}*{WS}*$ {
+ ListHosts(yytext, 0);
+ return(1);
+ }
+^{WS}*ls{WS}+-t{WS}+({LET}{NAME}*{WS}+)?{LET}{NAME}*{WS}+>>?{WS}+{NAME}+{WS}*$ {
+ /*
+ * 2nd arg.
+ * 0 == output to stdout
+ * 1 == output to file
+ */
+ ListHostsByType(yytext, 1);
+ return(1);
+ }
+^{WS}*ls{WS}+-t{WS}+({LET}{NAME}*{WS}+)?{LET}{NAME}*{WS}*$ {
+ ListHostsByType(yytext, 0);
+ return(1);
+ }
+^{WS}*set{WS}+{NAME}+{WS}*$ {
+ SetOption(yytext);
+ return(1);
+ }
+^{WS}*help{WS}*$ {
+ PrintHelp();
+ return(1);
+ }
+^{WS}*"?"{WS}*$ {
+ extern void PrintHelp();
+
+ PrintHelp();
+ return(1);
+ }
+^{WS}*{FLET}{NAME}*{WS}+>>?{WS}*{NAME}+{WS}*$ {
+ /*
+ * 0 == output to stdout
+ * 1 == output to file
+ */
+ LookupHost(yytext, 1);
+ return(1);
+ }
+^{WS}*{FLET}{NAME}*{WS}*$ {
+ LookupHost(yytext, 0);
+ return(1);
+ }
+^{WS}*{FLET}{NAME}*{WS}+{LET}{NAME}*{WS}+>>?{WS}*{NAME}+{WS}*$ {
+ /*
+ * 0 == output to stdout
+ * 1 == output to file
+ */
+ LookupHostWithServer(yytext, 1);
+ return(1);
+ }
+^{WS}*{FLET}{NAME}*{WS}+{LET}{NAME}*{WS}*$ {
+ LookupHostWithServer(yytext, 0);
+ return(1);
+ }
+^{WS}*\n {
+ return(1);
+ }
+^.*\n {
+ printf("Unrecognized command: %s",
+ yytext);
+ return(1);
+ }
+\n { ; }
+%%
diff --git a/contrib/bind/tools/nslookup/debug.c b/contrib/bind/tools/nslookup/debug.c
new file mode 100644
index 0000000..e523ae6
--- /dev/null
+++ b/contrib/bind/tools/nslookup/debug.c
@@ -0,0 +1,590 @@
+/*
+ * ++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--
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)debug.c 5.26 (Berkeley) 3/21/91";
+static char rcsid[] = "$Id: debug.c,v 8.4 1996/05/21 07:04:38 vixie Exp $";
+#endif /* not lint */
+
+/*
+ *******************************************************************************
+ *
+ * debug.c --
+ *
+ * Routines to print out packets received from a name server query.
+ *
+ * Modified version of 4.3BSD BIND res_debug.c 5.30 6/27/90
+ *
+ *******************************************************************************
+ */
+
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <arpa/inet.h>
+#include <resolv.h>
+#include <netdb.h>
+#include <stdio.h>
+#include "res.h"
+#include "../../conf/portability.h"
+
+/*
+ * Imported from res_debug.c
+ */
+extern char *_res_resultcodes[];
+extern char *_res_opcodes[];
+
+/*
+ * Used to highlight the start of a record when printing it.
+ */
+#define INDENT " -> "
+
+
+
+/*
+ * Print the contents of a query.
+ * This is intended to be primarily a debugging routine.
+ */
+
+Print_query(msg, eom, printHeader)
+ char *msg, *eom;
+ int printHeader;
+{
+ Fprint_query(msg, eom, printHeader,stdout);
+}
+
+Fprint_query(msg, eom, printHeader,file)
+ u_char *msg, *eom;
+ int printHeader;
+ FILE *file;
+{
+ register u_char *cp;
+ register HEADER *hp;
+ register int n;
+ short class;
+ short type;
+
+ /*
+ * Print header fields.
+ */
+ hp = (HEADER *)msg;
+ cp = msg + HFIXEDSZ;
+ if (printHeader || (_res.options & RES_DEBUG2)) {
+ fprintf(file," HEADER:\n");
+ fprintf(file,"\topcode = %s", _res_opcodes[hp->opcode]);
+ fprintf(file,", id = %d", ntohs(hp->id));
+ fprintf(file,", rcode = %s\n", _res_resultcodes[hp->rcode]);
+ fprintf(file,"\theader flags: ");
+ if (hp->qr) {
+ fprintf(file," response");
+ } else {
+ fprintf(file," query");
+ }
+ if (hp->aa)
+ fprintf(file,", auth. answer");
+ if (hp->tc)
+ fprintf(file,", truncation");
+ if (hp->rd)
+ fprintf(file,", want recursion");
+ if (hp->ra)
+ fprintf(file,", recursion avail.");
+ fprintf(file,"\n\tquestions = %d", ntohs(hp->qdcount));
+ fprintf(file,", answers = %d", ntohs(hp->ancount));
+ fprintf(file,", authority records = %d", ntohs(hp->nscount));
+ fprintf(file,", additional = %d\n\n", ntohs(hp->arcount));
+ }
+
+ /*
+ * Print question records.
+ */
+ if (n = ntohs(hp->qdcount)) {
+ fprintf(file," QUESTIONS:\n");
+ while (--n >= 0) {
+ fprintf(file,"\t");
+ cp = Print_cdname(cp, msg, eom, file);
+ if (cp == NULL)
+ return;
+ type = _getshort((u_char*)cp);
+ cp += INT16SZ;
+ class = _getshort((u_char*)cp);
+ cp += INT16SZ;
+ fprintf(file,", type = %s", p_type(type));
+ fprintf(file,", class = %s\n", p_class(class));
+ }
+ }
+ /*
+ * Print authoritative answer records
+ */
+ if (n = ntohs(hp->ancount)) {
+ fprintf(file," ANSWERS:\n");
+ while (--n >= 0) {
+ fprintf(file, INDENT);
+ cp = Print_rr(cp, msg, eom, file);
+ if (cp == NULL)
+ return;
+ }
+ }
+ /*
+ * print name server records
+ */
+ if (n = ntohs(hp->nscount)) {
+ fprintf(file," AUTHORITY RECORDS:\n");
+ while (--n >= 0) {
+ fprintf(file, INDENT);
+ cp = Print_rr(cp, msg, eom, file);
+ if (cp == NULL)
+ return;
+ }
+ }
+ /*
+ * print additional records
+ */
+ if (n = ntohs(hp->arcount)) {
+ fprintf(file," ADDITIONAL RECORDS:\n");
+ while (--n >= 0) {
+ fprintf(file, INDENT);
+ cp = Print_rr(cp, msg, eom, file);
+ if (cp == NULL)
+ return;
+ }
+ }
+ fprintf(file,"\n------------\n");
+}
+
+
+u_char *
+Print_cdname_sub(cp, msg, eom, file, format)
+ u_char *cp, *msg, *eom;
+ FILE *file;
+ int format;
+{
+ int n;
+ char name[MAXDNAME];
+
+ n = dn_expand(msg, eom, cp, name, sizeof name);
+ if (n < 0)
+ return (NULL);
+ if (name[0] == '\0') {
+ (void) strcpy(name, "(root)");
+ }
+ if (format) {
+ fprintf(file, "%-30s", name);
+ } else {
+ fputs(name, file);
+ }
+ return (cp + n);
+}
+
+u_char *
+Print_cdname(cp, msg, eom, file)
+ u_char *cp, *msg, *eom;
+ FILE *file;
+{
+ return (Print_cdname_sub(cp, msg, eom, file, 0));
+}
+
+u_char *
+Print_cdname2(cp, msg, eom, file)
+ u_char *cp, *msg, *eom;
+ FILE *file;
+{
+ return (Print_cdname_sub(cp, msg, eom, file, 1));
+}
+
+/*
+ * Print resource record fields in human readable form.
+ */
+u_char *
+Print_rr(cp, msg, eom, file)
+ u_char *cp, *msg, *eom;
+ FILE *file;
+{
+ int type, class, dlen, n, c;
+ u_int32_t rrttl, ttl;
+ struct in_addr inaddr;
+ u_char *cp1, *cp2;
+ int debug;
+
+ if ((cp = Print_cdname(cp, msg, eom, file)) == NULL) {
+ fprintf(file, "(name truncated?)\n");
+ return (NULL); /* compression error */
+ }
+
+ type = _getshort((u_char*)cp);
+ cp += INT16SZ;
+ class = _getshort((u_char*)cp);
+ cp += INT16SZ;
+ rrttl = _getlong((u_char*)cp);
+ cp += INT32SZ;
+ dlen = _getshort((u_char*)cp);
+ cp += INT16SZ;
+
+ debug = _res.options & (RES_DEBUG|RES_DEBUG2);
+ if (debug) {
+ if (_res.options & RES_DEBUG2) {
+ fprintf(file,"\n\ttype = %s, class = %s, dlen = %d",
+ p_type(type), p_class(class), dlen);
+ }
+ if (type == T_SOA) {
+ fprintf(file,"\n\tttl = %lu (%s)", rrttl, p_time(rrttl));
+ }
+ (void) putc('\n', file);
+ }
+
+ cp1 = cp;
+
+ /*
+ * Print type specific data, if appropriate
+ */
+ switch (type) {
+ case T_A:
+ switch (class) {
+ case C_IN:
+ case C_HS:
+ bcopy(cp, (char *)&inaddr, INADDRSZ);
+ if (dlen == 4) {
+ fprintf(file,"\tinternet address = %s\n",
+ inet_ntoa(inaddr));
+ cp += dlen;
+ } else if (dlen == 7) {
+ fprintf(file,"\tinternet address = %s",
+ inet_ntoa(inaddr));
+ fprintf(file,", protocol = %d", cp[4]);
+ fprintf(file,", port = %d\n",
+ (cp[5] << 8) + cp[6]);
+ cp += dlen;
+ }
+ break;
+ default:
+ fprintf(file,"\taddress, class = %d, len = %d\n",
+ class, dlen);
+ cp += dlen;
+ }
+ break;
+
+ case T_CNAME:
+ fprintf(file,"\tcanonical name = ");
+ goto doname;
+
+ case T_MG:
+ fprintf(file,"\tmail group member = ");
+ goto doname;
+ case T_MB:
+ fprintf(file,"\tmail box = ");
+ goto doname;
+ case T_MR:
+ fprintf(file,"\tmailbox rename = ");
+ goto doname;
+ case T_MX:
+ fprintf(file,"\tpreference = %u",_getshort((u_char*)cp));
+ cp += INT16SZ;
+ fprintf(file,", mail exchanger = ");
+ goto doname;
+ case T_PX:
+ fprintf(file,"\tpreference = %u",_getshort((u_char*)cp));
+ cp += INT16SZ;
+ fprintf(file,", RFC 822 = ");
+ cp = Print_cdname(cp, msg, eom, file);
+ if (cp == NULL) {
+ fprintf(file, "(name truncated?)\n");
+ return (NULL); /* compression error */
+ }
+ fprintf(file,"\nX.400 = ");
+ cp = Print_cdname(cp, msg, eom, file);
+ if (cp == NULL) {
+ fprintf(file, "(name truncated?)\n");
+ return (NULL); /* compression error */
+ }
+ (void) putc('\n', file);
+ break;
+ case T_RT:
+ fprintf(file,"\tpreference = %u",_getshort((u_char*)cp));
+ cp += INT16SZ;
+ fprintf(file,", router = ");
+ goto doname;
+ case T_AFSDB:
+ fprintf(file,"\tsubtype = %d",_getshort((u_char*)cp));
+ cp += INT16SZ;
+ fprintf(file,", DCE/AFS server = ");
+ goto doname;
+ case T_NS:
+ fprintf(file,"\tnameserver = ");
+ goto doname;
+ case T_PTR:
+ fprintf(file,"\tname = ");
+doname:
+ cp = Print_cdname(cp, msg, eom, file);
+ if (cp == NULL) {
+ fprintf(file, "(name truncated?)\n");
+ return (NULL); /* compression error */
+ }
+ (void) putc('\n', file);
+ break;
+
+ case T_HINFO:
+ cp2 = cp + dlen;
+ if (n = *cp++) {
+ fprintf(file,"\tCPU = %.*s", n, cp);
+ cp += n;
+ }
+ if ((cp < cp2) && (n = *cp++)) {
+ fprintf(file,"\tOS = %.*s\n", n, cp);
+ cp += n;
+ } else fprintf(file, "\n*** Warning *** OS-type missing\n");
+ break;
+
+ case T_ISDN:
+ cp2 = cp + dlen;
+ if (n = *cp++) {
+ fprintf(file,"\tISDN = \"%.*s", n, cp);
+ cp += n;
+ }
+ if ((cp < cp2) && (n = *cp++)) {
+ fprintf(file,"-%.*s\"\n", n, cp);
+ cp += n;
+ } else fprintf(file,"\"\n");
+ break;
+
+
+ case T_SOA:
+ if (!debug)
+ (void) putc('\n', file);
+ fprintf(file,"\torigin = ");
+ cp = Print_cdname(cp, msg, eom, file);
+ if (cp == NULL) {
+ fprintf(file, "(name truncated?)\n");
+ return (NULL); /* compression error */
+ }
+ fprintf(file,"\n\tmail addr = ");
+ cp = Print_cdname(cp, msg, eom, file);
+ if (cp == NULL) {
+ fprintf(file, "(name truncated?)\n");
+ return (NULL); /* compression error */
+ }
+ fprintf(file,"\n\tserial = %lu", _getlong((u_char*)cp));
+ cp += INT32SZ;
+ ttl = _getlong((u_char*)cp);
+ fprintf(file,"\n\trefresh = %lu (%s)", ttl, p_time(ttl));
+ cp += INT32SZ;
+ ttl = _getlong((u_char*)cp);
+ fprintf(file,"\n\tretry = %lu (%s)", ttl, p_time(ttl));
+ cp += INT32SZ;
+ ttl = _getlong((u_char*)cp);
+ fprintf(file,"\n\texpire = %lu (%s)", ttl, p_time(ttl));
+ cp += INT32SZ;
+ ttl = _getlong((u_char*)cp);
+ fprintf(file,
+ "\n\tminimum ttl = %lu (%s)\n", ttl, p_time(ttl));
+ cp += INT32SZ;
+ break;
+
+ case T_MINFO:
+ if (!debug)
+ (void) putc('\n', file);
+ fprintf(file,"\trequests = ");
+ cp = Print_cdname(cp, msg, eom, file);
+ if (cp == NULL) {
+ fprintf(file, "(name truncated?)\n");
+ return (NULL); /* compression error */
+ }
+ fprintf(file,"\n\terrors = ");
+ cp = Print_cdname(cp, msg, eom, file);
+ if (cp == NULL) {
+ fprintf(file, "(name truncated?)\n");
+ return (NULL); /* compression error */
+ }
+ (void) putc('\n', file);
+ break;
+ case T_RP:
+ if (!debug)
+ (void) putc('\n', file);
+ fprintf(file,"\tmailbox = ");
+ cp = Print_cdname(cp, msg, eom, file);
+ if (cp == NULL) {
+ fprintf(file, "(name truncated?)\n");
+ return (NULL); /* compression error */
+ }
+ fprintf(file,"\n\ttext = ");
+ cp = Print_cdname(cp, msg, eom, file);
+ if (cp == NULL) {
+ fprintf(file, "(name truncated?)\n");
+ return (NULL); /* compression error */
+ }
+ (void) putc('\n', file);
+ break;
+
+ case T_TXT:
+ (void) fputs("\ttext = \"", file);
+ cp2 = cp1 + dlen;
+ while (cp < cp2) {
+ if (n = (unsigned char) *cp++) {
+ for (c = n; c > 0 && cp < cp2; c--)
+ if ((*cp == '\n') || (*cp == '"')) {
+ (void) putc('\\', file);
+ (void) putc(*cp++, file);
+ } else
+ (void) putc(*cp++, file);
+ }
+ }
+ (void) fputs("\"\n", file);
+ break;
+
+ case T_X25:
+ (void) fputs("\tX25 = \"", file);
+ cp2 = cp1 + dlen;
+ while (cp < cp2) {
+ if (n = (unsigned char) *cp++) {
+ for (c = n; c > 0 && cp < cp2; c--)
+ if (*cp == '\n') {
+ (void) putc('\\', file);
+ (void) putc(*cp++, file);
+ } else
+ (void) putc(*cp++, file);
+ }
+ }
+ (void) fputs("\"\n", file);
+ break;
+
+ case T_NSAP:
+ fprintf(file, "\tnsap = %s\n", inet_nsap_ntoa(dlen, cp, NULL));
+ cp += dlen;
+ break;
+
+ case T_AAAA: {
+ char t[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"];
+
+ fprintf(file, "IPv6 address = %s\n",
+ inet_ntop(AF_INET6, cp, t, sizeof t));
+ break;
+ }
+
+ case T_UINFO:
+ fprintf(file,"\tuser info = %s\n", cp);
+ cp += dlen;
+ break;
+
+ case T_UID:
+ case T_GID:
+ if (dlen == 4) {
+ fprintf(file,"\t%cid = %u\n",type == T_UID ? 'u' : 'g',
+ _getlong((u_char*)cp));
+ cp += INT32SZ;
+ } else {
+ fprintf(file,"\t%cid of length %d?\n",
+ type == T_UID ? 'u' : 'g', dlen);
+ cp += dlen;
+ }
+ break;
+
+ case T_WKS: {
+ struct protoent *protoPtr;
+
+ if (dlen < INT32SZ + 1)
+ break;
+ if (!debug)
+ (void) putc('\n', file);
+ bcopy(cp, (char *)&inaddr, INADDRSZ);
+ cp += INT32SZ;
+ if ((protoPtr = getprotobynumber(*cp)) != NULL) {
+ fprintf(file,"\tinet address = %s, protocol = %s\n\t",
+ inet_ntoa(inaddr), protoPtr->p_name);
+ } else {
+ fprintf(file,"\tinet address = %s, protocol = %d\n\t",
+ inet_ntoa(inaddr), *cp);
+ }
+ cp++;
+ n = 0;
+ while (cp < cp1 + dlen) {
+ c = *cp++;
+ do {
+ struct servent *s;
+
+ if (c & 0200) {
+ s = getservbyport((int)htons(n),
+ protoPtr ? protoPtr->p_name : NULL);
+ if (s != NULL) {
+ fprintf(file," %s", s->s_name);
+ } else {
+ fprintf(file," #%d", n);
+ }
+ }
+ c <<= 1;
+ } while (++n & 07);
+ }
+ putc('\n',file);
+ }
+ break;
+
+ case T_NULL:
+ fprintf(file, "\tNULL (dlen %d)\n", dlen);
+ cp += dlen;
+ break;
+
+ default:
+ fprintf(file,"\t??? unknown type %d ???\n", type);
+ cp += dlen;
+ }
+ if (_res.options & RES_DEBUG && type != T_SOA) {
+ fprintf(file,"\tttl = %lu (%s)\n", rrttl, p_time(rrttl));
+ }
+ if (cp != cp1 + dlen) {
+ fprintf(file,
+ "\n*** Error: record size incorrect (%d != %d)\n\n",
+ cp - cp1, dlen);
+ cp = NULL;
+ }
+ return (cp);
+}
diff --git a/contrib/bind/tools/nslookup/getinfo.c b/contrib/bind/tools/nslookup/getinfo.c
new file mode 100644
index 0000000..4587fb6
--- /dev/null
+++ b/contrib/bind/tools/nslookup/getinfo.c
@@ -0,0 +1,843 @@
+/*
+ * ++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--
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)getinfo.c 5.26 (Berkeley) 3/21/91";
+static char rcsid[] = "$Id: getinfo.c,v 8.3 1995/12/29 07:16:27 vixie Exp $";
+#endif /* not lint */
+
+/*
+ ******************************************************************************
+ *
+ * getinfo.c --
+ *
+ * Routines to create requests to name servers
+ * and interpret the answers.
+ *
+ * Adapted from 4.3BSD BIND gethostnamadr.c
+ *
+ ******************************************************************************
+ */
+
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <arpa/inet.h>
+#include <resolv.h>
+#include <stdio.h>
+#include <ctype.h>
+#include "res.h"
+#include "../../conf/portability.h"
+
+extern char *_res_resultcodes[];
+extern char *res_skip();
+
+#define MAXALIASES 35
+#define MAXADDRS 35
+#define MAXDOMAINS 35
+#define MAXSERVERS 10
+
+static char *addr_list[MAXADDRS + 1];
+
+static char *host_aliases[MAXALIASES];
+static int host_aliases_len[MAXALIASES];
+static u_char hostbuf[BUFSIZ+1];
+
+typedef struct {
+ char *name;
+ char *domain[MAXDOMAINS];
+ int numDomains;
+ char *address[MAXADDRS];
+ int numAddresses;
+} ServerTable;
+
+ServerTable server[MAXSERVERS];
+
+typedef union {
+ HEADER qb1;
+ u_char qb2[PACKETSZ*2];
+} querybuf;
+
+typedef union {
+ int32_t al;
+ char ac;
+} align;
+
+#define GetShort(cp) _getshort(cp); cp += INT16SZ;
+
+
+/*
+ ******************************************************************************
+ *
+ * GetAnswer --
+ *
+ * Interprets an answer packet and retrieves the following
+ * information:
+ *
+ * Results:
+ * SUCCESS the info was retrieved.
+ * NO_INFO the packet did not contain an answer.
+ * NONAUTH non-authoritative information was found.
+ * ERROR the answer was malformed.
+ * Other errors returned in the packet header.
+ *
+ ******************************************************************************
+ */
+
+static int
+GetAnswer(nsAddrPtr, queryType, msg, msglen, iquery, hostPtr, isServer)
+ struct in_addr *nsAddrPtr;
+ char *msg;
+ int queryType;
+ int msglen;
+ Boolean iquery;
+ register HostInfo *hostPtr;
+ Boolean isServer;
+{
+ register HEADER *headerPtr;
+ register u_char *cp;
+ querybuf answer;
+ char **aliasPtr;
+ u_char *eom, *bp;
+ char **addrPtr;
+ char *namePtr;
+ char *dnamePtr;
+ int type, class;
+ int qdcount, ancount, arcount, nscount, buflen;
+ int origClass;
+ int numAliases = 0;
+ int numAddresses = 0;
+ int n, i, j;
+ int len;
+ int dlen;
+ int status;
+ int numServers;
+ Boolean haveAnswer;
+ Boolean printedAnswers = FALSE;
+
+
+ /*
+ * If the hostPtr was used before, free up the calloc'd areas.
+ */
+ FreeHostInfoPtr(hostPtr);
+
+ status = SendRequest(nsAddrPtr, msg, msglen, (char *) &answer,
+ sizeof(answer), &n);
+
+ if (status != SUCCESS) {
+ if (_res.options & RES_DEBUG2)
+ printf("SendRequest failed\n");
+ return (status);
+ }
+ eom = (u_char *) &answer + n;
+
+ headerPtr = (HEADER *) &answer;
+
+ if (headerPtr->rcode != NOERROR) {
+ return (headerPtr->rcode);
+ }
+
+ qdcount = ntohs(headerPtr->qdcount);
+ ancount = ntohs(headerPtr->ancount);
+ arcount = ntohs(headerPtr->arcount);
+ nscount = ntohs(headerPtr->nscount);
+
+ /*
+ * If there are no answer, n.s. or additional records
+ * then return with an error.
+ */
+ if (ancount == 0 && nscount == 0 && arcount == 0) {
+ return (NO_INFO);
+ }
+
+
+ bp = hostbuf;
+ buflen = sizeof(hostbuf);
+ cp = (u_char *) &answer + HFIXEDSZ;
+
+ /* Skip over question section. */
+ while (qdcount-- > 0) {
+ cp += dn_skipname(cp, eom) + QFIXEDSZ;
+ }
+
+ aliasPtr = host_aliases;
+ addrPtr = addr_list;
+ haveAnswer = FALSE;
+
+ /*
+ * Scan through the answer resource records.
+ * Answers for address query types are saved.
+ * Other query type answers are just printed.
+ */
+ if (ancount != 0) {
+ if (!isServer && !headerPtr->aa) {
+ printf("Non-authoritative answer:\n");
+ }
+
+ if (queryType != T_A && !(iquery && queryType == T_PTR)) {
+ while (--ancount >= 0 && cp < eom) {
+ if ((cp = (u_char *)Print_rr(cp,
+ (char *)&answer, eom, stdout)) == NULL) {
+ return(ERROR);
+ }
+ }
+ printedAnswers = TRUE;
+ } else {
+ while (--ancount >= 0 && cp < eom) {
+ n = dn_expand(answer.qb2, eom, cp, (char *)bp, buflen);
+ if (n < 0) {
+ return(ERROR);
+ }
+ cp += n;
+ type = GetShort(cp);
+ class = GetShort(cp);
+ cp += INT32SZ; /* skip TTL */
+ dlen = GetShort(cp);
+ if (type == T_CNAME) {
+ /*
+ * Found an alias.
+ */
+ cp += dlen;
+ if (aliasPtr >= &host_aliases[MAXALIASES-1]) {
+ continue;
+ }
+ *aliasPtr++ = (char *)bp;
+ n = strlen((char *)bp) + 1;
+ host_aliases_len[numAliases] = n;
+ numAliases++;
+ bp += n;
+ buflen -= n;
+ continue;
+ } else if (type == T_PTR) {
+ /*
+ * Found a "pointer" to the real name.
+ */
+ n = dn_expand(answer.qb2, eom, cp, (char *)bp, buflen);
+ if (n < 0) {
+ cp += n;
+ continue;
+ }
+ cp += n;
+ len = strlen((char *)bp) + 1;
+ hostPtr->name = Calloc(1, len);
+ bcopy(bp, hostPtr->name, len);
+ haveAnswer = TRUE;
+ break;
+ } else if (type != T_A) {
+ cp += dlen;
+ continue;
+ }
+ if (haveAnswer) {
+ /*
+ * If we've already got 1 address, we aren't interested
+ * in addresses with a different length or class.
+ */
+ if (dlen != hostPtr->addrLen) {
+ cp += dlen;
+ continue;
+ }
+ if (class != origClass) {
+ cp += dlen;
+ continue;
+ }
+ } else {
+ /*
+ * First address: record its length and class so we
+ * only save additonal ones with the same attributes.
+ */
+ hostPtr->addrLen = dlen;
+ origClass = class;
+ hostPtr->addrType = (class == C_IN) ? AF_INET : AF_UNSPEC;
+ len = strlen((char *)bp) + 1;
+ hostPtr->name = Calloc(1, len);
+ bcopy(bp, hostPtr->name, len);
+ }
+ bp += (((u_int32_t)bp) % sizeof(align));
+
+ if (bp + dlen >= &hostbuf[sizeof(hostbuf)]) {
+ if (_res.options & RES_DEBUG) {
+ printf("Size (%d) too big\n", dlen);
+ }
+ break;
+ }
+ bcopy(cp, *addrPtr++ = (char *)bp, dlen);
+ bp +=dlen;
+ cp += dlen;
+ numAddresses++;
+ haveAnswer = TRUE;
+ }
+ }
+ }
+
+ if ((queryType == T_A || queryType == T_PTR) && haveAnswer) {
+
+ /*
+ * Go through the alias and address lists and return them
+ * in the hostPtr variable.
+ */
+
+ if (numAliases > 0) {
+ hostPtr->aliases =
+ (char **) Calloc(1 + numAliases, sizeof(char *));
+ for (i = 0; i < numAliases; i++) {
+ hostPtr->aliases[i] = Calloc(1, host_aliases_len[i]);
+ bcopy(host_aliases[i],
+ hostPtr->aliases[i],
+ host_aliases_len[i]);
+ }
+ hostPtr->aliases[i] = NULL;
+ }
+ if (numAddresses > 0) {
+ hostPtr->addrList =
+ (char **)Calloc(1+numAddresses, sizeof(char *));
+ for (i = 0; i < numAddresses; i++) {
+ hostPtr->addrList[i] = Calloc(1, hostPtr->addrLen);
+ bcopy(addr_list[i], hostPtr->addrList[i], hostPtr->addrLen);
+ }
+ hostPtr->addrList[i] = NULL;
+ }
+#ifdef verbose
+ if (headerPtr->aa || nscount == 0) {
+ hostPtr->servers = NULL;
+ return (SUCCESS);
+ }
+#else
+ hostPtr->servers = NULL;
+ return (SUCCESS);
+#endif
+ }
+
+ /*
+ * At this point, for the T_A query type, only empty answers remain.
+ * For other query types, additional information might be found
+ * in the additional resource records part.
+ */
+
+ if (!headerPtr->aa && (queryType != T_A) && (nscount > 0 || arcount > 0)) {
+ if (printedAnswers) {
+ putchar('\n');
+ }
+ printf("Authoritative answers can be found from:\n");
+ }
+
+ cp = (u_char *)res_skip((char *) &answer, 2, eom);
+
+ numServers = 0;
+ if (queryType != T_A) {
+ /*
+ * If we don't need to save the record, just print it.
+ */
+ while (--nscount >= 0 && cp < eom) {
+ if ((cp = (u_char *)Print_rr(cp,
+ (char *) &answer, eom, stdout)) == NULL) {
+ return(ERROR);
+ }
+ }
+ } else {
+ while (--nscount >= 0 && cp < eom) {
+ /*
+ * Go through the NS records and retrieve the names of hosts
+ * that serve the requested domain.
+ */
+
+ n = dn_expand(answer.qb2, eom, cp, (char *)bp, buflen);
+ if (n < 0) {
+ return(ERROR);
+ }
+ cp += n;
+ len = strlen((char *)bp) + 1;
+ dnamePtr = Calloc(1, len); /* domain name */
+ bcopy(bp, dnamePtr, len);
+
+ type = GetShort(cp);
+ class = GetShort(cp);
+ cp += INT32SZ; /* skip TTL */
+ dlen = GetShort(cp);
+
+ if (type != T_NS) {
+ cp += dlen;
+ } else {
+ Boolean found;
+
+ n = dn_expand(answer.qb2, eom, cp, (char *)bp, buflen);
+ if (n < 0) {
+ return(ERROR);
+ }
+ cp += n;
+ len = strlen((char *)bp) + 1;
+ namePtr = Calloc(1, len); /* server host name */
+ bcopy(bp, namePtr, len);
+
+ /*
+ * Store the information keyed by the server host name.
+ */
+ found = FALSE;
+ for (j = 0; j < numServers; j++) {
+ if (strcmp(namePtr, server[j].name) == 0) {
+ found = TRUE;
+ free(namePtr);
+ break;
+ }
+ }
+ if (found) {
+ server[j].numDomains++;
+ if (server[j].numDomains <= MAXDOMAINS) {
+ server[j].domain[server[j].numDomains-1] = dnamePtr;
+ }
+ } else {
+ if (numServers >= MAXSERVERS) {
+ break;
+ }
+ server[numServers].name = namePtr;
+ server[numServers].domain[0] = dnamePtr;
+ server[numServers].numDomains = 1;
+ server[numServers].numAddresses = 0;
+ numServers++;
+ }
+ }
+ }
+ }
+
+ /*
+ * Additional resource records contain addresses of servers.
+ */
+ cp = (u_char *)res_skip((char *) &answer, 3, eom);
+
+ if (queryType != T_A) {
+ /*
+ * If we don't need to save the record, just print it.
+ */
+ while (--arcount >= 0 && cp < eom) {
+ if ((cp = (u_char *)Print_rr(cp,
+ (char *) &answer, eom, stdout)) == NULL) {
+ return(ERROR);
+ }
+ }
+ } else {
+ while (--arcount >= 0 && cp < eom) {
+ n = dn_expand(answer.qb2, eom, cp, (char *)bp, buflen);
+ if (n < 0) {
+ break;
+ }
+ cp += n;
+ type = GetShort(cp);
+ class = GetShort(cp);
+ cp += INT32SZ; /* skip TTL */
+ dlen = GetShort(cp);
+
+ if (type != T_A) {
+ cp += dlen;
+ continue;
+ } else {
+ for (j = 0; j < numServers; j++) {
+ if (strcmp((char *)bp, server[j].name) == 0) {
+ server[j].numAddresses++;
+ if (server[j].numAddresses <= MAXADDRS) {
+ server[j].address[server[j].numAddresses-1] =
+ Calloc(1,dlen);
+ bcopy(cp,
+ server[j].address[server[j].numAddresses-1],dlen);
+ break;
+ }
+ }
+ }
+ cp += dlen;
+ }
+ }
+ }
+
+ /*
+ * If we are returning name server info, transfer it to the hostPtr.
+ */
+ if (numServers > 0) {
+ hostPtr->servers = (ServerInfo **)
+ Calloc(numServers+1, sizeof(ServerInfo *));
+
+ for (i = 0; i < numServers; i++) {
+ hostPtr->servers[i] = (ServerInfo *) Calloc(1, sizeof(ServerInfo));
+ hostPtr->servers[i]->name = server[i].name;
+
+
+ hostPtr->servers[i]->domains = (char **)
+ Calloc(server[i].numDomains+1,sizeof(char *));
+ for (j = 0; j < server[i].numDomains; j++) {
+ hostPtr->servers[i]->domains[j] = server[i].domain[j];
+ }
+ hostPtr->servers[i]->domains[j] = NULL;
+
+
+ hostPtr->servers[i]->addrList = (char **)
+ Calloc(server[i].numAddresses+1,sizeof(char *));
+ for (j = 0; j < server[i].numAddresses; j++) {
+ hostPtr->servers[i]->addrList[j] = server[i].address[j];
+ }
+ hostPtr->servers[i]->addrList[j] = NULL;
+
+ }
+ hostPtr->servers[i] = NULL;
+ }
+
+ switch (queryType) {
+ case T_A:
+ return NONAUTH;
+ case T_PTR:
+ if (iquery)
+ return NO_INFO;
+ /* fall through */
+ default:
+ return SUCCESS;
+ }
+}
+
+/*
+*******************************************************************************
+*
+* GetHostInfo --
+*
+* Retrieves host name, address and alias information
+* for a domain.
+*
+* Algorithm from res_search().
+*
+* Results:
+* ERROR - res_mkquery failed.
+* + return values from GetAnswer()
+*
+*******************************************************************************
+*/
+
+int
+GetHostInfoByName(nsAddrPtr, queryClass, queryType, name, hostPtr, isServer)
+ struct in_addr *nsAddrPtr;
+ int queryClass;
+ int queryType;
+ char *name;
+ HostInfo *hostPtr;
+ Boolean isServer;
+{
+ int n;
+ register int result;
+ register char *cp, **domain;
+ Boolean got_nodata = FALSE;
+ struct in_addr ina;
+ Boolean tried_as_is = FALSE;
+
+ /* Catch explicit addresses */
+ if ((queryType == T_A) && IsAddr(name, &ina)) {
+ hostPtr->name = Calloc(strlen(name)+3, 1);
+ (void)sprintf(hostPtr->name,"[%s]",name);
+ hostPtr->aliases = NULL;
+ hostPtr->servers = NULL;
+ hostPtr->addrType = AF_INET;
+ hostPtr->addrLen = INADDRSZ;
+ hostPtr->addrList = (char **)Calloc(2, sizeof(char *));
+ hostPtr->addrList[0] = Calloc(INT32SZ, sizeof(char));
+ bcopy((char *)&ina, hostPtr->addrList[0], INADDRSZ);
+ hostPtr->addrList[1] = NULL;
+ return(SUCCESS);
+ }
+
+ result = NXDOMAIN;
+ for (cp = name, n = 0; *cp; cp++)
+ if (*cp == '.')
+ n++;
+ if (n == 0 && (cp = hostalias(name))) {
+ printf("Aliased to \"%s\"\n\n", cp);
+ return (GetHostDomain(nsAddrPtr, queryClass, queryType,
+ cp, (char *)NULL, hostPtr, isServer));
+ }
+
+ /*
+ * If there are dots in the name already, let's just give it a try
+ * 'as is'. The threshold can be set with the "ndots" option.
+ */
+ if (n >= (int)_res.ndots) {
+ result = GetHostDomain(nsAddrPtr, queryClass, queryType,
+ name, (char *)NULL, hostPtr, isServer);
+ if (result == SUCCESS)
+ return (result);
+ if (result == NO_INFO)
+ got_nodata++;
+ tried_as_is++;
+ }
+
+ /*
+ * We do at least one level of search if
+ * - there is no dot and RES_DEFNAME is set, or
+ * - there is at least one dot, there is no trailing dot,
+ * and RES_DNSRCH is set.
+ */
+ if ((n == 0 && _res.options & RES_DEFNAMES) ||
+ (n != 0 && *--cp != '.' && _res.options & RES_DNSRCH))
+ for (domain = _res.dnsrch; *domain; domain++) {
+ result = GetHostDomain(nsAddrPtr, queryClass, queryType,
+ name, *domain, hostPtr, isServer);
+ /*
+ * If no server present, give up.
+ * If name isn't found in this domain,
+ * keep trying higher domains in the search list
+ * (if that's enabled).
+ * On a NO_INFO error, keep trying, otherwise
+ * a wildcard entry of another type could keep us
+ * from finding this entry higher in the domain.
+ * If we get some other error (negative answer or
+ * server failure), then stop searching up,
+ * but try the input name below in case it's fully-qualified.
+ */
+ if (result == SUCCESS || result == NO_RESPONSE)
+ return result;
+ if (result == NO_INFO)
+ got_nodata++;
+ if ((result != NXDOMAIN && result != NO_INFO) ||
+ (_res.options & RES_DNSRCH) == 0)
+ break;
+ }
+ /* if we have not already tried the name "as is", do that now.
+ * note that we do this regardless of how many dots were in the
+ * name or whether it ends with a dot.
+ */
+ if (!tried_as_is &&
+ (result = GetHostDomain(nsAddrPtr, queryClass, queryType,
+ name, (char *)NULL, hostPtr, isServer)
+ ) == SUCCESS)
+ return (result);
+ if (got_nodata)
+ result = NO_INFO;
+ return (result);
+}
+
+/*
+ * Perform a query on the concatenation of name and domain,
+ * removing a trailing dot from name if domain is NULL.
+ */
+GetHostDomain(nsAddrPtr, queryClass, queryType, name, domain, hostPtr, isServer)
+ struct in_addr *nsAddrPtr;
+ int queryClass;
+ int queryType;
+ char *name, *domain;
+ HostInfo *hostPtr;
+ Boolean isServer;
+{
+ querybuf buf;
+ char nbuf[2*MAXDNAME+2];
+ char *longname = nbuf;
+ int n;
+
+ if (domain == NULL) {
+ /*
+ * Check for trailing '.';
+ * copy without '.' if present.
+ */
+ n = strlen(name) - 1;
+ if (name[n] == '.' && n < sizeof(nbuf) - 1) {
+ bcopy(name, nbuf, n);
+ nbuf[n] = '\0';
+ } else
+ longname = name;
+ } else {
+ (void)sprintf(nbuf, "%.*s.%.*s",
+ MAXDNAME, name, MAXDNAME, domain);
+ longname = nbuf;
+ }
+ n = res_mkquery(QUERY, longname, queryClass, queryType,
+ NULL, 0, 0, buf.qb2, sizeof(buf));
+ if (n < 0) {
+ if (_res.options & RES_DEBUG) {
+ printf("Res_mkquery failed\n");
+ }
+ return (ERROR);
+ }
+
+ n = GetAnswer(nsAddrPtr, queryType, (char *)&buf, n, 0, hostPtr, isServer);
+
+ /*
+ * GetAnswer didn't find a name, so set it to the specified one.
+ */
+ if (n == NONAUTH) {
+ if (hostPtr->name == NULL) {
+ int len = strlen(longname) + 1;
+ hostPtr->name = Calloc(len, sizeof(char));
+ bcopy(longname, hostPtr->name, len);
+ }
+ }
+ return(n);
+}
+
+
+/*
+*******************************************************************************
+*
+* GetHostInfoByAddr --
+*
+* Performs a PTR lookup in in-addr.arpa to find the host name
+* that corresponds to the given address.
+*
+* Results:
+* ERROR - res_mkquery failed.
+* + return values from GetAnswer()
+*
+*******************************************************************************
+*/
+
+int
+GetHostInfoByAddr(nsAddrPtr, address, hostPtr)
+ struct in_addr *nsAddrPtr;
+ struct in_addr *address;
+ HostInfo *hostPtr;
+{
+ int n;
+ querybuf buf;
+ char qbuf[MAXDNAME];
+ char *p = (char *) &address->s_addr;
+
+ (void)sprintf(qbuf, "%u.%u.%u.%u.in-addr.arpa",
+ ((unsigned)p[3] & 0xff),
+ ((unsigned)p[2] & 0xff),
+ ((unsigned)p[1] & 0xff),
+ ((unsigned)p[0] & 0xff));
+ n = res_mkquery(QUERY, qbuf, C_IN, T_PTR, NULL, 0, NULL,
+ buf.qb2, sizeof buf);
+ if (n < 0) {
+ if (_res.options & RES_DEBUG) {
+ printf("res_mkquery() failed\n");
+ }
+ return (ERROR);
+ }
+ n = GetAnswer(nsAddrPtr, T_PTR, (char *) &buf, n, 1, hostPtr, 1);
+ if (n == SUCCESS) {
+ hostPtr->addrType = AF_INET;
+ hostPtr->addrLen = 4;
+ hostPtr->addrList = (char **)Calloc(2, sizeof(char *));
+ hostPtr->addrList[0] = Calloc(INT32SZ, sizeof(char));
+ bcopy((char *)p, hostPtr->addrList[0], INADDRSZ);
+ hostPtr->addrList[1] = NULL;
+ }
+ return n;
+}
+
+/*
+*******************************************************************************
+*
+* FreeHostInfoPtr --
+*
+* Deallocates all the calloc'd areas for a HostInfo variable.
+*
+*******************************************************************************
+*/
+
+void
+FreeHostInfoPtr(hostPtr)
+ register HostInfo *hostPtr;
+{
+ int i, j;
+
+ if (hostPtr->name != NULL) {
+ free(hostPtr->name);
+ hostPtr->name = NULL;
+ }
+
+ if (hostPtr->aliases != NULL) {
+ i = 0;
+ while (hostPtr->aliases[i] != NULL) {
+ free(hostPtr->aliases[i]);
+ i++;
+ }
+ free((char *)hostPtr->aliases);
+ hostPtr->aliases = NULL;
+ }
+
+ if (hostPtr->addrList != NULL) {
+ i = 0;
+ while (hostPtr->addrList[i] != NULL) {
+ free(hostPtr->addrList[i]);
+ i++;
+ }
+ free((char *)hostPtr->addrList);
+ hostPtr->addrList = NULL;
+ }
+
+ if (hostPtr->servers != NULL) {
+ i = 0;
+ while (hostPtr->servers[i] != NULL) {
+
+ if (hostPtr->servers[i]->name != NULL) {
+ free(hostPtr->servers[i]->name);
+ }
+
+ if (hostPtr->servers[i]->domains != NULL) {
+ j = 0;
+ while (hostPtr->servers[i]->domains[j] != NULL) {
+ free(hostPtr->servers[i]->domains[j]);
+ j++;
+ }
+ free((char *)hostPtr->servers[i]->domains);
+ }
+
+ if (hostPtr->servers[i]->addrList != NULL) {
+ j = 0;
+ while (hostPtr->servers[i]->addrList[j] != NULL) {
+ free(hostPtr->servers[i]->addrList[j]);
+ j++;
+ }
+ free((char *)hostPtr->servers[i]->addrList);
+ }
+ free((char *)hostPtr->servers[i]);
+ i++;
+ }
+ free((char *)hostPtr->servers);
+ hostPtr->servers = NULL;
+ }
+}
diff --git a/contrib/bind/tools/nslookup/list.c b/contrib/bind/tools/nslookup/list.c
new file mode 100644
index 0000000..6225e4f
--- /dev/null
+++ b/contrib/bind/tools/nslookup/list.c
@@ -0,0 +1,1071 @@
+/*
+ * ++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--
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)list.c 5.23 (Berkeley) 3/21/91";
+static char rcsid[] = "$Id: list.c,v 8.5 1996/05/21 07:04:38 vixie Exp $";
+#endif /* not lint */
+
+/*
+ *******************************************************************************
+ *
+ * list.c --
+ *
+ * Routines to obtain info from name and finger servers.
+ *
+ * Adapted from 4.3BSD BIND ns_init.c and from finger.c.
+ *
+ *******************************************************************************
+ */
+
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <arpa/inet.h>
+#include <resolv.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <limits.h>
+#include <ctype.h>
+#include <errno.h>
+#include "res.h"
+#include "../../conf/portability.h"
+
+extern char *_res_resultcodes[]; /* res_debug.c */
+extern char *pager;
+
+typedef union {
+ HEADER qb1;
+ u_char qb2[PACKETSZ];
+} querybuf;
+
+extern HostInfo *defaultPtr;
+extern HostInfo curHostInfo;
+extern int curHostValid;
+extern int queryType;
+extern int queryClass;
+
+static int sockFD = -1;
+int ListSubr();
+
+/*
+ * During a listing to a file, hash marks are printed
+ * every HASH_SIZE records.
+ */
+
+#define HASH_SIZE 50
+
+
+/*
+ *******************************************************************************
+ *
+ * ListHosts --
+ * ListHostsByType --
+ *
+ * Requests the name server to do a zone transfer so we
+ * find out what hosts it knows about.
+ *
+ * For ListHosts, there are five types of output:
+ * - Internet addresses (default)
+ * - cpu type and operating system (-h option)
+ * - canonical and alias names (-a option)
+ * - well-known service names (-s option)
+ * - ALL records (-d option)
+ * ListHostsByType prints records of the default type or of a speicific
+ * type.
+ *
+ * To see all types of information sorted by name, do the following:
+ * ls -d domain.edu > file
+ * view file
+ *
+ * Results:
+ * SUCCESS the listing was successful.
+ * ERROR the server could not be contacted because
+ * a socket could not be obtained or an error
+ * occured while receiving, or the output file
+ * could not be opened.
+ *
+ *******************************************************************************
+ */
+
+void
+ListHostsByType(string, putToFile)
+ char *string;
+ int putToFile;
+{
+ int i, qtype, result;
+ char *namePtr;
+ char name[NAME_LEN];
+ char option[NAME_LEN];
+
+ /*
+ * Parse the command line. It maybe of the form "ls -t domain"
+ * or "ls -t type domain".
+ */
+
+ i = sscanf(string, " ls -t %s %s", option, name);
+ if (putToFile && i == 2 && name[0] == '>') {
+ i--;
+ }
+ if (i == 2) {
+ qtype = StringToType(option, -1, stderr);
+ if (qtype == -1)
+ return;
+ namePtr = name;
+ } else if (i == 1) {
+ namePtr = option;
+ qtype = queryType;
+ } else {
+ fprintf(stderr, "*** ls: invalid request %s\n",string);
+ return;
+ }
+ result = ListSubr(qtype, namePtr, putToFile ? string : NULL);
+ if (result != SUCCESS)
+ fprintf(stderr, "*** Can't list domain %s: %s\n",
+ namePtr, DecodeError(result));
+}
+
+void
+ListHosts(string, putToFile)
+ char *string;
+ int putToFile;
+{
+ int i, qtype, result;
+ char *namePtr;
+ char name[NAME_LEN];
+ char option[NAME_LEN];
+
+ /*
+ * Parse the command line. It maybe of the form "ls domain",
+ * "ls -X domain".
+ */
+ i = sscanf(string, " ls %s %s", option, name);
+ if (putToFile && i == 2 && name[0] == '>') {
+ i--;
+ }
+ if (i == 2) {
+ if (strcmp("-a", option) == 0) {
+ qtype = T_CNAME;
+ } else if (strcmp("-h", option) == 0) {
+ qtype = T_HINFO;
+ } else if (strcmp("-m", option) == 0) {
+ qtype = T_MX;
+ } else if (strcmp("-p", option) == 0) {
+ qtype = T_PX;
+ } else if (strcmp("-s", option) == 0) {
+ qtype = T_WKS;
+ } else if (strcmp("-d", option) == 0) {
+ qtype = T_ANY;
+ } else {
+ qtype = T_A;
+ }
+ namePtr = name;
+ } else if (i == 1) {
+ namePtr = option;
+ qtype = T_A;
+ } else {
+ fprintf(stderr, "*** ls: invalid request %s\n",string);
+ return;
+ }
+ result = ListSubr(qtype, namePtr, putToFile ? string : NULL);
+ if (result != SUCCESS)
+ fprintf(stderr, "*** Can't list domain %s: %s\n",
+ namePtr, DecodeError(result));
+}
+
+int
+ListSubr(qtype, domain, cmd)
+ int qtype;
+ char *domain;
+ char *cmd;
+{
+ querybuf buf;
+ struct sockaddr_in sin;
+ HEADER *headerPtr;
+ int msglen;
+ int amtToRead;
+ int numRead, n;
+ int numAnswers = 0;
+ int numRecords = 0;
+ int result;
+ int soacnt = 0;
+ int count, done;
+ u_short len;
+ u_char *cp;
+ char dname[2][NAME_LEN];
+ char file[NAME_LEN];
+ static u_char *answer = NULL;
+ static int answerLen = 0;
+ enum {
+ NO_ERRORS,
+ ERR_READING_LEN,
+ ERR_READING_MSG,
+ ERR_PRINTING
+ } error = NO_ERRORS;
+
+ /*
+ * Create a query packet for the requested domain name.
+ */
+ msglen = res_mkquery(QUERY, domain, queryClass, T_AXFR,
+ NULL, 0, 0, buf.qb2, sizeof buf);
+ if (msglen < 0) {
+ if (_res.options & RES_DEBUG) {
+ fprintf(stderr, "*** ls: res_mkquery failed\n");
+ }
+ return (ERROR);
+ }
+
+ bzero((char *)&sin, sizeof(sin));
+ sin.sin_family = AF_INET;
+ sin.sin_port = htons(nsport);
+
+ /*
+ * Check to see if we have the address of the server or the
+ * address of a server who knows about this domain.
+ *
+ * For now, just use the first address in the list.
+ */
+
+ if (defaultPtr->addrList != NULL) {
+ sin.sin_addr = *(struct in_addr *) defaultPtr->addrList[0];
+ } else {
+ sin.sin_addr = *(struct in_addr *)defaultPtr->servers[0]->addrList[0];
+ }
+
+ /*
+ * Set up a virtual circuit to the server.
+ */
+ if ((sockFD = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
+ perror("ls: socket");
+ return(ERROR);
+ }
+ if (connect(sockFD, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
+ int e;
+ if (errno == ECONNREFUSED) {
+ e = NO_RESPONSE;
+ } else {
+ perror("ls: connect");
+ e = ERROR;
+ }
+ (void) close(sockFD);
+ sockFD = -1;
+ return e;
+ }
+
+ /*
+ * Send length & message for zone transfer
+ */
+
+ __putshort(msglen, (u_char *)&len);
+
+ if (write(sockFD, (char *)&len, INT16SZ) != INT16SZ ||
+ write(sockFD, (char *) &buf, msglen) != msglen) {
+ perror("ls: write");
+ (void) close(sockFD);
+ sockFD = -1;
+ return(ERROR);
+ }
+
+ fprintf(stdout,"[%s]\n",
+ (defaultPtr->addrList != NULL) ? defaultPtr->name :
+ defaultPtr->servers[0]->name);
+
+ if (cmd == NULL) {
+ filePtr = stdout;
+ } else {
+ filePtr = OpenFile(cmd, file);
+ if (filePtr == NULL) {
+ fprintf(stderr, "*** Can't open %s for writing\n", file);
+ (void) close(sockFD);
+ sockFD = -1;
+ return(ERROR);
+ }
+ fprintf(filePtr, "> %s\n", cmd);
+ fprintf(filePtr,"[%s]\n",
+ (defaultPtr->addrList != NULL) ? defaultPtr->name :
+ defaultPtr->servers[0]->name);
+ }
+
+#if 0
+ if (qtype == T_CNAME) {
+ fprintf(filePtr, "%-30s", "Alias");
+ } else if (qtype == T_TXT) {
+ fprintf(filePtr, "%-30s", "Key");
+ } else {
+ fprintf(filePtr, "%-30s", "Host or domain name");
+ }
+ switch (qtype) {
+ case T_A:
+ fprintf(filePtr, " %-30s\n", "Internet Address");
+ break;
+ case T_AAAA:
+ fprintf(filePtr, " %-30s\n", "IPv6 Address");
+ break;
+ case T_HINFO:
+ fprintf(filePtr, " %-30s\n", "CPU & OS");
+ break;
+ case T_CNAME:
+ fprintf(filePtr, " %-30s\n", "Canonical Name");
+ break;
+ case T_MX:
+ fprintf(filePtr, " %-30s\n", "Metric & Host");
+ break;
+ case T_PX:
+ fprintf(filePtr, " %-30s\n", "Mapping information");
+ break;
+ case T_AFSDB:
+ fprintf(filePtr, " %-30s\n", "Subtype & Host");
+ break;
+ case T_X25:
+ fprintf(filePtr, " %-30s\n", "X25 Address");
+ break;
+ case T_ISDN:
+ fprintf(filePtr, " %-30s\n", "ISDN Address");
+ break;
+ case T_WKS:
+ fprintf(filePtr, " %-4s %s\n", "Protocol", "Services");
+ break;
+ case T_MB:
+ fprintf(filePtr, " %-30s\n", "Mailbox");
+ break;
+ case T_MG:
+ fprintf(filePtr, " %-30s\n", "Mail Group");
+ break;
+ case T_MR:
+ fprintf(filePtr, " %-30s\n", "Mail Rename");
+ break;
+ case T_MINFO:
+ fprintf(filePtr, " %-30s\n", "Mail List Requests & Errors");
+ break;
+ case T_UINFO:
+ fprintf(filePtr, " %-30s\n", "User Information");
+ break;
+ case T_UID:
+ fprintf(filePtr, " %-30s\n", "User ID");
+ break;
+ case T_GID:
+ fprintf(filePtr, " %-30s\n", "Group ID");
+ break;
+ case T_TXT:
+ fprintf(filePtr, " %-30s\n", "Text");
+ break;
+ case T_RP:
+ fprintf(filePtr, " %-30s\n", "Responsible Person");
+ break;
+ case T_RT:
+ fprintf(filePtr, " %-30s\n", "Router");
+ break;
+ case T_NSAP:
+ fprintf(filePtr, " %-30s\n", "NSAP address");
+ break;
+ case T_NSAP_PTR:
+ fprintf(filePtr, " %-30s\n", "NSAP pointer");
+ break;
+ case T_NS:
+ fprintf(filePtr, " %-30s\n", "Name Servers");
+ break;
+ case T_PTR:
+ fprintf(filePtr, " %-30s\n", "Pointers");
+ break;
+ case T_SOA:
+ fprintf(filePtr, " %-30s\n", "Start of Authority");
+ break;
+ case T_ANY:
+ fprintf(filePtr, " %-30s\n", "Resource Record Info.");
+ break;
+ }
+#endif
+
+
+ dname[0][0] = '\0';
+ for (done = 0; !done; NULL) {
+ unsigned short tmp;
+
+ /*
+ * Read the length of the response.
+ */
+
+ cp = (u_char *)&tmp;
+ amtToRead = INT16SZ;
+ while ((numRead = read(sockFD, cp, amtToRead)) > 0) {
+ cp += numRead;
+ if ((amtToRead -= numRead) <= 0)
+ break;
+ }
+ if (numRead <= 0) {
+ error = ERR_READING_LEN;
+ break;
+ }
+
+ if ((len = _getshort((u_char*)&tmp)) == 0) {
+ break; /* nothing left to read */
+ }
+
+ /*
+ * The server sent too much data to fit the existing buffer --
+ * allocate a new one.
+ */
+ if (len > (u_int)answerLen) {
+ if (answerLen != 0) {
+ free(answer);
+ }
+ answerLen = len;
+ answer = (u_char *)Malloc(answerLen);
+ }
+
+ /*
+ * Read the response.
+ */
+
+ amtToRead = len;
+ cp = answer;
+ while (amtToRead > 0 && (numRead=read(sockFD, cp, amtToRead)) > 0) {
+ cp += numRead;
+ amtToRead -= numRead;
+ }
+ if (numRead <= 0) {
+ error = ERR_READING_MSG;
+ break;
+ }
+
+ result = PrintListInfo(filePtr, answer, cp, qtype, dname[0]);
+ if (result != SUCCESS) {
+ error = ERR_PRINTING;
+ break;
+ }
+ numRecords += htons(((HEADER *)answer)->ancount);
+ numAnswers++;
+ if (cmd != NULL && ((numAnswers % HASH_SIZE) == 0)) {
+ fprintf(stdout, "#");
+ fflush(stdout);
+ }
+ /* Header. */
+ cp = answer + HFIXEDSZ;
+ /* Question. */
+ for (count = ntohs(((HEADER* )answer)->qdcount);
+ count > 0;
+ count--)
+ cp += dn_skipname(cp, answer + len) + QFIXEDSZ;
+ /* Answer. */
+ for (count = ntohs(((HEADER* )answer)->ancount);
+ count > 0;
+ count--) {
+ int type, class, rlen;
+
+ n = dn_expand(answer, answer + len, cp,
+ dname[soacnt], sizeof dname[0]);
+ if (n < 0) {
+ error = ERR_PRINTING;
+ done++;
+ break;
+ }
+ cp += n;
+ GETSHORT(type, cp);
+ GETSHORT(class, cp);
+ cp += INT32SZ; /* ttl */
+ GETSHORT(rlen, cp);
+ cp += rlen;
+ if (type == T_SOA && soacnt++ &&
+ !strcasecmp(dname[0], dname[1])) {
+ done++;
+ break;
+ }
+ }
+ }
+
+ if (cmd != NULL) {
+ fprintf(stdout, "%sReceived %d answer%s (%d record%s).\n",
+ (numAnswers >= HASH_SIZE) ? "\n" : "",
+ numAnswers, (numAnswers != 1) ? "s" : "",
+ numRecords, (numRecords != 1) ? "s" : "");
+ }
+
+ (void) close(sockFD);
+ sockFD = -1;
+ if (cmd != NULL && filePtr != NULL) {
+ fclose(filePtr);
+ filePtr = NULL;
+ }
+
+ switch (error) {
+ case NO_ERRORS:
+ return (SUCCESS);
+
+ case ERR_READING_LEN:
+ return(ERROR);
+
+ case ERR_PRINTING:
+ return(result);
+
+ case ERR_READING_MSG:
+ headerPtr = (HEADER *) answer;
+ fprintf(stderr,"*** ls: error receiving zone transfer:\n");
+ fprintf(stderr,
+ " result: %s, answers = %d, authority = %d, additional = %d\n",
+ _res_resultcodes[headerPtr->rcode],
+ ntohs(headerPtr->ancount), ntohs(headerPtr->nscount),
+ ntohs(headerPtr->arcount));
+ return(ERROR);
+ default:
+ return(ERROR);
+ }
+}
+
+
+/*
+ *******************************************************************************
+ *
+ * PrintListInfo --
+ *
+ * Used by the ListInfo routine to print the answer
+ * received from the name server. Only the desired
+ * information is printed.
+ *
+ * Results:
+ * SUCCESS the answer was printed without a problem.
+ * NO_INFO the answer packet did not contain an answer.
+ * ERROR the answer was malformed.
+ * Misc. errors returned in the packet header.
+ *
+ *******************************************************************************
+ */
+
+#define NAME_FORMAT " %-30s"
+
+static Boolean
+strip_domain(string, domain)
+ char *string, *domain;
+{
+ register char *dot;
+
+ if (*domain != '\0') {
+ dot = string;
+ while ((dot = strchr(dot, '.')) != NULL && strcasecmp(domain, ++dot))
+ ;
+ if (dot != NULL) {
+ dot[-1] = '\0';
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+
+PrintListInfo(file, msg, eom, qtype, domain)
+ FILE *file;
+ u_char *msg, *eom;
+ int qtype;
+ char *domain;
+{
+ register u_char *cp;
+ HEADER *headerPtr;
+ int type, class, dlen, nameLen;
+ u_int32_t ttl;
+ int n, pref, count;
+ struct in_addr inaddr;
+ char name[NAME_LEN];
+ char name2[NAME_LEN];
+ Boolean stripped;
+
+ /*
+ * Read the header fields.
+ */
+ headerPtr = (HEADER *)msg;
+ cp = msg + HFIXEDSZ;
+ if (headerPtr->rcode != NOERROR) {
+ return(headerPtr->rcode);
+ }
+
+ /*
+ * We are looking for info from answer resource records.
+ * If there aren't any, return with an error. We assume
+ * there aren't any question records.
+ */
+
+ if (ntohs(headerPtr->ancount) == 0) {
+ return(NO_INFO);
+ }
+ for (n = ntohs(headerPtr->qdcount); n > 0; n--) {
+ nameLen = dn_skipname(cp, eom);
+ if (nameLen < 0)
+ return (ERROR);
+ cp += nameLen + QFIXEDSZ;
+ }
+ for (count = ntohs(headerPtr->ancount); count > 0; count--) {
+ nameLen = dn_expand(msg, eom, cp, name, sizeof name);
+ if (nameLen < 0)
+ return (ERROR);
+ cp += nameLen;
+
+ type = _getshort((u_char*)cp);
+ cp += INT16SZ;
+
+ if (!(type == qtype || qtype == T_ANY) &&
+ !((type == T_NS || type == T_PTR) && qtype == T_A))
+ return(SUCCESS);
+
+ class = _getshort((u_char*)cp);
+ cp += INT16SZ;
+ ttl = _getlong((u_char*)cp);
+ cp += INT32SZ;
+ dlen = _getshort((u_char*)cp);
+ cp += INT16SZ;
+
+ if (name[0] == 0)
+ strcpy(name, "(root)");
+
+ /* Strip the domain name from the data, if desired. */
+ stripped = FALSE;
+ if ((_res.options & RES_DEBUG) == 0) {
+ if (type != T_SOA) {
+ stripped = strip_domain(name, domain);
+ }
+ }
+ if (!stripped && nameLen < sizeof(name)-1) {
+ strcat(name, ".");
+ }
+
+ fprintf(file, NAME_FORMAT, name);
+
+ if (qtype == T_ANY) {
+ if (_res.options & RES_DEBUG) {
+ fprintf(file,"\t%lu %-5s", ttl, p_class(queryClass));
+ }
+ fprintf(file," %-5s", p_type(type));
+ }
+
+ /* XXX merge this into debug.c's print routines */
+
+ switch (type) {
+ case T_A:
+ if (class == C_IN) {
+ bcopy(cp, (char *)&inaddr, INADDRSZ);
+ if (dlen == 4) {
+ fprintf(file," %s", inet_ntoa(inaddr));
+ } else if (dlen == 7) {
+ fprintf(file," %s", inet_ntoa(inaddr));
+ fprintf(file," (%d, %d)", cp[4],(cp[5] << 8) + cp[6]);
+ } else
+ fprintf(file, " (dlen = %d?)", dlen);
+ }
+ cp += dlen;
+ break;
+
+ case T_CNAME:
+ case T_MB:
+ case T_MG:
+ case T_MR:
+ nameLen = dn_expand(msg, eom, cp, name2, sizeof name2);
+ if (nameLen < 0) {
+ fprintf(file, " ***\n");
+ return (ERROR);
+ }
+ fprintf(file, " %s", name2);
+ cp += nameLen;
+ break;
+
+ case T_NS:
+ case T_PTR:
+ case T_NSAP_PTR:
+ putc(' ', file);
+ if (qtype != T_ANY)
+ fprintf(file,"%s = ", type == T_PTR ? "host" : "server");
+ cp = (u_char *)Print_cdname2(cp, msg, eom, file);
+ if (!cp) {
+ fprintf(file, " ***\n");
+ return (ERROR);
+ }
+ break;
+
+ case T_HINFO:
+ case T_ISDN:
+ {
+ u_char *cp2 = cp + dlen;
+ if (n = *cp++) {
+ (void)sprintf(name,"%.*s", n, cp);
+ fprintf(file," %-10s", name);
+ cp += n;
+ } else {
+ fprintf(file," %-10s", " ");
+ }
+ if (cp == cp2)
+ break;
+ if (n = *cp++) {
+ fprintf(file," %.*s", n, cp);
+ cp += n;
+ }
+ }
+ break;
+
+ case T_SOA:
+ nameLen = dn_expand(msg, eom, cp, name2, sizeof name2);
+ if (nameLen < 0) {
+ fprintf(file, " ***\n");
+ return (ERROR);
+ }
+ cp += nameLen;
+ fprintf(file, " %s", name2);
+ nameLen = dn_expand(msg, eom, cp, name2, sizeof name2);
+ if (nameLen < 0) {
+ fprintf(file, " ***\n");
+ return (ERROR);
+ }
+ cp += nameLen;
+ fprintf(file, " %s. (", name2);
+ for (n = 0; n < 5; n++) {
+ u_int32_t u;
+
+ u = _getlong((u_char*)cp);
+ cp += INT32SZ;
+ fprintf(file,"%s%lu", n? " " : "", u);
+ }
+ fprintf(file, ")");
+ break;
+
+ case T_MX:
+ case T_AFSDB:
+ case T_RT:
+ pref = _getshort((u_char*)cp);
+ cp += INT16SZ;
+ fprintf(file," %-3d ",pref);
+ nameLen = dn_expand(msg, eom, cp, name2, sizeof name2);
+ if (nameLen < 0) {
+ fprintf(file, " ***\n");
+ return (ERROR);
+ }
+ fprintf(file, " %s", name2);
+ cp += nameLen;
+ break;
+
+ case T_PX:
+ pref = _getshort((u_char*)cp);
+ cp += INT16SZ;
+ fprintf(file," %-3d ",pref);
+ nameLen = dn_expand(msg, eom, cp, name2, sizeof name2);
+ if (nameLen < 0) {
+ fprintf(file, " ***\n");
+ return (ERROR);
+ }
+ fprintf(file, " %s", name2);
+ cp += nameLen;
+ nameLen = dn_expand(msg, eom, cp, name2, sizeof name2);
+ if (nameLen < 0) {
+ fprintf(file, " ***\n");
+ return (ERROR);
+ }
+ fprintf(file, " %s", name2);
+ cp += nameLen;
+ break;
+
+ case T_TXT:
+ case T_X25:
+ {
+ u_char *cp2 = cp + dlen;
+ int c;
+
+ (void) fputs(" \"", file);
+ while (cp < cp2)
+ if (n = (unsigned char) *cp++)
+ for (c = n; c > 0 && cp < cp2; c--)
+ if (strchr("\n\"\\", *cp)) {
+ (void) putc('\\', file);
+ (void) putc(*cp++, file);
+ } else
+ (void) putc(*cp++, file);
+ (void) putc('"', file);
+ }
+ break;
+
+ case T_NSAP:
+ fprintf(file, " %s", inet_nsap_ntoa(dlen, cp, NULL));
+ cp += dlen;
+ break;
+
+ case T_AAAA: {
+ char t[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"];
+
+ fprintf(file, " %s", inet_ntop(AF_INET6, cp, t, sizeof t));
+ break;
+ }
+
+ case T_MINFO:
+ case T_RP:
+ (void) putc(' ', file);
+ cp = (u_char *)Print_cdname(cp, msg, eom, file);
+ if (!cp) {
+ fprintf(file, " ***\n");
+ return (ERROR);
+ }
+ fprintf(file, " ");
+ cp = (u_char *)Print_cdname(cp, msg, eom, file);
+ if (!cp) {
+ fprintf(file, " ***\n");
+ return (ERROR);
+ }
+ break;
+
+ case T_UINFO:
+ fprintf(file, " %s", cp);
+ cp += dlen;
+ break;
+
+ case T_UID:
+ case T_GID:
+ fprintf(file, " %lu", _getlong((u_char*)cp));
+ cp += dlen;
+ break;
+
+ case T_WKS:
+ if (class == C_IN) {
+ struct protoent *pp;
+ struct servent *ss;
+ u_short port;
+
+ cp += 4; /* skip inet address */
+ dlen -= 4;
+
+ setprotoent(1);
+ setservent(1);
+ n = *cp & 0377;
+ pp = getprotobynumber(n);
+ if (pp == 0)
+ fprintf(file," %-3d ", n);
+ else
+ fprintf(file," %-3s ", pp->p_name);
+ cp++; dlen--;
+
+ port = 0;
+ while (dlen-- > 0) {
+ n = *cp++;
+ do {
+ if (n & 0200) {
+ ss = getservbyport((int)htons(port),
+ pp->p_name);
+ if (ss == 0)
+ fprintf(file," %u", port);
+ else
+ fprintf(file," %s", ss->s_name);
+ }
+ n <<= 1;
+ } while (++port & 07);
+ }
+ endprotoent();
+ endservent();
+ }
+ break;
+ }
+ fprintf(file,"\n");
+ }
+ return(SUCCESS);
+}
+
+
+/*
+ *******************************************************************************
+ *
+ * ViewList --
+ *
+ * A hack to view the output of the ls command in sorted
+ * order using more.
+ *
+ *******************************************************************************
+ */
+
+ViewList(string)
+ char *string;
+{
+ char file[PATH_MAX];
+ char command[PATH_MAX];
+
+ sscanf(string, " view %s", file);
+ (void)sprintf(command, "grep \"^ \" %s | sort | %s", file, pager);
+ system(command);
+}
+
+/*
+ *******************************************************************************
+ *
+ * Finger --
+ *
+ * Connects with the finger server for the current host
+ * to request info on the specified person (long form)
+ * who is on the system (short form).
+ *
+ * Results:
+ * SUCCESS the finger server was contacted.
+ * ERROR the server could not be contacted because
+ * a socket could not be obtained or connected
+ * to or the service could not be found.
+ *
+ *******************************************************************************
+ */
+
+Finger(string, putToFile)
+ char *string;
+ int putToFile;
+{
+ struct servent *sp;
+ struct sockaddr_in sin;
+ register FILE *f;
+ register int c;
+ register int lastc;
+ char name[NAME_LEN];
+ char file[NAME_LEN];
+
+ /*
+ * We need a valid current host info to get an inet address.
+ */
+ if (!curHostValid) {
+ fprintf(stderr, "Finger: no current host defined.\n");
+ return (ERROR);
+ }
+
+ if (sscanf(string, " finger %s", name) == 1) {
+ if (putToFile && (name[0] == '>')) {
+ name[0] = '\0';
+ }
+ } else {
+ name[0] = '\0';
+ }
+
+ sp = getservbyname("finger", "tcp");
+ if (sp == 0) {
+ fprintf(stderr, "Finger: unknown service\n");
+ return (ERROR);
+ }
+
+ bzero((char *)&sin, sizeof(sin));
+ sin.sin_family = curHostInfo.addrType;
+ sin.sin_port = sp->s_port;
+ bcopy(curHostInfo.addrList[0], (char *)&sin.sin_addr,
+ curHostInfo.addrLen);
+
+ /*
+ * Set up a virtual circuit to the host.
+ */
+
+ sockFD = socket(curHostInfo.addrType, SOCK_STREAM, 0);
+ if (sockFD < 0) {
+ fflush(stdout);
+ perror("finger: socket");
+ return (ERROR);
+ }
+
+ if (connect(sockFD, (struct sockaddr *)&sin, sizeof (sin)) < 0) {
+ fflush(stdout);
+ perror("finger: connect");
+ close(sockFD);
+ sockFD = -1;
+ return (ERROR);
+ }
+
+ if (!putToFile) {
+ filePtr = stdout;
+ } else {
+ filePtr = OpenFile(string, file);
+ if (filePtr == NULL) {
+ fprintf(stderr, "*** Can't open %s for writing\n", file);
+ close(sockFD);
+ sockFD = -1;
+ return(ERROR);
+ }
+ fprintf(filePtr,"> %s\n", string);
+ }
+ fprintf(filePtr, "[%s]\n", curHostInfo.name);
+
+ if (name[0] != '\0') {
+ write(sockFD, "/W ", 3);
+ }
+ write(sockFD, name, strlen(name));
+ write(sockFD, "\r\n", 2);
+ f = fdopen(sockFD, "r");
+ lastc = '\n';
+ while ((c = getc(f)) != EOF) {
+ switch (c) {
+ case 0210:
+ case 0211:
+ case 0212:
+ case 0214:
+ c -= 0200;
+ break;
+ case 0215:
+ c = '\n';
+ break;
+ }
+ putc(lastc = c, filePtr);
+ }
+ if (lastc != '\n') {
+ putc('\n', filePtr);
+ }
+ putc('\n', filePtr);
+
+ close(sockFD);
+ sockFD = -1;
+
+ if (putToFile) {
+ fclose(filePtr);
+ filePtr = NULL;
+ }
+ return (SUCCESS);
+}
+
+ListHost_close()
+{
+ if (sockFD != -1) {
+ (void) close(sockFD);
+ sockFD = -1;
+ }
+}
diff --git a/contrib/bind/tools/nslookup/main.c b/contrib/bind/tools/nslookup/main.c
new file mode 100644
index 0000000..fb674b5
--- /dev/null
+++ b/contrib/bind/tools/nslookup/main.c
@@ -0,0 +1,1119 @@
+/*
+ * ++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--
+ */
+
+#ifndef lint
+char copyright[] =
+"@(#) Copyright (c) 1985,1989 Regents of the University of California.\n\
+ All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)main.c 5.42 (Berkeley) 3/3/91";
+static char rcsid[] = "$Id: main.c,v 8.3 1996/06/02 08:20:41 vixie Exp $";
+#endif /* not lint */
+
+/*
+ ******************************************************************************
+ *
+ * main.c --
+ *
+ * Main routine and some action routines for the name server
+ * lookup program.
+ *
+ * Andrew Cherenson
+ * U.C. Berkeley Computer Science Div.
+ * CS298-26, Fall 1985
+ *
+ ******************************************************************************
+ */
+
+#include <sys/param.h>
+#include <netdb.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <arpa/inet.h>
+#include <resolv.h>
+#include <signal.h>
+#include <setjmp.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <errno.h>
+#include <limits.h>
+#include "res.h"
+#include "pathnames.h"
+#include "../../conf/portability.h"
+
+
+/*
+ * Name of a top-level name server. Can be changed with
+ * the "set root" command.
+ */
+
+#ifndef ROOT_SERVER
+#define ROOT_SERVER "a.root-servers.net."
+#endif
+char rootServerName[NAME_LEN] = ROOT_SERVER;
+
+
+/*
+ * Import the state information from the resolver library.
+ */
+
+extern struct __res_state _res;
+
+
+/*
+ * Info about the most recently queried host.
+ */
+
+HostInfo curHostInfo;
+int curHostValid = FALSE;
+
+
+/*
+ * Info about the default name server.
+ */
+
+HostInfo *defaultPtr = NULL;
+char defaultServer[NAME_LEN];
+struct in_addr defaultAddr;
+
+
+/*
+ * Initial name server query type is Address.
+ */
+
+int queryType = T_A;
+int queryClass = C_IN;
+
+/*
+ * Stuff for Interrupt (control-C) signal handler.
+ */
+
+extern SIG_FN IntrHandler();
+FILE *filePtr;
+jmp_buf env;
+
+
+/*
+ * Browser command for help and view.
+ */
+char *pager;
+
+static void CvtAddrToPtr();
+static void ReadRC();
+
+
+/*
+ ******************************************************************************
+ *
+ * main --
+ *
+ * Initializes the resolver library and determines the address
+ * of the initial name server. The yylex routine is used to
+ * read and perform commands.
+ *
+ ******************************************************************************
+ */
+
+main(argc, argv)
+ int argc;
+ char **argv;
+{
+ char *wantedHost = NULL;
+ Boolean useLocalServer;
+ int result;
+ int i;
+ struct hostent *hp;
+
+ /*
+ * Initialize the resolver library routines.
+ */
+
+ if (res_init() == -1) {
+ fprintf(stderr,"*** Can't initialize resolver.\n");
+ exit(1);
+ }
+
+ /*
+ * Allocate space for the default server's host info and
+ * find the server's address and name. If the resolver library
+ * already has some addresses for a potential name server,
+ * then use them. Otherwise, see if the current host has a server.
+ * Command line arguments may override the choice of initial server.
+ */
+
+ defaultPtr = (HostInfo *) Calloc(1, sizeof(HostInfo));
+
+ /*
+ * Parse the arguments:
+ * no args = go into interactive mode, use default host as server
+ * 1 arg = use as host name to be looked up, default host will be server
+ * non-interactive mode
+ * 2 args = 1st arg:
+ * if it is '-', then
+ * ignore but go into interactive mode
+ * else
+ * use as host name to be looked up,
+ * go into non-interactive mode
+ * 2nd arg: name or inet address of server
+ *
+ * "Set" options are specified with a leading - and must come before
+ * any arguments. For example, to find the well-known services for
+ * a host, type "nslookup -query=wks host"
+ */
+
+ ReadRC(); /* look for options file */
+
+ ++argv; --argc; /* skip prog name */
+
+ while (argc && *argv[0] == '-' && argv[0][1]) {
+ (void) SetOption (&(argv[0][1]));
+ ++argv; --argc;
+ }
+ if (argc > 2) {
+ Usage();
+ }
+ if (argc && *argv[0] != '-') {
+ wantedHost = *argv; /* name of host to be looked up */
+ }
+
+ useLocalServer = FALSE;
+ if (argc == 2) {
+ struct in_addr addr;
+
+ /*
+ * Use an explicit name server. If the hostname lookup fails,
+ * default to the server(s) in resolv.conf.
+ */
+
+ if (inet_aton(*++argv, &addr)) {
+ _res.nscount = 1;
+ _res.nsaddr.sin_addr = addr;
+ } else {
+ hp = gethostbyname(*argv);
+ if (hp == NULL) {
+ fprintf(stderr, "*** Can't find server address for '%s': ",
+ *argv);
+ herror((char *)NULL);
+ fputc('\n', stderr);
+ } else {
+ for (i = 0; i < MAXNS && hp->h_addr_list[i] != NULL; i++) {
+ bcopy(hp->h_addr_list[i],
+ (char *)&_res.nsaddr_list[i].sin_addr,
+ hp->h_length);
+ }
+ _res.nscount = i;
+ }
+ }
+ }
+
+
+ if (_res.nscount == 0 || useLocalServer) {
+ LocalServer(defaultPtr);
+ } else {
+ for (i = 0; i < _res.nscount; i++) {
+ if (_res.nsaddr_list[i].sin_addr.s_addr == INADDR_ANY) {
+ LocalServer(defaultPtr);
+ break;
+ } else {
+ result = GetHostInfoByAddr(&(_res.nsaddr_list[i].sin_addr),
+ &(_res.nsaddr_list[i].sin_addr),
+ defaultPtr);
+ if (result != SUCCESS) {
+ fprintf(stderr,
+ "*** Can't find server name for address %s: %s\n",
+ inet_ntoa(_res.nsaddr_list[i].sin_addr),
+ DecodeError(result));
+ } else {
+ defaultAddr = _res.nsaddr_list[i].sin_addr;
+ break;
+ }
+ }
+ }
+
+ /*
+ * If we have exhausted the list, tell the user about the
+ * command line argument to specify an address.
+ */
+
+ if (i == _res.nscount) {
+ fprintf(stderr, "*** Default servers are not available\n");
+ exit(1);
+ }
+
+ }
+ strcpy(defaultServer, defaultPtr->name);
+
+
+#ifdef DEBUG
+#ifdef DEBUG2
+ _res.options |= RES_DEBUG2;
+#endif
+ _res.options |= RES_DEBUG;
+ _res.retry = 2;
+#endif /* DEBUG */
+
+ /*
+ * If we're in non-interactive mode, look up the wanted host and quit.
+ * Otherwise, print the initial server's name and continue with
+ * the initialization.
+ */
+
+ if (wantedHost != (char *) NULL) {
+ LookupHost(wantedHost, 0);
+ } else {
+ PrintHostInfo(stdout, "Default Server:", defaultPtr);
+
+ pager = getenv("PAGER");
+ if (pager == NULL) {
+ pager = _PATH_PAGERCMD;
+ }
+
+ /*
+ * Setup the environment to allow the interrupt handler to return here.
+ */
+
+ (void) setjmp(env);
+
+ /*
+ * Return here after a longjmp.
+ */
+
+ signal(SIGINT, IntrHandler);
+ signal(SIGPIPE, SIG_IGN);
+
+ /*
+ * Read and evaluate commands. The commands are described in commands.l
+ * Yylex returns 0 when ^D or 'exit' is typed.
+ */
+
+ printf("> ");
+ fflush(stdout);
+ while(yylex()) {
+ printf("> ");
+ fflush(stdout);
+ }
+ }
+ exit(0);
+}
+
+
+LocalServer(defaultPtr)
+ HostInfo *defaultPtr;
+{
+ char hostName[NAME_LEN];
+
+ (void) gethostname(hostName, sizeof(hostName));
+
+ defaultAddr.s_addr = htonl(INADDR_ANY);
+ (void) GetHostInfoByName(&defaultAddr, C_IN, T_A,
+ "0.0.0.0", defaultPtr, 1);
+ free(defaultPtr->name);
+ defaultPtr->name = Calloc(1, sizeof(hostName)+1);
+ strcpy(defaultPtr->name, hostName);
+}
+
+
+/*
+ ******************************************************************************
+ *
+ * Usage --
+ *
+ * Lists the proper methods to run the program and exits.
+ *
+ ******************************************************************************
+ */
+
+Usage()
+{
+ fprintf(stderr, "Usage:\n");
+ fprintf(stderr,
+" nslookup [-opt ...] # interactive mode using default server\n");
+ fprintf(stderr,
+" nslookup [-opt ...] - server # interactive mode using 'server'\n");
+ fprintf(stderr,
+" nslookup [-opt ...] host # just look up 'host' using default server\n");
+ fprintf(stderr,
+" nslookup [-opt ...] host server # just look up 'host' using 'server'\n");
+ exit(1);
+}
+
+/*
+ ******************************************************************************
+ *
+ * IsAddr --
+ *
+ * Returns TRUE if the string looks like an Internet address.
+ * A string with a trailing dot is not an address, even if it looks
+ * like one.
+ *
+ ******************************************************************************
+ */
+
+Boolean
+IsAddr(host, addrPtr)
+ char *host;
+ struct in_addr *addrPtr; /* If return TRUE, contains IP address */
+{
+ register char *cp;
+
+ if (isdigit(host[0])) {
+ /* Make sure it has only digits and dots. */
+ for (cp = host; *cp; ++cp) {
+ if (!isdigit(*cp) && *cp != '.')
+ return FALSE;
+ }
+ /* If it has a trailing dot, don't treat it as an address. */
+ if (*--cp != '.') {
+ return inet_aton(host, addrPtr);
+ }
+ }
+ return FALSE;
+}
+
+
+/*
+ ******************************************************************************
+ *
+ * SetDefaultServer --
+ *
+ * Changes the default name server to the one specified by
+ * the first argument. The command "server name" uses the current
+ * default server to lookup the info for "name". The command
+ * "lserver name" uses the original server to lookup "name".
+ *
+ * Side effects:
+ * This routine will cause a core dump if the allocation requests fail.
+ *
+ * Results:
+ * SUCCESS The default server was changed successfully.
+ * NONAUTH The server was changed but addresses of
+ * other servers who know about the requested server
+ * were returned.
+ * Errors No info about the new server was found or
+ * requests to the current server timed-out.
+ *
+ ******************************************************************************
+ */
+
+int
+SetDefaultServer(string, local)
+ char *string;
+ Boolean local;
+{
+ register HostInfo *newDefPtr;
+ struct in_addr *servAddrPtr;
+ struct in_addr addr;
+ char newServer[NAME_LEN];
+ int result;
+ int i;
+
+ /*
+ * Parse the command line. It maybe of the form "server name",
+ * "lserver name" or just "name".
+ */
+
+ if (local) {
+ i = sscanf(string, " lserver %s", newServer);
+ } else {
+ i = sscanf(string, " server %s", newServer);
+ }
+ if (i != 1) {
+ i = sscanf(string, " %s", newServer);
+ if (i != 1) {
+ fprintf(stderr,"SetDefaultServer: invalid name: %s\n", string);
+ return(ERROR);
+ }
+ }
+
+ /*
+ * Allocate space for a HostInfo variable for the new server. Don't
+ * overwrite the old HostInfo struct because info about the new server
+ * might not be found and we need to have valid default server info.
+ */
+
+ newDefPtr = (HostInfo *) Calloc(1, sizeof(HostInfo));
+
+
+ /*
+ * A 'local' lookup uses the original server that the program was
+ * initialized with.
+ *
+ * Check to see if we have the address of the server or the
+ * address of a server who knows about this domain.
+ * XXX For now, just use the first address in the list.
+ */
+
+ if (local) {
+ servAddrPtr = &defaultAddr;
+ } else if (defaultPtr->addrList != NULL) {
+ servAddrPtr = (struct in_addr *) defaultPtr->addrList[0];
+ } else {
+ servAddrPtr = (struct in_addr *) defaultPtr->servers[0]->addrList[0];
+ }
+
+ result = ERROR;
+ if (IsAddr(newServer, &addr)) {
+ result = GetHostInfoByAddr(servAddrPtr, &addr, newDefPtr);
+ /* If we can't get the name, fall through... */
+ }
+ if (result != SUCCESS && result != NONAUTH) {
+ result = GetHostInfoByName(servAddrPtr, C_IN, T_A,
+ newServer, newDefPtr, 1);
+ }
+
+ /* If we ask for an A record and get none back, but get an NS
+ record for the NS server, this is the NONAUTH case.
+ We must check whether we got an IP address for the NS
+ server or not. */
+ if ((result == SUCCESS || result == NONAUTH) &&
+ ((newDefPtr->addrList && newDefPtr->addrList[0] != 0) ||
+ (newDefPtr->servers && newDefPtr->servers[0] &&
+ newDefPtr->servers[0]->addrList[0] != 0))) {
+ /*
+ * Found info about the new server. Free the resources for
+ * the old server.
+ */
+
+ FreeHostInfoPtr(defaultPtr);
+ free((char *)defaultPtr);
+ defaultPtr = newDefPtr;
+ strcpy(defaultServer, defaultPtr->name);
+ PrintHostInfo(stdout, "Default Server:", defaultPtr);
+ return(SUCCESS);
+ } else {
+ fprintf(stderr, "*** Can't find address for server %s: %s\n",
+ newServer, DecodeError(result));
+ free((char *)newDefPtr);
+
+ return(result);
+ }
+}
+
+/*
+ ******************************************************************************
+ *
+ * DoLoookup --
+ *
+ * Common subroutine for LookupHost and LookupHostWithServer.
+ *
+ * Results:
+ * SUCCESS - the lookup was successful.
+ * Misc. Errors - an error message is printed if the lookup failed.
+ *
+ ******************************************************************************
+ */
+
+static int
+DoLookup(host, servPtr, serverName)
+ char *host;
+ HostInfo *servPtr;
+ char *serverName;
+{
+ int result;
+ struct in_addr *servAddrPtr;
+ struct in_addr addr;
+
+ /* Skip escape character */
+ if (host[0] == '\\')
+ host++;
+
+ /*
+ * If the user gives us an address for an address query,
+ * silently treat it as a PTR query. If the query type is already
+ * PTR, then convert the address into the in-addr.arpa format.
+ *
+ * Use the address of the server if it exists, otherwise use the
+ * address of a server who knows about this domain.
+ * XXX For now, just use the first address in the list.
+ */
+
+ if (servPtr->addrList != NULL) {
+ servAddrPtr = (struct in_addr *) servPtr->addrList[0];
+ } else {
+ servAddrPtr = (struct in_addr *) servPtr->servers[0]->addrList[0];
+ }
+
+ /*
+ * RFC1123 says we "SHOULD check the string syntactically for a
+ * dotted-decimal number before looking it up [...]" (p. 13).
+ */
+ if (queryType == T_A && IsAddr(host, &addr)) {
+ result = GetHostInfoByAddr(servAddrPtr, &addr, &curHostInfo);
+ } else {
+ if (queryType == T_PTR) {
+ CvtAddrToPtr(host);
+ }
+ result = GetHostInfoByName(servAddrPtr, queryClass, queryType, host,
+ &curHostInfo, 0);
+ }
+
+ switch (result) {
+ case SUCCESS:
+ /*
+ * If the query was for an address, then the &curHostInfo
+ * variable can be used by Finger.
+ * There's no need to print anything for other query types
+ * because the info has already been printed.
+ */
+ if (queryType == T_A) {
+ curHostValid = TRUE;
+ PrintHostInfo(filePtr, "Name:", &curHostInfo);
+ }
+ break;
+
+ /*
+ * No Authoritative answer was available but we got names
+ * of servers who know about the host.
+ */
+ case NONAUTH:
+ PrintHostInfo(filePtr, "Name:", &curHostInfo);
+ break;
+
+ case NO_INFO:
+ fprintf(stderr, "*** No %s (%s) records available for %s\n",
+ DecodeType(queryType), p_type(queryType), host);
+ break;
+
+ case TIME_OUT:
+ fprintf(stderr, "*** Request to %s timed-out\n", serverName);
+ break;
+
+ default:
+ fprintf(stderr, "*** %s can't find %s: %s\n", serverName, host,
+ DecodeError(result));
+ }
+ return result;
+}
+
+/*
+ ******************************************************************************
+ *
+ * LookupHost --
+ *
+ * Asks the default name server for information about the
+ * specified host or domain. The information is printed
+ * if the lookup was successful.
+ *
+ * Results:
+ * ERROR - the output file could not be opened.
+ * + results of DoLookup
+ *
+ ******************************************************************************
+ */
+
+int
+LookupHost(string, putToFile)
+ char *string;
+ Boolean putToFile;
+{
+ char host[NAME_LEN];
+ char file[PATH_MAX];
+ int result;
+
+ /*
+ * Invalidate the current host information to prevent Finger
+ * from using bogus info.
+ */
+
+ curHostValid = FALSE;
+
+ /*
+ * Parse the command string into the host and
+ * optional output file name.
+ *
+ */
+
+ sscanf(string, " %s", host); /* removes white space */
+ if (!putToFile) {
+ filePtr = stdout;
+ } else {
+ filePtr = OpenFile(string, file);
+ if (filePtr == NULL) {
+ fprintf(stderr, "*** Can't open %s for writing\n", file);
+ return(ERROR);
+ }
+ fprintf(filePtr,"> %s\n", string);
+ }
+
+ PrintHostInfo(filePtr, "Server:", defaultPtr);
+
+ result = DoLookup(host, defaultPtr, defaultServer);
+
+ if (putToFile) {
+ fclose(filePtr);
+ filePtr = NULL;
+ }
+ return(result);
+}
+
+/*
+ ******************************************************************************
+ *
+ * LookupHostWithServer --
+ *
+ * Asks the name server specified in the second argument for
+ * information about the host or domain specified in the first
+ * argument. The information is printed if the lookup was successful.
+ *
+ * Address info about the requested name server is obtained
+ * from the default name server. This routine will return an
+ * error if the default server doesn't have info about the
+ * requested server. Thus an error return status might not
+ * mean the requested name server doesn't have info about the
+ * requested host.
+ *
+ * Comments from LookupHost apply here, too.
+ *
+ * Results:
+ * ERROR - the output file could not be opened.
+ * + results of DoLookup
+ *
+ ******************************************************************************
+ */
+
+int
+LookupHostWithServer(string, putToFile)
+ char *string;
+ Boolean putToFile;
+{
+ char file[PATH_MAX];
+ char host[NAME_LEN];
+ char server[NAME_LEN];
+ int result;
+ static HostInfo serverInfo;
+
+ curHostValid = FALSE;
+
+ sscanf(string, " %s %s", host, server);
+ if (!putToFile) {
+ filePtr = stdout;
+ } else {
+ filePtr = OpenFile(string, file);
+ if (filePtr == NULL) {
+ fprintf(stderr, "*** Can't open %s for writing\n", file);
+ return(ERROR);
+ }
+ fprintf(filePtr,"> %s\n", string);
+ }
+
+ result = GetHostInfoByName(
+ defaultPtr->addrList ?
+ (struct in_addr *) defaultPtr->addrList[0] :
+ (struct in_addr *) defaultPtr->servers[0]->addrList[0],
+ C_IN, T_A, server, &serverInfo, 1);
+
+ if (result != SUCCESS) {
+ fprintf(stderr,"*** Can't find address for server %s: %s\n", server,
+ DecodeError(result));
+ } else {
+ PrintHostInfo(filePtr, "Server:", &serverInfo);
+
+ result = DoLookup(host, &serverInfo, server);
+ }
+ if (putToFile) {
+ fclose(filePtr);
+ filePtr = NULL;
+ }
+ return(result);
+}
+
+/*
+ ******************************************************************************
+ *
+ * SetOption --
+ *
+ * This routine is used to change the state information
+ * that affect the lookups. The command format is
+ * set keyword[=value]
+ * Most keywords can be abbreviated. Parsing is very simplistic--
+ * A value must not be separated from its keyword by white space.
+ *
+ * Valid keywords: Meaning:
+ * all lists current values of options.
+ * ALL lists current values of options, including
+ * hidden options.
+ * [no]d2 turn on/off extra debugging mode.
+ * [no]debug turn on/off debugging mode.
+ * [no]defname use/don't use default domain name.
+ * [no]search use/don't use domain search list.
+ * domain=NAME set default domain name to NAME.
+ * [no]ignore ignore/don't ignore trunc. errors.
+ * query=value set default query type to value,
+ * value is one of the query types in RFC883
+ * without the leading T_. (e.g., A, HINFO)
+ * [no]recurse use/don't use recursive lookup.
+ * retry=# set number of retries to #.
+ * root=NAME change root server to NAME.
+ * time=# set timeout length to #.
+ * [no]vc use/don't use virtual circuit.
+ * port TCP/UDP port to server.
+ *
+ * Deprecated:
+ * [no]primary use/don't use primary server.
+ *
+ * Results:
+ * SUCCESS the command was parsed correctly.
+ * ERROR the command was not parsed correctly.
+ *
+ ******************************************************************************
+ */
+
+int
+SetOption(option)
+ register char *option;
+{
+ char type[NAME_LEN];
+ char *ptr;
+ int tmp;
+
+ while (isspace(*option))
+ ++option;
+ if (strncmp (option, "set ", 4) == 0)
+ option += 4;
+ while (isspace(*option))
+ ++option;
+
+ if (*option == 0) {
+ fprintf(stderr, "*** Invalid set command\n");
+ return(ERROR);
+ } else {
+ if (strncmp(option, "all", 3) == 0) {
+ ShowOptions();
+ } else if (strncmp(option, "ALL", 3) == 0) {
+ ShowOptions();
+ } else if (strncmp(option, "d2", 2) == 0) { /* d2 (more debug) */
+ _res.options |= (RES_DEBUG | RES_DEBUG2);
+ } else if (strncmp(option, "nod2", 4) == 0) {
+ _res.options &= ~RES_DEBUG2;
+ printf("d2 mode disabled; still in debug mode\n");
+ } else if (strncmp(option, "def", 3) == 0) { /* defname */
+ _res.options |= RES_DEFNAMES;
+ } else if (strncmp(option, "nodef", 5) == 0) {
+ _res.options &= ~RES_DEFNAMES;
+ } else if (strncmp(option, "do", 2) == 0) { /* domain */
+ ptr = strchr(option, '=');
+ if (ptr != NULL) {
+ sscanf(++ptr, "%s", _res.defdname);
+ res_re_init();
+ }
+ } else if (strncmp(option, "deb", 1) == 0) { /* debug */
+ _res.options |= RES_DEBUG;
+ } else if (strncmp(option, "nodeb", 5) == 0) {
+ _res.options &= ~(RES_DEBUG | RES_DEBUG2);
+ } else if (strncmp(option, "ig", 2) == 0) { /* ignore */
+ _res.options |= RES_IGNTC;
+ } else if (strncmp(option, "noig", 4) == 0) {
+ _res.options &= ~RES_IGNTC;
+ } else if (strncmp(option, "po", 2) == 0) { /* port */
+ ptr = strchr(option, '=');
+ if (ptr != NULL) {
+ sscanf(++ptr, "%hu", &nsport);
+ }
+#ifdef deprecated
+ } else if (strncmp(option, "pri", 3) == 0) { /* primary */
+ _res.options |= RES_PRIMARY;
+ } else if (strncmp(option, "nopri", 5) == 0) {
+ _res.options &= ~RES_PRIMARY;
+#endif
+ } else if (strncmp(option, "q", 1) == 0 || /* querytype */
+ strncmp(option, "ty", 2) == 0) { /* type */
+ ptr = strchr(option, '=');
+ if (ptr != NULL) {
+ sscanf(++ptr, "%s", type);
+ queryType = StringToType(type, queryType, stderr);
+ }
+ } else if (strncmp(option, "cl", 2) == 0) { /* query class */
+ ptr = strchr(option, '=');
+ if (ptr != NULL) {
+ sscanf(++ptr, "%s", type);
+ queryClass = StringToClass(type, queryClass, stderr);
+ }
+ } else if (strncmp(option, "rec", 3) == 0) { /* recurse */
+ _res.options |= RES_RECURSE;
+ } else if (strncmp(option, "norec", 5) == 0) {
+ _res.options &= ~RES_RECURSE;
+ } else if (strncmp(option, "ret", 3) == 0) { /* retry */
+ ptr = strchr(option, '=');
+ if (ptr != NULL) {
+ sscanf(++ptr, "%d", &tmp);
+ if (tmp >= 0) {
+ _res.retry = tmp;
+ }
+ }
+ } else if (strncmp(option, "ro", 2) == 0) { /* root */
+ ptr = strchr(option, '=');
+ if (ptr != NULL) {
+ sscanf(++ptr, "%s", rootServerName);
+ }
+ } else if (strncmp(option, "sea", 3) == 0) { /* search list */
+ _res.options |= RES_DNSRCH;
+ } else if (strncmp(option, "nosea", 5) == 0) {
+ _res.options &= ~RES_DNSRCH;
+ } else if (strncmp(option, "srchl", 5) == 0) { /* domain search list */
+ ptr = strchr(option, '=');
+ if (ptr != NULL) {
+ res_dnsrch(++ptr);
+ }
+ } else if (strncmp(option, "ti", 2) == 0) { /* timeout */
+ ptr = strchr(option, '=');
+ if (ptr != NULL) {
+ sscanf(++ptr, "%d", &tmp);
+ if (tmp >= 0) {
+ _res.retrans = tmp;
+ }
+ }
+ } else if (strncmp(option, "v", 1) == 0) { /* vc */
+ _res.options |= RES_USEVC;
+ } else if (strncmp(option, "nov", 3) == 0) {
+ _res.options &= ~RES_USEVC;
+ } else {
+ fprintf(stderr, "*** Invalid option: %s\n", option);
+ return(ERROR);
+ }
+ }
+ return(SUCCESS);
+}
+
+/*
+ * Fake a reinitialization when the domain is changed.
+ */
+res_re_init()
+{
+ register char *cp, **pp;
+ int n;
+
+ /* find components of local domain that might be searched */
+ pp = _res.dnsrch;
+ *pp++ = _res.defdname;
+ for (cp = _res.defdname, n = 0; *cp; cp++)
+ if (*cp == '.')
+ n++;
+ cp = _res.defdname;
+ for (; n >= LOCALDOMAINPARTS && pp < _res.dnsrch + MAXDFLSRCH; n--) {
+ cp = strchr(cp, '.');
+ *pp++ = ++cp;
+ }
+ *pp = 0;
+ _res.options |= RES_INIT;
+}
+
+#define SRCHLIST_SEP '/'
+
+res_dnsrch(cp)
+ register char *cp;
+{
+ register char **pp;
+ int n;
+
+ (void)strncpy(_res.defdname, cp, sizeof(_res.defdname) - 1);
+ if ((cp = strchr(_res.defdname, '\n')) != NULL)
+ *cp = '\0';
+ /*
+ * Set search list to be blank-separated strings
+ * on rest of line.
+ */
+ cp = _res.defdname;
+ pp = _res.dnsrch;
+ *pp++ = cp;
+ for (n = 0; *cp && pp < _res.dnsrch + MAXDNSRCH; cp++) {
+ if (*cp == SRCHLIST_SEP) {
+ *cp = '\0';
+ n = 1;
+ } else if (n) {
+ *pp++ = cp;
+ n = 0;
+ }
+ }
+ if ((cp = strchr(pp[-1], SRCHLIST_SEP)) != NULL) {
+ *cp = '\0';
+ }
+ *pp = NULL;
+}
+
+
+/*
+ ******************************************************************************
+ *
+ * ShowOptions --
+ *
+ * Prints out the state information used by the resolver
+ * library and other options set by the user.
+ *
+ ******************************************************************************
+ */
+
+void
+ShowOptions()
+{
+ register char **cp;
+
+ PrintHostInfo(stdout, "Default Server:", defaultPtr);
+ if (curHostValid) {
+ PrintHostInfo(stdout, "Host:", &curHostInfo);
+ }
+
+ printf("Set options:\n");
+ printf(" %sdebug \t", (_res.options & RES_DEBUG) ? "" : "no");
+ printf(" %sdefname\t", (_res.options & RES_DEFNAMES) ? "" : "no");
+ printf(" %ssearch\t", (_res.options & RES_DNSRCH) ? "" : "no");
+ printf(" %srecurse\n", (_res.options & RES_RECURSE) ? "" : "no");
+
+ printf(" %sd2\t\t", (_res.options & RES_DEBUG2) ? "" : "no");
+ printf(" %svc\t\t", (_res.options & RES_USEVC) ? "" : "no");
+ printf(" %signoretc\t", (_res.options & RES_IGNTC) ? "" : "no");
+ printf(" port=%u\n", nsport);
+
+ printf(" querytype=%s\t", p_type(queryType));
+ printf(" class=%s\t", p_class(queryClass));
+ printf(" timeout=%d\t", _res.retrans);
+ printf(" retry=%d\n", _res.retry);
+ printf(" root=%s\n", rootServerName);
+ printf(" domain=%s\n", _res.defdname);
+
+ if (cp = _res.dnsrch) {
+ printf(" srchlist=%s", *cp);
+ for (cp++; *cp; cp++) {
+ printf("%c%s", SRCHLIST_SEP, *cp);
+ }
+ putchar('\n');
+ }
+ putchar('\n');
+}
+#undef SRCHLIST_SEP
+
+/*
+ ******************************************************************************
+ *
+ * PrintHelp --
+ *
+ * Displays the help file.
+ *
+ ******************************************************************************
+ */
+
+void
+PrintHelp()
+{
+ char cmd[PATH_MAX];
+
+ sprintf(cmd, "%s %s", pager, _PATH_HELPFILE);
+ system(cmd);
+}
+
+/*
+ ******************************************************************************
+ *
+ * CvtAddrToPtr --
+ *
+ * Convert a dotted-decimal Internet address into the standard
+ * PTR format (reversed address with .in-arpa. suffix).
+ *
+ * Assumes the argument buffer is large enougth to hold the result.
+ *
+ ******************************************************************************
+ */
+
+static void
+CvtAddrToPtr(name)
+ char *name;
+{
+ char *p;
+ int ip[4];
+ struct in_addr addr;
+
+ if (IsAddr(name, &addr)) {
+ p = inet_ntoa(addr);
+ if (sscanf(p, "%d.%d.%d.%d", &ip[0], &ip[1], &ip[2], &ip[3]) == 4) {
+ sprintf(name, "%d.%d.%d.%d.in-addr.arpa.",
+ ip[3], ip[2], ip[1], ip[0]);
+ }
+ }
+}
+
+/*
+ ******************************************************************************
+ *
+ * ReadRC --
+ *
+ * Use the contents of ~/.nslookuprc as options.
+ *
+ ******************************************************************************
+ */
+
+static void
+ReadRC()
+{
+ register FILE *fp;
+ register char *cp;
+ char buf[PATH_MAX];
+
+ if ((cp = getenv("HOME")) != NULL) {
+ (void) strcpy(buf, cp);
+ (void) strcat(buf, _PATH_NSLOOKUPRC);
+
+ if ((fp = fopen(buf, "r")) != NULL) {
+ while (fgets(buf, sizeof(buf), fp) != NULL) {
+ if ((cp = strchr(buf, '\n')) != NULL) {
+ *cp = '\0';
+ }
+ (void) SetOption(buf);
+ }
+ (void) fclose(fp);
+ }
+ }
+}
diff --git a/contrib/bind/tools/nslookup/nslookup.help b/contrib/bind/tools/nslookup/nslookup.help
new file mode 100644
index 0000000..18f2e6b
--- /dev/null
+++ b/contrib/bind/tools/nslookup/nslookup.help
@@ -0,0 +1,34 @@
+$Id: nslookup.help,v 8.3 1996/08/05 08:31:39 vixie Exp $
+
+Commands: (identifiers are shown in uppercase, [] means optional)
+NAME - print info about the host/domain NAME using default server
+NAME1 NAME2 - as above, but use NAME2 as server
+help or ? - print info on common commands; see nslookup(1) for details
+set OPTION - set an option
+ all - print options, current server and host
+ [no]debug - print debugging information
+ [no]d2 - print exhaustive debugging information
+ [no]defname - append domain name to each query
+ [no]recurse - ask for recursive answer to query
+ [no]vc - always use a virtual circuit
+ domain=NAME - set default domain name to NAME
+ srchlist=N1[/N2/.../N6] - set domain to N1 and search list to N1,N2, etc.
+ root=NAME - set root server to NAME
+ retry=X - set number of retries to X
+ timeout=X - set initial time-out interval to X seconds
+ querytype=X - set query type, e.g., A,ANY,CNAME,HINFO,MX,PX,NS,PTR,SOA,TXT,WKS
+ port=X - set port number to send query on
+ type=X - synonym for querytype
+ class=X - set query class to one of IN (Internet), CHAOS, HESIOD or ANY
+server NAME - set default server to NAME, using current default server
+lserver NAME - set default server to NAME, using initial server
+finger [USER] - finger the optional USER at the current default host
+root - set current default server to the root
+ls [opt] DOMAIN [> FILE] - list addresses in DOMAIN (optional: output to FILE)
+ -a - list canonical names and aliases
+ -h - list HINFO (CPU type and operating system)
+ -s - list well-known services
+ -d - list all records
+ -t TYPE - list records of the given type (e.g., A,CNAME,MX, etc.)
+view FILE - sort an 'ls' output file and view it with more
+exit - exit the program, ^D also exits
diff --git a/contrib/bind/tools/nslookup/pathnames.h b/contrib/bind/tools/nslookup/pathnames.h
new file mode 100644
index 0000000..bfeae4f
--- /dev/null
+++ b/contrib/bind/tools/nslookup/pathnames.h
@@ -0,0 +1,71 @@
+/*
+ * ++Copyright++ 1990
+ * -
+ * Copyright (c) 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--
+ */
+
+/*
+ * @(#)pathnames.h 5.1 (Berkeley) 5/28/90
+ * $Id: pathnames.h,v 8.1 1994/12/15 06:24:31 vixie Exp $
+ */
+
+#define _PATH_NSLOOKUPRC "/.nslookuprc"
+#define _PATH_PAGERCMD "more"
+
+#ifndef _PATH_HELPFILE
+#if defined(BSD) && BSD >= 198810
+#define _PATH_HELPFILE "/usr/share/misc/nslookup.help"
+#else
+#define _PATH_HELPFILE "/usr/lib/nslookup.help"
+#endif
+#endif
+
diff --git a/contrib/bind/tools/nslookup/res.h b/contrib/bind/tools/nslookup/res.h
new file mode 100644
index 0000000..9363f38
--- /dev/null
+++ b/contrib/bind/tools/nslookup/res.h
@@ -0,0 +1,172 @@
+/*
+ * ++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--
+ */
+
+/*
+ * @(#)res.h 5.10 (Berkeley) 6/1/90
+ * $Id: res.h,v 8.1 1994/12/15 06:24:31 vixie Exp $
+ */
+
+/*
+ *******************************************************************************
+ *
+ * res.h --
+ *
+ * Definitions used by modules of the name server lookup program.
+ *
+ * Copyright (c) 1985
+ * Andrew Cherenson
+ * U.C. Berkeley
+ * CS298-26 Fall 1985
+ *
+ *******************************************************************************
+ */
+
+#define TRUE 1
+#define FALSE 0
+typedef int Boolean;
+
+/*
+ * Define return statuses in addtion to the ones defined in namserv.h
+ * let SUCCESS be a synonym for NOERROR
+ *
+ * TIME_OUT - a socket connection timed out.
+ * NO_INFO - the server didn't find any info about the host.
+ * ERROR - one of the following types of errors:
+ * dn_expand, res_mkquery failed
+ * bad command line, socket operation failed, etc.
+ * NONAUTH - the server didn't have the desired info but
+ * returned the name(s) of some servers who should.
+ * NO_RESPONSE - the server didn't respond.
+ *
+ */
+
+#define SUCCESS 0
+#define TIME_OUT -1
+#define NO_INFO -2
+#define ERROR -3
+#define NONAUTH -4
+#define NO_RESPONSE -5
+
+/*
+ * Define additional options for the resolver state structure.
+ *
+ * RES_DEBUG2 more verbose debug level
+ */
+
+#define RES_DEBUG2 0x80000000
+
+/*
+ * Maximum length of server, host and file names.
+ */
+
+#define NAME_LEN 256
+
+
+/*
+ * Modified struct hostent from <netdb.h>
+ *
+ * "Structures returned by network data base library. All addresses
+ * are supplied in host order, and returned in network order (suitable
+ * for use in system calls)."
+ */
+
+typedef struct {
+ char *name; /* official name of host */
+ char **domains; /* domains it serves */
+ char **addrList; /* list of addresses from name server */
+} ServerInfo;
+
+typedef struct {
+ char *name; /* official name of host */
+ char **aliases; /* alias list */
+ char **addrList; /* list of addresses from name server */
+ int addrType; /* host address type */
+ int addrLen; /* length of address */
+ ServerInfo **servers;
+} HostInfo;
+
+
+/*
+ * FilePtr is used for directing listings to a file.
+ * It is global so the Control-C handler can close it.
+ */
+
+extern FILE *filePtr;
+
+/*
+ * TCP/UDP port of server.
+ */
+extern unsigned short nsport;
+
+/*
+ * External routines:
+ */
+
+extern Boolean IsAddr();
+extern int Print_query();
+extern unsigned char *Print_cdname();
+extern unsigned char *Print_cdname2(); /* fixed width */
+extern unsigned char *Print_rr();
+extern char *DecodeType(); /* descriptive version of p_type */
+extern char *DecodeError();
+extern char *Calloc();
+extern char *Malloc();
+extern void NsError();
+extern void PrintServer();
+extern void PrintHostInfo();
+extern void ShowOptions();
+extern void FreeHostInfoPtr();
+extern FILE *OpenFile();
+extern char *res_skip();
diff --git a/contrib/bind/tools/nslookup/send.c b/contrib/bind/tools/nslookup/send.c
new file mode 100644
index 0000000..46c74b5
--- /dev/null
+++ b/contrib/bind/tools/nslookup/send.c
@@ -0,0 +1,412 @@
+/*
+ * ++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--
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)send.c 5.18 (Berkeley) 3/2/91";
+static char rcsid[] = "$Id: send.c,v 8.1 1994/12/15 06:24:31 vixie Exp $";
+#endif /* not lint */
+
+/*
+ ******************************************************************************
+ *
+ * send.c --
+ *
+ * Routine to send request packets to a name server.
+ *
+ * Based on "@(#)res_send.c 6.25 (Berkeley) 6/1/90".
+ *
+ ******************************************************************************
+ */
+
+
+/*
+ * Send query to name server and wait for reply.
+ */
+
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+#include <netinet/in.h>
+#include <stdio.h>
+#include <errno.h>
+#include <arpa/nameser.h>
+#include <arpa/inet.h>
+#include <resolv.h>
+#include "res.h"
+#include "../../conf/portability.h"
+
+static int s = -1; /* socket used for communications */
+
+
+#ifndef FD_SET
+#define NFDBITS 32
+#define FD_SETSIZE 32
+#define FD_SET(n, p) ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
+#define FD_CLR(n, p) ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))
+#define FD_ISSET(n, p) ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))
+#define FD_ZERO(p) bzero((char *)(p), sizeof(*(p)))
+#endif
+
+
+
+unsigned short nsport = NAMESERVER_PORT;
+
+
+
+/*
+ ******************************************************************************
+ *
+ * SendRequest --
+ *
+ * Sends a request packet to a name server whose address
+ * is specified by the first argument and returns with
+ * the answer packet.
+ *
+ * Results:
+ * SUCCESS - the request was sent and an answer
+ * was received.
+ * TIME_OUT - the virtual circuit connection timed-out
+ * or a reply to a datagram wasn't received.
+ *
+ *
+ ******************************************************************************
+ */
+
+int
+SendRequest(nsAddrPtr, buf, buflen, answer, anslen, trueLenPtr)
+ struct in_addr *nsAddrPtr;
+ char *buf;
+ int buflen;
+ char *answer;
+ u_int anslen;
+ int *trueLenPtr;
+{
+ register int n;
+ int try, v_circuit, resplen;
+ int gotsomewhere = 0, connected = 0;
+ int connreset = 0;
+ u_short id, len;
+ char *cp;
+ fd_set dsmask;
+ struct timeval timeout;
+ HEADER *hp = (HEADER *) buf;
+ HEADER *anhp = (HEADER *) answer;
+ struct iovec iov[2];
+ int terrno = ETIMEDOUT;
+ char junk[512];
+ struct sockaddr_in sin;
+
+ if (_res.options & RES_DEBUG2) {
+ printf("------------\nSendRequest(), len %d\n", buflen);
+ Print_query(buf, buf+buflen, 1);
+ }
+ sin.sin_family = AF_INET;
+ sin.sin_port = htons(nsport);
+ sin.sin_addr = *nsAddrPtr;
+ v_circuit = (_res.options & RES_USEVC) || buflen > PACKETSZ;
+ id = hp->id;
+ /*
+ * Send request, RETRY times, or until successful
+ */
+ for (try = 0; try < _res.retry; try++) {
+ usevc:
+ if (v_circuit) {
+ int truncated = 0;
+
+ /*
+ * Use virtual circuit;
+ * at most one attempt per server.
+ */
+ try = _res.retry;
+ if (s < 0) {
+ s = socket(AF_INET, SOCK_STREAM, 0);
+ if (s < 0) {
+ terrno = errno;
+ if (_res.options & RES_DEBUG)
+ perror("socket (vc) failed");
+ continue;
+ }
+ if (connect(s, (struct sockaddr *)&sin,
+ sizeof(struct sockaddr)) < 0) {
+ terrno = errno;
+ if (_res.options & RES_DEBUG)
+ perror("connect failed");
+ (void) close(s);
+ s = -1;
+ continue;
+ }
+ }
+ /*
+ * Send length & message
+ */
+ __putshort(buflen, (u_char *)&len);
+ iov[0].iov_base = (caddr_t)&len;
+ iov[0].iov_len = INT16SZ;
+ iov[1].iov_base = buf;
+ iov[1].iov_len = buflen;
+ if (writev(s, iov, 2) != INT16SZ + buflen) {
+ terrno = errno;
+ if (_res.options & RES_DEBUG)
+ perror("write failed");
+ (void) close(s);
+ s = -1;
+ continue;
+ }
+ /*
+ * Receive length & response
+ */
+ cp = answer;
+ len = INT16SZ;
+ while ((n = read(s, (char *)cp, (int)len)) > 0) {
+ cp += n;
+ if ((len -= n) <= 0)
+ break;
+ }
+ if (n <= 0) {
+ terrno = errno;
+ if (_res.options & RES_DEBUG)
+ perror("read failed");
+ (void) close(s);
+ s = -1;
+ /*
+ * A long running process might get its TCP
+ * connection reset if the remote server was
+ * restarted. Requery the server instead of
+ * trying a new one. When there is only one
+ * server, this means that a query might work
+ * instead of failing. We only allow one reset
+ * per query to prevent looping.
+ */
+ if (terrno == ECONNRESET && !connreset) {
+ connreset = 1;
+ }
+ continue;
+ }
+ cp = answer;
+ if ((resplen = _getshort((u_char*)cp)) > anslen) {
+ if (_res.options & RES_DEBUG)
+ fprintf(stderr, "response truncated\n");
+ len = anslen;
+ truncated = 1;
+ } else
+ len = resplen;
+ while (len != 0 &&
+ (n = read(s, (char *)cp, (int)len)) > 0) {
+ cp += n;
+ len -= n;
+ }
+ if (n <= 0) {
+ terrno = errno;
+ if (_res.options & RES_DEBUG)
+ perror("read failed");
+ (void) close(s);
+ s = -1;
+ continue;
+ }
+ if (truncated) {
+ /*
+ * Flush rest of answer
+ * so connection stays in synch.
+ */
+ anhp->tc = 1;
+ len = resplen - anslen;
+ while (len != 0) {
+ n = (len > sizeof(junk) ?
+ sizeof(junk) : len);
+ if ((n = read(s, junk, n)) > 0)
+ len -= n;
+ else
+ break;
+ }
+ }
+ } else {
+ /*
+ * Use datagrams.
+ */
+ if (s < 0) {
+ s = socket(AF_INET, SOCK_DGRAM, 0);
+ if (s < 0) {
+ terrno = errno;
+ if (_res.options & RES_DEBUG)
+ perror("socket (dg) failed");
+ continue;
+ }
+ }
+#if BSD >= 43
+ if (connected == 0) {
+ if (connect(s, (struct sockaddr *)&sin,
+ sizeof(struct sockaddr)) < 0) {
+ if (_res.options & RES_DEBUG)
+ perror("connect");
+ continue;
+ }
+ connected = 1;
+ }
+ if (send(s, buf, buflen, 0) != buflen) {
+ if (_res.options & RES_DEBUG)
+ perror("send");
+ continue;
+ }
+#else /* BSD */
+ if (sendto(s, buf, buflen, 0,
+ (struct sockaddr *) &sin,
+ sizeof(sin)) != buflen) {
+ if (_res.options & RES_DEBUG)
+ perror("sendto");
+ continue;
+ }
+#endif
+
+ /*
+ * Wait for reply
+ */
+ timeout.tv_sec = (_res.retrans << try);
+ if (timeout.tv_sec <= 0)
+ timeout.tv_sec = 1;
+ timeout.tv_usec = 0;
+wait:
+ FD_ZERO(&dsmask);
+ FD_SET(s, &dsmask);
+ n = select(s+1, &dsmask, (fd_set *)NULL,
+ (fd_set *)NULL, &timeout);
+ if (n < 0) {
+ if (_res.options & RES_DEBUG)
+ perror("select");
+ continue;
+ }
+ if (n == 0) {
+ /*
+ * timeout
+ */
+ if (_res.options & RES_DEBUG)
+ printf("timeout (%d secs)\n",
+ timeout.tv_sec);
+#if BSD >= 43
+ gotsomewhere = 1;
+#endif
+ continue;
+ }
+ if ((resplen = recv(s, answer, anslen, 0)) <= 0) {
+ if (_res.options & RES_DEBUG)
+ perror("recvfrom");
+ continue;
+ }
+ gotsomewhere = 1;
+ if (id != anhp->id) {
+ /*
+ * response from old query, ignore it
+ */
+ if (_res.options & RES_DEBUG2) {
+ printf("------------\nOld answer:\n");
+ Print_query(answer, answer+resplen, 1);
+ }
+ goto wait;
+ }
+ if (!(_res.options & RES_IGNTC) && anhp->tc) {
+ /*
+ * get rest of answer;
+ * use TCP with same server.
+ */
+ if (_res.options & RES_DEBUG)
+ printf("truncated answer\n");
+ (void) close(s);
+ s = -1;
+ v_circuit = 1;
+ goto usevc;
+ }
+ }
+ if (_res.options & RES_DEBUG) {
+ if (_res.options & RES_DEBUG2)
+ printf("------------\nGot answer (%d bytes):\n",
+ resplen);
+ else
+ printf("------------\nGot answer:\n");
+ Print_query(answer, answer+resplen, 1);
+ }
+ (void) close(s);
+ s = -1;
+ *trueLenPtr = resplen;
+ return (SUCCESS);
+ }
+ if (s >= 0) {
+ (void) close(s);
+ s = -1;
+ }
+ if (v_circuit == 0)
+ if (gotsomewhere == 0)
+ return NO_RESPONSE; /* no nameservers found */
+ else
+ return TIME_OUT; /* no answer obtained */
+ else
+ if (errno == ECONNREFUSED)
+ return NO_RESPONSE;
+ else
+ return ERROR;
+}
+
+/*
+ * This routine is for closing the socket if a virtual circuit is used and
+ * the program wants to close it.
+ *
+ * Called from the interrupt handler.
+ */
+SendRequest_close()
+{
+ if (s != -1) {
+ (void) close(s);
+ s = -1;
+ }
+}
diff --git a/contrib/bind/tools/nslookup/skip.c b/contrib/bind/tools/nslookup/skip.c
new file mode 100644
index 0000000..2c78377
--- /dev/null
+++ b/contrib/bind/tools/nslookup/skip.c
@@ -0,0 +1,211 @@
+/*
+ * ++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--
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)skip.c 5.12 (Berkeley) 3/21/91";
+static char rcsid[] = "$Id: skip.c,v 8.1 1994/12/15 06:24:31 vixie Exp $";
+#endif /* not lint */
+
+/*
+ *******************************************************************************
+ *
+ * skip.c --
+ *
+ * Routines to skip over portions of a query buffer.
+ *
+ * Note: this file has been submitted for inclusion in
+ * BIND resolver library. When this has been done, this file
+ * is no longer necessary (assuming there haven't been any
+ * changes).
+ *
+ * Adapted from 4.3BSD BIND res_debug.c
+ *
+ *******************************************************************************
+ */
+
+#include <sys/param.h>
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <resolv.h>
+#include <stdio.h>
+#include "../../conf/portability.h"
+
+char *res_skip_rr();
+
+
+/*
+ *******************************************************************************
+ *
+ * res_skip --
+ *
+ * Skip the contents of a query.
+ *
+ * Interpretation of numFieldsToSkip argument:
+ * res_skip returns pointer to:
+ * 1 -> start of question records.
+ * 2 -> start of authoritative answer records.
+ * 3 -> start of additional records.
+ * 4 -> first byte after end of additional records.
+ *
+ * Results:
+ * (address) - success operation.
+ * NULL - a resource record had an incorrect format.
+ *
+ *******************************************************************************
+ */
+
+char *
+res_skip(msg, numFieldsToSkip, eom)
+ char *msg;
+ int numFieldsToSkip;
+ char *eom;
+{
+ register char *cp;
+ register HEADER *hp;
+ register int tmp;
+ register int n;
+
+ /*
+ * Skip the header fields.
+ */
+ hp = (HEADER *)msg;
+ cp = msg + HFIXEDSZ;
+
+ /*
+ * skip question records.
+ */
+ if (n = ntohs(hp->qdcount) ) {
+ while (--n >= 0 && cp < eom) {
+ tmp = dn_skipname((u_char *)cp, (u_char *)eom);
+ if (tmp == -1) return(NULL);
+ cp += tmp;
+ cp += INT16SZ; /* type */
+ cp += INT16SZ; /* class */
+ }
+ }
+ if (--numFieldsToSkip <= 0) return(cp);
+
+ /*
+ * skip authoritative answer records
+ */
+ if (n = ntohs(hp->ancount)) {
+ while (--n >= 0 && cp < eom) {
+ cp = res_skip_rr(cp, eom);
+ if (cp == NULL) return(NULL);
+ }
+ }
+ if (--numFieldsToSkip == 0) return(cp);
+
+ /*
+ * skip name server records
+ */
+ if (n = ntohs(hp->nscount)) {
+ while (--n >= 0 && cp < eom) {
+ cp = res_skip_rr(cp, eom);
+ if (cp == NULL) return(NULL);
+ }
+ }
+ if (--numFieldsToSkip == 0) return(cp);
+
+ /*
+ * skip additional records
+ */
+ if (n = ntohs(hp->arcount)) {
+ while (--n >= 0 && cp < eom) {
+ cp = res_skip_rr(cp, eom);
+ if (cp == NULL) return(NULL);
+ }
+ }
+
+ return(cp);
+}
+
+
+/*
+ *******************************************************************************
+ *
+ * res_skip_rr --
+ *
+ * Skip over resource record fields.
+ *
+ * Results:
+ * (address) - success operation.
+ * NULL - a resource record had an incorrect format.
+ *******************************************************************************
+ */
+
+char *
+res_skip_rr(cp, eom)
+ char *cp;
+ char *eom;
+{
+ int tmp;
+ int dlen;
+
+ if ((tmp = dn_skipname((u_char *)cp, (u_char *)eom)) == -1)
+ return (NULL); /* compression error */
+ cp += tmp;
+ if ((cp + RRFIXEDSZ) > eom)
+ return (NULL);
+ cp += INT16SZ; /* type */
+ cp += INT16SZ; /* class */
+ cp += INT32SZ; /* ttl */
+ dlen = _getshort((u_char*)cp);
+ cp += INT16SZ; /* dlen */
+ cp += dlen;
+ if (cp > eom)
+ return (NULL);
+ return (cp);
+}
diff --git a/contrib/bind/tools/nslookup/subr.c b/contrib/bind/tools/nslookup/subr.c
new file mode 100644
index 0000000..59a47f5
--- /dev/null
+++ b/contrib/bind/tools/nslookup/subr.c
@@ -0,0 +1,583 @@
+/*
+ * ++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--
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)subr.c 5.24 (Berkeley) 3/2/91";
+static char rcsid[] = "$Id: subr.c,v 8.5 1996/05/21 07:04:38 vixie Exp $";
+#endif /* not lint */
+
+/*
+ *******************************************************************************
+ *
+ * subr.c --
+ *
+ * Miscellaneous subroutines for the name server
+ * lookup program.
+ *
+ * Copyright (c) 1985
+ * Andrew Cherenson
+ * U.C. Berkeley
+ * CS298-26 Fall 1985
+ *
+ *******************************************************************************
+ */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <netdb.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <arpa/inet.h>
+#include <signal.h>
+#include <setjmp.h>
+#include <stdio.h>
+#include "res.h"
+#include "../../conf/portability.h"
+
+
+
+/*
+ *******************************************************************************
+ *
+ * IntrHandler --
+ *
+ * This routine is called whenever a control-C is typed.
+ * It performs three main functions:
+ * - closes an open socket connection,
+ * - closes an open output file (used by LookupHost, et al.),
+ * - jumps back to the main read-eval loop.
+ *
+ * If a user types a ^C in the middle of a routine that uses a socket,
+ * the routine would not be able to close the socket. To prevent an
+ * overflow of the process's open file table, the socket and output
+ * file descriptors are closed by the interrupt handler.
+ *
+ * Side effects:
+ * Open file descriptors are closed.
+ * If filePtr is valid, it is closed.
+ * Flow of control returns to the main() routine.
+ *
+ *******************************************************************************
+ */
+
+SIG_FN
+IntrHandler()
+{
+ extern jmp_buf env;
+#if defined(BSD) && BSD >= 199006 && !defined(RISCOS_BSD) && !defined(__osf__)
+ extern FILE *yyin; /* scanner input file */
+ extern void yyrestart(); /* routine to restart scanner after interrupt */
+#endif
+
+ SendRequest_close();
+ ListHost_close();
+ if (filePtr != NULL && filePtr != stdout) {
+ fclose(filePtr);
+ filePtr = NULL;
+ }
+ printf("\n");
+#if defined(BSD) && BSD >= 199006 && !defined(RISCOS_BSD) && !defined(__osf__)
+ yyrestart(yyin);
+#endif
+ longjmp(env, 1);
+}
+
+
+/*
+ *******************************************************************************
+ *
+ * Malloc --
+ * Calloc --
+ *
+ * Calls the malloc library routine with SIGINT blocked to prevent
+ * corruption of malloc's data structures. We need to do this because
+ * a control-C doesn't kill the program -- it causes a return to the
+ * main command loop.
+ *
+ * NOTE: This method doesn't prevent the pointer returned by malloc
+ * from getting lost, so it is possible to get "core leaks".
+ *
+ * If malloc fails, the program exits.
+ *
+ * Results:
+ * (address) - address of new buffer.
+ *
+ *******************************************************************************
+ */
+
+char *
+Malloc(size)
+ int size;
+{
+ char *ptr;
+
+#ifdef SYSV
+#if defined(SVR3) || defined(SVR4)
+ sighold(SIGINT);
+ ptr = malloc((unsigned) size);
+ sigrelse(SIGINT);
+#else
+ { SIG_FN (*old)();
+ old = signal(SIGINT, SIG_IGN);
+ ptr = malloc((unsigned) size);
+ signal(SIGINT, old);
+ }
+#endif
+#else
+#ifdef POSIX_SIGNALS
+ { sigset_t sset;
+ sigemptyset(&sset);
+ sigaddset(&sset,SIGINT);
+ sigprocmask(SIG_BLOCK,&sset,NULL);
+ ptr = malloc((unsigned) size);
+ sigprocmask(SIG_UNBLOCK,&sset,NULL);
+ }
+#else
+ { int saveMask;
+ saveMask = sigblock(sigmask(SIGINT));
+ ptr = malloc((unsigned) size);
+ (void) sigsetmask(saveMask);
+ }
+#endif
+#endif
+ if (ptr == NULL) {
+ fflush(stdout);
+ fprintf(stderr, "*** Can't allocate memory\n");
+ fflush(stderr);
+ abort();
+ /*NOTREACHED*/
+ } else {
+ return(ptr);
+ }
+}
+
+char *
+Calloc(num, size)
+ register int num, size;
+{
+ char *ptr = Malloc(num*size);
+ bzero(ptr, num*size);
+ return(ptr);
+}
+
+
+/*
+ *******************************************************************************
+ *
+ * PrintHostInfo --
+ *
+ * Prints out the HostInfo structure for a host.
+ *
+ *******************************************************************************
+ */
+
+void
+PrintHostInfo(file, title, hp)
+ FILE *file;
+ char *title;
+ register HostInfo *hp;
+{
+ register char **cp;
+ register ServerInfo **sp;
+ char comma;
+ int i;
+
+ fprintf(file, "%-7s %s", title, hp->name);
+
+ if (hp->addrList != NULL) {
+ if (hp->addrList[1] != NULL) {
+ fprintf(file, "\nAddresses:");
+ } else {
+ fprintf(file, "\nAddress:");
+ }
+ comma = ' ';
+ i = 0;
+ for (cp = hp->addrList; cp && *cp; cp++) {
+ i++;
+ if (i > 4) {
+ fprintf(file, "\n\t");
+ comma = ' ';
+ i = 0;
+ }
+ fprintf(file,"%c %s", comma, inet_ntoa(*(struct in_addr *)*cp));
+ comma = ',';
+ }
+ }
+
+ if (hp->aliases != NULL) {
+ fprintf(file, "\nAliases:");
+ comma = ' ';
+ i = 10;
+ for (cp = hp->aliases; cp && *cp && **cp; cp++) {
+ i += strlen(*cp) + 2;
+ if (i > 75) {
+ fprintf(file, "\n\t");
+ comma = ' ';
+ i = 10;
+ }
+ fprintf(file, "%c %s", comma, *cp);
+ comma = ',';
+ }
+ }
+
+ if (hp->servers != NULL) {
+ fprintf(file, "\nServed by:\n");
+ for (sp = hp->servers; *sp != NULL ; sp++) {
+
+ fprintf(file, "- %s\n\t", (*sp)->name);
+
+ comma = ' ';
+ i = 0;
+ for (cp = (*sp)->addrList; cp && *cp && **cp; cp++) {
+ i++;
+ if (i > 4) {
+ fprintf(file, "\n\t");
+ comma = ' ';
+ i = 0;
+ }
+ fprintf(file,
+ "%c %s", comma, inet_ntoa(*(struct in_addr *)*cp));
+ comma = ',';
+ }
+ fprintf(file, "\n\t");
+
+ comma = ' ';
+ i = 10;
+ for (cp = (*sp)->domains; cp && *cp && **cp; cp++) {
+ i += strlen(*cp) + 2;
+ if (i > 75) {
+ fprintf(file, "\n\t");
+ comma = ' ';
+ i = 10;
+ }
+ fprintf(file, "%c %s", comma, *cp);
+ comma = ',';
+ }
+ fprintf(file, "\n");
+ }
+ }
+
+ fprintf(file, "\n\n");
+}
+
+/*
+ *******************************************************************************
+ *
+ * OpenFile --
+ *
+ * Parses a command string for a file name and opens
+ * the file.
+ *
+ * Results:
+ * file pointer - the open was successful.
+ * NULL - there was an error opening the file or
+ * the input string was invalid.
+ *
+ *******************************************************************************
+ */
+
+FILE *
+OpenFile(string, file)
+ char *string;
+ char *file;
+{
+ char *redirect;
+ FILE *tmpPtr;
+
+ /*
+ * Open an output file if we see '>' or >>'.
+ * Check for overwrite (">") or concatenation (">>").
+ */
+
+ redirect = strchr(string, '>');
+ if (redirect == NULL) {
+ return(NULL);
+ }
+ if (redirect[1] == '>') {
+ sscanf(redirect, ">> %s", file);
+ tmpPtr = fopen(file, "a+");
+ } else {
+ sscanf(redirect, "> %s", file);
+ tmpPtr = fopen(file, "w");
+ }
+
+ if (tmpPtr != NULL) {
+ redirect[0] = '\0';
+ }
+
+ return(tmpPtr);
+}
+
+/*
+ *******************************************************************************
+ *
+ * DecodeError --
+ *
+ * Converts an error code into a character string.
+ *
+ *******************************************************************************
+ */
+
+char *
+DecodeError(result)
+ int result;
+{
+ switch (result) {
+ case NOERROR: return("Success"); break;
+ case FORMERR: return("Format error"); break;
+ case SERVFAIL: return("Server failed"); break;
+ case NXDOMAIN: return("Non-existent host/domain"); break;
+ case NOTIMP: return("Not implemented"); break;
+ case REFUSED: return("Query refused"); break;
+#ifdef NOCHANGE
+ case NOCHANGE: return("No change"); break;
+#endif
+ case TIME_OUT: return("Timed out"); break;
+ case NO_INFO: return("No information"); break;
+ case ERROR: return("Unspecified error"); break;
+ case NONAUTH: return("Non-authoritative answer"); break;
+ case NO_RESPONSE: return("No response from server"); break;
+ default: break;
+ }
+ return("BAD ERROR VALUE");
+}
+
+
+int
+StringToClass(class, dflt, errorfile)
+ char *class;
+ int dflt;
+ FILE *errorfile;
+{
+ if (strcasecmp(class, "IN") == 0)
+ return(C_IN);
+ if (strcasecmp(class, "HESIOD") == 0 ||
+ strcasecmp(class, "HS") == 0)
+ return(C_HS);
+ if (strcasecmp(class, "CHAOS") == 0)
+ return(C_CHAOS);
+ if (strcasecmp(class, "ANY") == 0)
+ return(C_ANY);
+ if (errorfile)
+ fprintf(errorfile, "unknown query class: %s\n", class);
+ return(dflt);
+}
+
+
+/*
+ *******************************************************************************
+ *
+ * StringToType --
+ *
+ * Converts a string form of a query type name to its
+ * corresponding integer value.
+ *
+ *******************************************************************************
+ */
+
+int
+StringToType(type, dflt, errorfile)
+ char *type;
+ int dflt;
+ FILE *errorfile;
+{
+ if (strcasecmp(type, "A") == 0)
+ return(T_A);
+ if (strcasecmp(type, "NS") == 0)
+ return(T_NS); /* authoritative server */
+ if (strcasecmp(type, "MX") == 0)
+ return(T_MX); /* mail exchanger */
+ if (strcasecmp(type, "PX") == 0)
+ return(T_PX); /* mapping information */
+ if (strcasecmp(type, "CNAME") == 0)
+ return(T_CNAME); /* canonical name */
+ if (strcasecmp(type, "SOA") == 0)
+ return(T_SOA); /* start of authority zone */
+ if (strcasecmp(type, "MB") == 0)
+ return(T_MB); /* mailbox domain name */
+ if (strcasecmp(type, "MG") == 0)
+ return(T_MG); /* mail group member */
+ if (strcasecmp(type, "MR") == 0)
+ return(T_MR); /* mail rename name */
+ if (strcasecmp(type, "WKS") == 0)
+ return(T_WKS); /* well known service */
+ if (strcasecmp(type, "PTR") == 0)
+ return(T_PTR); /* domain name pointer */
+ if (strcasecmp(type, "HINFO") == 0)
+ return(T_HINFO); /* host information */
+ if (strcasecmp(type, "MINFO") == 0)
+ return(T_MINFO); /* mailbox information */
+ if (strcasecmp(type, "AXFR") == 0)
+ return(T_AXFR); /* zone transfer */
+ if (strcasecmp(type, "MAILA") == 0)
+ return(T_MAILA); /* mail agent */
+ if (strcasecmp(type, "MAILB") == 0)
+ return(T_MAILB); /* mail box */
+ if (strcasecmp(type, "ANY") == 0)
+ return(T_ANY); /* matches any type */
+ if (strcasecmp(type, "UINFO") == 0)
+ return(T_UINFO); /* user info */
+ if (strcasecmp(type, "UID") == 0)
+ return(T_UID); /* user id */
+ if (strcasecmp(type, "GID") == 0)
+ return(T_GID); /* group id */
+ if (strcasecmp(type, "TXT") == 0)
+ return(T_TXT); /* text */
+ if (strcasecmp(type, "RP") == 0)
+ return(T_RP); /* responsible person */
+ if (strcasecmp(type, "X25") == 0)
+ return(T_X25); /* x25 address */
+ if (strcasecmp(type, "ISDN") == 0)
+ return(T_ISDN); /* isdn address */
+ if (strcasecmp(type, "RT") == 0)
+ return(T_RT); /* router */
+ if (strcasecmp(type, "AFSDB") == 0)
+ return(T_AFSDB); /* DCE or AFS server */
+ if (strcasecmp(type, "NSAP") == 0)
+ return(T_NSAP); /* NSAP address */
+ if (strcasecmp(type, "NSAP_PTR") == 0)
+ return(T_NSAP_PTR); /* NSAP reverse pointer */
+ if (strcasecmp(type, "AAAA") == 0)
+ return(T_AAAA); /* IPv6 address */
+ if (errorfile)
+ fprintf(errorfile, "unknown query type: %s\n", type);
+ return(dflt);
+}
+
+/*
+ *******************************************************************************
+ *
+ * DecodeType --
+ *
+ * Converts a query type to a descriptive name.
+ * (A more verbose form of p_type.)
+ *
+ *
+ *******************************************************************************
+ */
+
+static char nbuf[20];
+
+char *
+DecodeType(type)
+ int type;
+{
+ switch (type) {
+ case T_A:
+ return("address");
+ case T_AAAA:
+ return("IPv6 address");
+ case T_NS:
+ return("name server");
+ case T_CNAME:
+ return("canonical name");
+ case T_SOA:
+ return("start of authority");
+ case T_MB:
+ return("mailbox");
+ case T_MG:
+ return("mail group member");
+ case T_MR:
+ return("mail rename");
+ case T_NULL:
+ return("null");
+ case T_WKS:
+ return("well-known service");
+ case T_PTR:
+ return("domain name pointer");
+ case T_HINFO:
+ return("host information");
+ case T_MINFO:
+ return("mailbox information");
+ case T_MX:
+ return("mail exchanger");
+ case T_PX:
+ return("mapping information");
+ case T_TXT:
+ return("text");
+ case T_RP:
+ return("responsible person");
+ case T_AFSDB:
+ return("DCE or AFS server");
+ case T_X25:
+ return("X25 address");
+ case T_ISDN:
+ return("ISDN address");
+ case T_RT:
+ return("router");
+ case T_NSAP:
+ return("nsap address");
+ case T_NSAP_PTR:
+ return("domain name pointer");
+ case T_UINFO:
+ return("user information");
+ case T_UID:
+ return("user ID");
+ case T_GID:
+ return("group ID");
+ case T_AXFR:
+ return("zone transfer");
+ case T_MAILB:
+ return("mailbox-related data");
+ case T_MAILA:
+ return("mail agent");
+ case T_ANY:
+ return("\"any\"");
+ default:
+ (void) sprintf(nbuf, "%d", type);
+ return (nbuf);
+ }
+}
OpenPOWER on IntegriCloud