diff options
author | peter <peter@FreeBSD.org> | 1996-08-29 19:20:22 +0000 |
---|---|---|
committer | peter <peter@FreeBSD.org> | 1996-08-29 19:20:22 +0000 |
commit | a4451e14cb8b614d2330dc98aafd2e66f048243f (patch) | |
tree | 6c8c8ede0dc22cb0583c2645a360921c77c8e875 /contrib | |
parent | ab0ebe585d3b07199c949f94201193c0187ab393 (diff) | |
parent | 2d3cf9fcaf1ca2528c5fe3ba683d1f6c1268dc41 (diff) | |
download | FreeBSD-src-a4451e14cb8b614d2330dc98aafd2e66f048243f.zip FreeBSD-src-a4451e14cb8b614d2330dc98aafd2e66f048243f.tar.gz |
This commit was generated by cvs2svn to compensate for changes in r17892,
which included commits to RCS files with non-trunk default branches.
Diffstat (limited to 'contrib')
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); + } +} |