pax_global_header00006660000000000000000000000064110342407620014511gustar00rootroot0000000000000052 comment=cbda7e182b1e3592aba05b60284d4e73dae86821 tinydyndns-0.4.2.debian1/000077500000000000000000000000001103424076200152215ustar00rootroot00000000000000tinydyndns-0.4.2.debian1/CHANGES000066400000000000000000000357621103424076200162310ustar00rootroot0000000000000019991129 version: dnscache 0.50, alpha. not released yet. 19991223 version: dnscache 0.60, alpha. 19991224 internal: dns_sortip() takes length argument. api: dns_ip4() sorts output. currently this means just random. api: added socket_bind4_reuse(). removed reuse from bind4(). ui: used bind4_reuse() for port 53, bind4() otherwise. internal: eliminated some unused variables. internal: prototypes in cdb.h, cdbmake.h, cdbmss.h. internal: prototypes in case.h, env.h, fmt.h, scan.h, str.h. internal: prototypes in stralloc.h. internal: prototypes in error.h, strerr.h. internal: prototypes in ndelay.h, open.h, seek.h. internal: prototypes in sgetopt.h, subgetopt.h. internal: prototypes in tai.h, taia.h. internal: added some missing declarations. bug: query.c checked void response_finishanswer() return code. impact: cached responses were dropped on systems that didn't follow the traditional C return behavior. fix: obvious. tnx Giles Lean. internal: switched from taia_addsec() to taia_uint(). api: switched to uint16 for socket_* port numbers. internal: integrated uint16_pack() and friends. ui: dnscache allows (recursive) queries from port 53. ui: dnscache has 10-second idle timer on TCP read/write. ui: dnscache limits itself to 20 concurrent TCP connections. internal: moved dns_domain_fromdot() to separate file. ui: supported \X, \1, \12, \123 in dns_domain_fromdot(). ui: supported \123 in dns_domain_todot_append(). version: dnscache 0.61, alpha. 19991230 api: added dns_ip4_qualify(). api: added dns_resolvconfrewrite(). ui: added dnsipq. api: dns_ip4() checks for (strings of) IP addresses. 20000106 port: Solaris needs /dev/udp, not just /dev/tcp. impact: dnscache and tinydns would stop immediately under Solaris. fix: create /dev/udp in configure; and have tinydns create socket before chroot. tnx Louis Theran. internal: moved dns_name4_domain() to dns_nd.c. ui: tinydns no longer excludes screwy queries from its log. internal: moved respond() to tdlookup.c under new name. ui: added tinydns-get. ui: rewrote tinydns-data for new data format. internal: expanded rts to cover tinydns-data using tinydns-get. 20000107 ui: tinydns-data allows arbitrary case in domain names. ui: dnscache supports preconfigured servers for non-root domains. ui: dnscache uses textual addresses for preconfigured servers. 20000108 ui: tinydns-data excludes the additional and authority sections if doing so helps meet the 512-byte UDP limit. version: dnscache 0.70, beta. 20000114 internal: in log.c, ulong() now prints a uint64. internal: added cache_motion, query_count, log_stats. ui: dnscache now prints queries/motion stats after typical response packets. 20000115 internal: added droproot.c. used in tinydns and dnscache. internal: moved tinydns log() to qlog.c under new name. ui: added walldns, configure-wd. ui: configure-td now creates an empty root/data. ui: added tinydns-edit. ui: configure-td now sets up root/add-{ns,childns,host,mx}. 20000116 ui: renamed configure* as *-conf. ui: added axfrdns, axfrdns-conf. ui: added axfr-get. ui: dnscache-conf 10.* or 192.168.* now sets IPSEND=0.0.0.0. 20000117 ui: added pickdns, pickdns-conf, pickdns-data. version: dnscache 0.75, beta. 20000118 internal: address* -> address_* in pickdns-data.c. internal: start writing cdb earlier in pickdns-data.c. internal: keep track of namelen in pickdns-data.c. ui: added client-location variability to pickdns, pickdns-data. ui: qlog logs short packets. ui: qlog logs header if RD or other unusual bits are set. ui: qlog logs non-Internet classes. api: dns_domain_todot_append() -> dns_domain_todot_cat(). ui: axfr-get prints A records more nicely. tnx Russ Nelson. ui: tinydns, pickdns, and walldns respond REFUSED to multiple queries, strange classes, and strange header bits. pickdns and walldns also respond REFUSED to unrecognized domain names. 20000120 ui: dns_resolvconfip() and dns_resolvconfrewrite() reread after 10 minutes or 10000 uses. ui: dns_resolvconfrewrite() treats "domain" like "search". ui: dns_resolvconfrewrite() supports $LOCALDOMAIN. ui: dns_resolvconfrewrite() supports gethostname(). api: dns_ip4_qualify() -> dns_ip4_qualify_rules(). new function under the old name uses dns_resolvconfrewrite(). internal: cleaned up log.h. 20000121 port: the gcc 2.95.2 -O2 optimizer can destroy parameters in a function that calls another function with a long long argument. impact: gcc 2.95.2 kills dnscache in log_query(). fix: pass log_stats() inputs by reference, and pass uint64's through a variable inside log.c. internal: introduced x_* in axfr-get. internal: more format verification in axfr-get. ui: minimal Z support in tinydns-data. ui: axfr-get prints Z lines. ui: juggled axfr-get to support BIND 8's many-answers option. ui: axfr-get prints common characters readably rather than in octal. tnx Karsten Thygesen. ui: install copies VERSION into .../etc. 20000122 ui: dns_domain_todot_cat() now lowercases everything. internal: split printrecord.c out of tinydns-get. ui: added dnstrace. 20000123 version: dnscache 0.76, beta. 20000124 port: Solaris needs socket libraries for dnstrace. impact: couldn't compile under Solaris. fix: use socket.lib. tnx Karsten Thygesen. 20000126 ui: dns_resolvconfip() supports $DNSCACHEIP. ui: changed tinydns-get arg order. internal: split printpacket.c out of tinydns-get. ui: added dnsquery. internal: merged case.a, fs.a, str.a, uint.a, ip4.a into byte.a. internal: merged strerr.a into buffer.a. internal: merged stralloc.a, getln.a into alloc.a. internal: merged error.a, open.a, seek.a, ndelay.a, socket.a into unix.a. internal: used catulong in axfr-get.c. ui: packet-parsing errors produce error_proto. ui: axfr-get goes out of its way to reject wildcards. internal: introduced generic-conf.c. internal: upgraded timeoutread and timeoutwrite to iopause. 20000127 ui: revamped details of the log formats. ui: full Z support in tinydns-data. ui: axfr-get accepts authority records and additional records. ui: axfrdns tries to imitate BIND's handling of glue. internal: expanded rts to try out the servers and *-conf. ui: added rbldns. 20000128 ui: increased MAXNS to 16 in query.h. 20000129 version: DNScache 0.80, beta. 20000205 ui: tinydns-data supports ^, for the benefit of people stuck behind reverse CNAMEs. tnx Petr Novotny. 20000206 ui: rbldns supports $. ui: tinydns-data supports C. CNAME is overridden by NS; CNAME overrides other records; no multiple CNAMEs. ui: axfr-get supports C. ui: axfr-get no longer rejects wildcards, except for NS. internal: eliminated flagempty from tinydns-data. internal: cleaned up delegation/NXDOMAIN loops in tinydns-data. internal: reorganized packet_start interface in tinydns-data. ui: tinydns-data supports BIND-style wildcards, except for NS. version: DNScache 0.81, beta. 20000207 ui: renamed dnsquery as dnsq, to eliminate name conflict with Beecher dnsquery program. tnx Anand Buddhdev. 20000208 ui: tinydns-edit supports add alias. ui: tinydns-conf sets up root/add-alias. 20000209 ui: dnscache-conf now sets IPSEND=0.0.0.0 in all cases. ui: dnsq and dnstrace allow server names. ui: dnsq and dnstrace allow type names. 20000210 internal: response_tc() reduces len, simplifying udprespond(). ui: response_tc() now truncates immediately after query. this should work around the Squid parsing bug reported by Stuart Henderson. 20000211 ui: tinydns-get allows type names. ui: tinydns-data prints query name for >512 error. tnx Uwe Ohse. version: DNScache 0.82, beta. 20000212 ui: dns_transmit starts with loop 1 for recursive queries. ui: dnscache tries to allocate 128K of incoming UDP buffer space. tnx Jeremy Hansen. 20000213 ui: tinydns tries to allocate 64K of incoming UDP buffer space. internal: renamed response_*answer as response_r*. internal: expanded response_rfinish to allow au and ar. internal: expanded response_rstart to allow any ttl. internal: rewrote tinydns-data, tinydns, tinydns-get, axfrdns for compact new data.cdb format. a few ui effects: empty nodes produce NXDOMAIN; wildcards affect empty nodes. ui: response_addname() tries more extensive compression. 20000215 ui: tinydns-edit takes fn arguments. tnx Jason R. Mastaler. 20000218 internal: upgraded to new cdb library. internal: added globalip(). ui: dnscache assigns IP addresses to dotted-decimal domain names in canonical form. internal: merged handling of C and ^ in tinydns-data. port: FreeBSD 3.4-RELEASE poll() doesn't think that regular files are readable. impact: under FreeBSD 3.4-RELEASE, dnsfilter hangs waiting to read from regular files. tnx Kenji Rikitake. fix: check for this bug in trypoll.c. 20000219 ui: tinydns-data supports time-to-die. ui: changed home directory from /usr/local/dnscache to /usr/local; moved @ from home/etc to home/etc/dnscache. internal: reorganized response.c. 20000220 ui: tinydns-data allows omitted numeric fields in Z lines. tnx Timothy L. Mayo. version: DNScache 0.85, beta. 20000222 ui: dns_transmit_get() pauses after server failure, if udploop is 2. internal: sped up name handling in response.c. 20000223 ui: dnscache ignores some garbage in queries: AA, !RD, RA, Z, RCODE, AN, AU, AR. (note that responses still say RD.) this allows bogus queries from Ultrix versions of BIND. internal: split dd.c out of query.c. internal: split server.c out of tinydns. internal: rewrote walldns, pickdns, rbldns to use server.c. ui: server.c allows some garbage in queries: RA, Z, RCODE, AN, AU, AR. ui: axfrdns logs packets. ui: walldns supports dotted-decimal IP addresses. 20000224 ui: revamped qlog, again. ui: better error message in dnscache-conf.c. tnx Chris Johnson. 20000225 version: DNScache 0.90, gamma. 20000226 internal: dnscache-conf sets up dnscache/run to avoid env. tnx Chris Cappuccio. 20000227 ui: tinydns-data uses server name instead of a.ns.domain for automatic primary in SOA. tnx Frank Tegtmeyer. 20000228 bug: axfrdns doesn't set aa bit in responses. impact: named-xfer refuses to do zone transfers from axfrdns. fix: set aa bit. tnx Peter Hunter. ui: server.c now accepts packets from low ports. sigh. 20000229 version: DNScache 0.91, gamma. 20000307 internal: switched from slurp to openreadclose. 20000308 ui: dns_transmit_get() pauses after recv() failure (such as connection-refused), if udploop is 2. ui: tinydns-data uses refresh 16384, retry 2048, expire 1048576. tnx Frank Tegtmeyer. version: DNScache 0.92, gamma. 20000314 portability problem: the poll() emulation in RedHat 5.1 doesn't clear revents when select() returns 0. tnx Petr Novotny. impact: dns_transmit_get() never times out; dns_resolve() busy-loops. fix: clear revents before poll(). 20000315 ui: axfr-get grabs zones when serials drop. tnx Frank Tegtmeyer. version: DNScache 0.93, gamma. 20000323 ui: dns_rcip() accepts 0.0.0.0 in /etc/resolv.conf as 127.0.0.1. tnx Chris Saia. 20000325 version: DNScache 1.00. 20000914 ui: axfr-get decodes PTR. tnx to various people. ui: added dnsqr. 20000915 portability problem: on some buggy kernels, accept() fails to copy O_NONBLOCK. tnx Pavel Kankovsky. impact: with these kernels, dnscache hangs if a TCP connection times out. fix: ndelay_on() after accept(). ui: dnscache discards non-recursive queries. ui: *-conf use envdir in */run. internal: reorganized seed_addtime() calls in dnscache-conf. ui: tinydns-data prohibits PTR in generic records. 20000917 ui: dns_transmit_get() does not pause after most recv() errors. still pauses after connection-refused when udploop is 2. version: djbdns 1.01. 20000922 portability problem: Linux distributions use bash as /bin/sh; bash destroys $UID. dorks. impact: dnscache and axfrdns run as root. fix: envdir, then sh, then envuidgid. but /bin/sh really has to stop polluting the environment. 20000923 ui: install /etc/dnsroots.global. dnscache-conf tries dnsroots.local, then dnsroots.global. ui: no longer install home/etc/dnscache. version: djbdns 1.02. 20001224 ui: new dnstrace output format. ui: dnstrace shows all servers providing each ns/a line. ui: added dnstracesort. 20001225 internal: response_rstart() and response_cname() use uint32 ttl. internal: added response_hidettl(). internal: cache_get() returns ttl. internal: dnscache keeps track of ttls for aliases. ui: dnscache returns ttl unless $HIDETTL is set. ui: dnscache returns ttl 655360 for localhost et al. 20001226 ui: dnscache supports $FORWARDONLY. tnx to several people for the suggestion. tnx Dan Peterson for sample code. ui: dnscache now logs sequential query numbers, not indices. internal: revamped dnscache to separate udp from tcp. ui: dnscache reports uactive, tactive separately. ui: dnscache reports tcpopen/tcpclose by port and ip. ui: dnscache artificially times out oldest UDP query if UDP table is full, and oldest TCP connection if TCP table is full. ui: dnscache reports broken pipe when a TCP client sends FIN. 20001228 ui: dnstrace supports dd. ui: dnscache logs stats when it handles 1.0.0.127.in-addr.arpa. ui: pickdns actively refuses queries for unknown types. ui: pickdns responds to MX queries. tnx Mike Batchelor. internal: added const at various places. internal: removed some unused variables. internal: used time_t in tai_now.c. internal: used stdlib.h in alloc.c. api: split dns_domain_suffix() into suffix(), suffixpos(). internal: switched to buffer_unix*. internal: included unistd.h for various declarations. 20010103 ui: increased maximum data size from 512 bytes to 32767 bytes in tinydns, tinydns-get, axfrdns. allows big TXT records. ui: dnsmx reformats name when it prints an artificial 0 MX. 20010105 ui: increased MAXLEVEL to 5. the Internet is becoming more glueless every day. 20010106 version: djbdns 1.03. 20010113 ui: increased MAXALIAS to 16. ui: dnscache no longer caches SERVFAIL. per-ip is obviously the way to go. ui: tinydns et al. now respond FORMERR to non-Internet-class queries. ui: tdlookup now returns A records in a random order in the answer section, and truncates the list after 8 records. ui: tinydns-data skips lines starting -. 20010114 internal: documented the tinydns data.cdb format. ui: tinydns-data, tinydns, tinydns-get, axfrdns support client differentiation. ui: dnsqr aborts if it is given an extra argument. 20010117 ui: dnstracesort removes duplicate lines. ui: dnstracesort prints glue. ui: dnstrace uses a ``start'' IP address for the root glue. 20010121 version: djbdns 1.04. 20010206 internal: response_query() takes a class argument. internal: query_start() takes a class argument. internal: packetquery() takes a class argument. ui: tinydns et al., axfrdns, and dnscache repeat qclass * in response to bogus * queries. tnx Mike Batchelor. ui: axfrdns rejects queries for weird classes. ui: axfrdns uses query ID instead of ID 0 in the series of AXFR response messages between the SOAs, to support the AXFR client in BIND 9. ui: axfrdns sets AA in the series of AXFR response messages. 20010211 ui: servers print starting message. internal: some respond() declarations. version: djbdns 1.05. tinydyndns-0.4.2.debian1/FILES000066400000000000000000000051721103424076200160130ustar00rootroot00000000000000README TODO CHANGES VERSION FILES SYSDEPS TARGETS Makefile dnsroots.global TINYDNS conf-cc conf-ld conf-home rts.sh rts.tests rts.exp dnscache-conf.c hasdevtcp.h1 hasdevtcp.h2 dnscache.c server.c walldns-conf.c walldns.c rbldns-conf.c rbldns.c rbldns-data.c pickdns-conf.c pickdns.c pickdns-data.c dnsipq.c tinydns-conf.c tinydns.c tdlookup.c tinydns-get.c tinydns-data.c tinydns-edit.c axfrdns-conf.c axfrdns.c axfr-get.c dnsip.c dnsname.c dnstxt.c dnsmx.c dnsfilter.c random-ip.c dnsqr.c dnsq.c dnstrace.c dnstracesort.sh utime.c cachetest.c generic-conf.h generic-conf.c dd.h dd.c droproot.h droproot.c response.h response.c query.h query.c cache.h cache.c log.h log.c okclient.h okclient.c roots.h roots.c qlog.h qlog.c printrecord.h printrecord.c printpacket.h printpacket.c parsetype.h parsetype.c dns.h dns_dfd.c dns_domain.c dns_dtda.c dns_ip.c dns_ipq.c dns_mx.c dns_name.c dns_nd.c dns_packet.c dns_random.c dns_rcip.c dns_rcrw.c dns_resolve.c dns_sortip.c dns_transmit.c dns_txt.c choose.sh warn-auto.sh find-systype.sh trycpp.c x86cpuid.c alloc.c alloc.h alloc_re.c auto-str.c auto_home.h buffer.c buffer.h buffer_1.c buffer_2.c buffer_copy.c buffer_get.c buffer_put.c byte.h byte_chr.c byte_copy.c byte_cr.c byte_diff.c byte_zero.c case.h case_diffb.c case_diffs.c case_lowerb.c cdb.c cdb.h cdb_hash.c cdb_make.c cdb_make.h chkshsgr.c direntry.h1 direntry.h2 env.c env.h error.c error.h error_str.c exit.h fmt.h fmt_ulong.c gen_alloc.h gen_allocdefs.h getln.c getln.h getln2.c hasshsgr.h1 hasshsgr.h2 hier.c install.c instcheck.c iopause.c iopause.h1 iopause.h2 ip4.h ip4_fmt.c ip4_scan.c ndelay.h ndelay_off.c ndelay_on.c open.h open_read.c open_trunc.c openreadclose.c openreadclose.h prot.c prot.h readclose.c readclose.h scan.h scan_ulong.c seek.h seek_set.c select.h1 select.h2 sgetopt.c sgetopt.h socket.h socket_accept.c socket_bind.c socket_conn.c socket_listen.c socket_recv.c socket_send.c socket_tcp.c socket_udp.c str.h str_chr.c str_diff.c str_len.c str_rchr.c str_start.c stralloc.h stralloc_cat.c stralloc_catb.c stralloc_cats.c stralloc_copy.c stralloc_eady.c stralloc_num.c stralloc_opyb.c stralloc_opys.c stralloc_pend.c strerr.h strerr_die.c strerr_sys.c subgetopt.c subgetopt.h tai.h tai_add.c tai_now.c tai_pack.c tai_sub.c tai_uint.c tai_unpack.c taia.h taia_add.c taia_approx.c taia_frac.c taia_less.c taia_now.c taia_pack.c taia_sub.c taia_tai.c taia_uint.c timeoutread.c timeoutread.h timeoutwrite.c timeoutwrite.h trydrent.c trylsock.c trypoll.c tryshsgr.c trysysel.c tryulong32.c tryulong64.c uint16.h uint16_pack.c uint16_unpack.c uint32.h1 uint32.h2 uint32_pack.c uint32_unpack.c uint64.h1 uint64.h2 warn-shsgr buffer_read.c buffer_write.c tinydyndns-0.4.2.debian1/Makefile000066400000000000000000000020521103424076200166600ustar00rootroot00000000000000tinydyndns: tinydyndns-update tinydyndns-data tinydyndns-update: load tinydyndns-update.o libtai.a env.a cdb.a dns.a \ alloc.a buffer.a unix.a byte.a ./load tinydyndns-update strerr_sys.o strerr_die.o libtai.a env.a \ cdb.a dns.a alloc.a buffer.a unix.a byte.a tinydyndns-update.o: compile tinydyndns-update.c str.h strerr.h cdb.h \ dns.h iopause.h uint64.h uint32.h ./compile tinydyndns-update.c tinydyndns-data: load tinydyndns-data.o libtai.a env.a cdb.a dns.a alloc.a \ buffer.a unix.a byte.a ./load tinydyndns-data strerr_sys.o strerr_die.o libtai.a env.a \ cdb.a dns.a alloc.a buffer.a unix.a byte.a tinydyndns-data.o: compile tinydyndns-data.c uint32.h uint64.h iopause.h ./compile tinydyndns-data.c clean: rm -f `cat TARGETS` \ tinydyndns-update tinydyndns-update.o \ tinydyndns-data tinydyndns-data.o install-tinydyndns: install -m0755 tinydyndns-conf /usr/local/bin/tinydyndns-conf install -m0755 tinydyndns-data /usr/local/bin/tinydyndns-data install -m0755 tinydyndns-update /usr/local/bin/tinydyndns-update include ./Makefile.djbdns tinydyndns-0.4.2.debian1/Makefile.djbdns000066400000000000000000000740171103424076200201350ustar00rootroot00000000000000# Don't edit Makefile! Use conf-* for configuration. SHELL=/bin/sh default: it alloc.a: \ makelib alloc.o alloc_re.o getln.o getln2.o stralloc_cat.o \ stralloc_catb.o stralloc_cats.o stralloc_copy.o stralloc_eady.o \ stralloc_num.o stralloc_opyb.o stralloc_opys.o stralloc_pend.o ./makelib alloc.a alloc.o alloc_re.o getln.o getln2.o \ stralloc_cat.o stralloc_catb.o stralloc_cats.o \ stralloc_copy.o stralloc_eady.o stralloc_num.o \ stralloc_opyb.o stralloc_opys.o stralloc_pend.o alloc.o: \ compile alloc.c alloc.h error.h ./compile alloc.c alloc_re.o: \ compile alloc_re.c alloc.h byte.h ./compile alloc_re.c auto-str: \ load auto-str.o buffer.a unix.a byte.a ./load auto-str buffer.a unix.a byte.a auto-str.o: \ compile auto-str.c buffer.h exit.h ./compile auto-str.c auto_home.c: \ auto-str conf-home ./auto-str auto_home `head -1 conf-home` > auto_home.c auto_home.o: \ compile auto_home.c ./compile auto_home.c axfr-get: \ load axfr-get.o iopause.o timeoutread.o timeoutwrite.o dns.a libtai.a \ alloc.a buffer.a unix.a byte.a ./load axfr-get iopause.o timeoutread.o timeoutwrite.o \ dns.a libtai.a alloc.a buffer.a unix.a byte.a axfr-get.o: \ compile axfr-get.c uint32.h uint16.h stralloc.h gen_alloc.h error.h \ strerr.h getln.h buffer.h stralloc.h buffer.h exit.h open.h scan.h \ byte.h str.h ip4.h timeoutread.h timeoutwrite.h dns.h stralloc.h \ iopause.h taia.h tai.h uint64.h taia.h ./compile axfr-get.c axfrdns: \ load axfrdns.o iopause.o droproot.o tdlookup.o response.o qlog.o \ prot.o timeoutread.o timeoutwrite.o dns.a libtai.a alloc.a env.a \ cdb.a buffer.a unix.a byte.a ./load axfrdns iopause.o droproot.o tdlookup.o response.o \ qlog.o prot.o timeoutread.o timeoutwrite.o dns.a libtai.a \ alloc.a env.a cdb.a buffer.a unix.a byte.a axfrdns-conf: \ load axfrdns-conf.o generic-conf.o auto_home.o buffer.a unix.a byte.a ./load axfrdns-conf generic-conf.o auto_home.o buffer.a \ unix.a byte.a axfrdns-conf.o: \ compile axfrdns-conf.c strerr.h exit.h auto_home.h generic-conf.h \ buffer.h ./compile axfrdns-conf.c axfrdns.o: \ compile axfrdns.c droproot.h exit.h env.h uint32.h uint16.h ip4.h \ tai.h uint64.h buffer.h timeoutread.h timeoutwrite.h open.h seek.h \ cdb.h uint32.h stralloc.h gen_alloc.h strerr.h str.h byte.h case.h \ dns.h stralloc.h iopause.h taia.h tai.h taia.h scan.h qlog.h uint16.h \ response.h uint32.h ./compile axfrdns.c buffer.a: \ makelib buffer.o buffer_1.o buffer_2.o buffer_copy.o buffer_get.o \ buffer_put.o strerr_die.o strerr_sys.o ./makelib buffer.a buffer.o buffer_1.o buffer_2.o \ buffer_copy.o buffer_get.o buffer_put.o strerr_die.o \ strerr_sys.o buffer.o: \ compile buffer.c buffer.h ./compile buffer.c buffer_1.o: \ compile buffer_1.c buffer.h ./compile buffer_1.c buffer_2.o: \ compile buffer_2.c buffer.h ./compile buffer_2.c buffer_copy.o: \ compile buffer_copy.c buffer.h ./compile buffer_copy.c buffer_get.o: \ compile buffer_get.c buffer.h byte.h error.h ./compile buffer_get.c buffer_put.o: \ compile buffer_put.c buffer.h str.h byte.h error.h ./compile buffer_put.c buffer_read.o: \ compile buffer_read.c buffer.h ./compile buffer_read.c buffer_write.o: \ compile buffer_write.c buffer.h ./compile buffer_write.c byte.a: \ makelib byte_chr.o byte_copy.o byte_cr.o byte_diff.o byte_zero.o \ case_diffb.o case_diffs.o case_lowerb.o fmt_ulong.o ip4_fmt.o \ ip4_scan.o scan_ulong.o str_chr.o str_diff.o str_len.o str_rchr.o \ str_start.o uint16_pack.o uint16_unpack.o uint32_pack.o \ uint32_unpack.o ./makelib byte.a byte_chr.o byte_copy.o byte_cr.o \ byte_diff.o byte_zero.o case_diffb.o case_diffs.o \ case_lowerb.o fmt_ulong.o ip4_fmt.o ip4_scan.o scan_ulong.o \ str_chr.o str_diff.o str_len.o str_rchr.o str_start.o \ uint16_pack.o uint16_unpack.o uint32_pack.o uint32_unpack.o byte_chr.o: \ compile byte_chr.c byte.h ./compile byte_chr.c byte_copy.o: \ compile byte_copy.c byte.h ./compile byte_copy.c byte_cr.o: \ compile byte_cr.c byte.h ./compile byte_cr.c byte_diff.o: \ compile byte_diff.c byte.h ./compile byte_diff.c byte_zero.o: \ compile byte_zero.c byte.h ./compile byte_zero.c cache.o: \ compile cache.c alloc.h byte.h uint32.h exit.h tai.h uint64.h cache.h \ uint32.h uint64.h ./compile cache.c cachetest: \ load cachetest.o cache.o libtai.a buffer.a alloc.a unix.a byte.a ./load cachetest cache.o libtai.a buffer.a alloc.a unix.a \ byte.a cachetest.o: \ compile cachetest.c buffer.h exit.h cache.h uint32.h uint64.h str.h ./compile cachetest.c case_diffb.o: \ compile case_diffb.c case.h ./compile case_diffb.c case_diffs.o: \ compile case_diffs.c case.h ./compile case_diffs.c case_lowerb.o: \ compile case_lowerb.c case.h ./compile case_lowerb.c cdb.a: \ makelib cdb.o cdb_hash.o cdb_make.o ./makelib cdb.a cdb.o cdb_hash.o cdb_make.o cdb.o: \ compile cdb.c error.h seek.h byte.h cdb.h uint32.h ./compile cdb.c cdb_hash.o: \ compile cdb_hash.c cdb.h uint32.h ./compile cdb_hash.c cdb_make.o: \ compile cdb_make.c seek.h error.h alloc.h cdb.h uint32.h cdb_make.h \ buffer.h uint32.h ./compile cdb_make.c check: \ it instcheck ./instcheck chkshsgr: \ load chkshsgr.o ./load chkshsgr chkshsgr.o: \ compile chkshsgr.c exit.h ./compile chkshsgr.c choose: \ warn-auto.sh choose.sh conf-home cat warn-auto.sh choose.sh \ | sed s}HOME}"`head -1 conf-home`"}g \ > choose chmod 755 choose compile: \ warn-auto.sh conf-cc ( cat warn-auto.sh; \ echo exec "`head -1 conf-cc`" '-c $${1+"$$@"}' \ ) > compile chmod 755 compile dd.o: \ compile dd.c dns.h stralloc.h gen_alloc.h iopause.h taia.h tai.h \ uint64.h taia.h dd.h ./compile dd.c direntry.h: \ choose compile trydrent.c direntry.h1 direntry.h2 ./choose c trydrent direntry.h1 direntry.h2 > direntry.h dns.a: \ makelib dns_dfd.o dns_domain.o dns_dtda.o dns_ip.o dns_ipq.o dns_mx.o \ dns_name.o dns_nd.o dns_packet.o dns_random.o dns_rcip.o dns_rcrw.o \ dns_resolve.o dns_sortip.o dns_transmit.o dns_txt.o ./makelib dns.a dns_dfd.o dns_domain.o dns_dtda.o dns_ip.o \ dns_ipq.o dns_mx.o dns_name.o dns_nd.o dns_packet.o \ dns_random.o dns_rcip.o dns_rcrw.o dns_resolve.o \ dns_sortip.o dns_transmit.o dns_txt.o dns_dfd.o: \ compile dns_dfd.c error.h alloc.h byte.h dns.h stralloc.h gen_alloc.h \ iopause.h taia.h tai.h uint64.h taia.h ./compile dns_dfd.c dns_domain.o: \ compile dns_domain.c error.h alloc.h case.h byte.h dns.h stralloc.h \ gen_alloc.h iopause.h taia.h tai.h uint64.h taia.h ./compile dns_domain.c dns_dtda.o: \ compile dns_dtda.c stralloc.h gen_alloc.h dns.h stralloc.h iopause.h \ taia.h tai.h uint64.h taia.h ./compile dns_dtda.c dns_ip.o: \ compile dns_ip.c stralloc.h gen_alloc.h uint16.h byte.h dns.h \ stralloc.h iopause.h taia.h tai.h uint64.h taia.h ./compile dns_ip.c dns_ipq.o: \ compile dns_ipq.c stralloc.h gen_alloc.h case.h byte.h str.h dns.h \ stralloc.h iopause.h taia.h tai.h uint64.h taia.h ./compile dns_ipq.c dns_mx.o: \ compile dns_mx.c stralloc.h gen_alloc.h byte.h uint16.h dns.h \ stralloc.h iopause.h taia.h tai.h uint64.h taia.h ./compile dns_mx.c dns_name.o: \ compile dns_name.c stralloc.h gen_alloc.h uint16.h byte.h dns.h \ stralloc.h iopause.h taia.h tai.h uint64.h taia.h ./compile dns_name.c dns_nd.o: \ compile dns_nd.c byte.h fmt.h dns.h stralloc.h gen_alloc.h iopause.h \ taia.h tai.h uint64.h taia.h ./compile dns_nd.c dns_packet.o: \ compile dns_packet.c error.h dns.h stralloc.h gen_alloc.h iopause.h \ taia.h tai.h uint64.h taia.h ./compile dns_packet.c dns_random.o: \ compile dns_random.c dns.h stralloc.h gen_alloc.h iopause.h taia.h \ tai.h uint64.h taia.h taia.h uint32.h ./compile dns_random.c dns_rcip.o: \ compile dns_rcip.c taia.h tai.h uint64.h openreadclose.h stralloc.h \ gen_alloc.h byte.h ip4.h env.h dns.h stralloc.h iopause.h taia.h \ taia.h ./compile dns_rcip.c dns_rcrw.o: \ compile dns_rcrw.c taia.h tai.h uint64.h env.h byte.h str.h \ openreadclose.h stralloc.h gen_alloc.h dns.h stralloc.h iopause.h \ taia.h taia.h ./compile dns_rcrw.c dns_resolve.o: \ compile dns_resolve.c iopause.h taia.h tai.h uint64.h taia.h byte.h \ dns.h stralloc.h gen_alloc.h iopause.h taia.h ./compile dns_resolve.c dns_sortip.o: \ compile dns_sortip.c byte.h dns.h stralloc.h gen_alloc.h iopause.h \ taia.h tai.h uint64.h taia.h ./compile dns_sortip.c dns_transmit.o: \ compile dns_transmit.c socket.h uint16.h alloc.h error.h byte.h \ uint16.h dns.h stralloc.h gen_alloc.h iopause.h taia.h tai.h uint64.h \ taia.h ./compile dns_transmit.c dns_txt.o: \ compile dns_txt.c stralloc.h gen_alloc.h uint16.h byte.h dns.h \ stralloc.h iopause.h taia.h tai.h uint64.h taia.h ./compile dns_txt.c dnscache: \ load dnscache.o droproot.o okclient.o log.o cache.o query.o \ response.o dd.o roots.o iopause.o prot.o dns.a env.a alloc.a buffer.a \ libtai.a unix.a byte.a socket.lib ./load dnscache droproot.o okclient.o log.o cache.o \ query.o response.o dd.o roots.o iopause.o prot.o dns.a \ env.a alloc.a buffer.a libtai.a unix.a byte.a `cat \ socket.lib` dnscache-conf: \ load dnscache-conf.o generic-conf.o auto_home.o libtai.a buffer.a \ unix.a byte.a ./load dnscache-conf generic-conf.o auto_home.o libtai.a \ buffer.a unix.a byte.a dnscache-conf.o: \ compile dnscache-conf.c hasdevtcp.h strerr.h buffer.h uint32.h taia.h \ tai.h uint64.h str.h open.h error.h exit.h auto_home.h generic-conf.h \ buffer.h ./compile dnscache-conf.c dnscache.o: \ compile dnscache.c env.h exit.h scan.h strerr.h error.h ip4.h \ uint16.h uint64.h socket.h uint16.h dns.h stralloc.h gen_alloc.h \ iopause.h taia.h tai.h uint64.h taia.h taia.h byte.h roots.h fmt.h \ iopause.h query.h dns.h uint32.h alloc.h response.h uint32.h cache.h \ uint32.h uint64.h ndelay.h log.h uint64.h okclient.h droproot.h ./compile dnscache.c dnsfilter: \ load dnsfilter.o iopause.o getopt.a dns.a env.a libtai.a alloc.a \ buffer.a unix.a byte.a socket.lib ./load dnsfilter iopause.o getopt.a dns.a env.a libtai.a \ alloc.a buffer.a unix.a byte.a `cat socket.lib` dnsfilter.o: \ compile dnsfilter.c strerr.h buffer.h stralloc.h gen_alloc.h alloc.h \ dns.h stralloc.h iopause.h taia.h tai.h uint64.h taia.h ip4.h byte.h \ scan.h taia.h sgetopt.h subgetopt.h iopause.h error.h exit.h ./compile dnsfilter.c dnsip: \ load dnsip.o iopause.o dns.a env.a libtai.a alloc.a buffer.a unix.a \ byte.a socket.lib ./load dnsip iopause.o dns.a env.a libtai.a alloc.a \ buffer.a unix.a byte.a `cat socket.lib` dnsip.o: \ compile dnsip.c buffer.h exit.h strerr.h ip4.h dns.h stralloc.h \ gen_alloc.h iopause.h taia.h tai.h uint64.h taia.h ./compile dnsip.c dnsipq: \ load dnsipq.o iopause.o dns.a env.a libtai.a alloc.a buffer.a unix.a \ byte.a socket.lib ./load dnsipq iopause.o dns.a env.a libtai.a alloc.a \ buffer.a unix.a byte.a `cat socket.lib` dnsipq.o: \ compile dnsipq.c buffer.h exit.h strerr.h ip4.h dns.h stralloc.h \ gen_alloc.h iopause.h taia.h tai.h uint64.h taia.h ./compile dnsipq.c dnsmx: \ load dnsmx.o iopause.o dns.a env.a libtai.a alloc.a buffer.a unix.a \ byte.a socket.lib ./load dnsmx iopause.o dns.a env.a libtai.a alloc.a \ buffer.a unix.a byte.a `cat socket.lib` dnsmx.o: \ compile dnsmx.c buffer.h exit.h strerr.h uint16.h byte.h str.h fmt.h \ dns.h stralloc.h gen_alloc.h iopause.h taia.h tai.h uint64.h taia.h ./compile dnsmx.c dnsname: \ load dnsname.o iopause.o dns.a env.a libtai.a alloc.a buffer.a unix.a \ byte.a socket.lib ./load dnsname iopause.o dns.a env.a libtai.a alloc.a \ buffer.a unix.a byte.a `cat socket.lib` dnsname.o: \ compile dnsname.c buffer.h exit.h strerr.h ip4.h dns.h stralloc.h \ gen_alloc.h iopause.h taia.h tai.h uint64.h taia.h ./compile dnsname.c dnsq: \ load dnsq.o iopause.o printrecord.o printpacket.o parsetype.o dns.a \ env.a libtai.a buffer.a alloc.a unix.a byte.a socket.lib ./load dnsq iopause.o printrecord.o printpacket.o \ parsetype.o dns.a env.a libtai.a buffer.a alloc.a unix.a \ byte.a `cat socket.lib` dnsq.o: \ compile dnsq.c uint16.h strerr.h buffer.h scan.h str.h byte.h error.h \ ip4.h iopause.h taia.h tai.h uint64.h printpacket.h stralloc.h \ gen_alloc.h parsetype.h dns.h stralloc.h iopause.h taia.h ./compile dnsq.c dnsqr: \ load dnsqr.o iopause.o printrecord.o printpacket.o parsetype.o dns.a \ env.a libtai.a buffer.a alloc.a unix.a byte.a socket.lib ./load dnsqr iopause.o printrecord.o printpacket.o \ parsetype.o dns.a env.a libtai.a buffer.a alloc.a unix.a \ byte.a `cat socket.lib` dnsqr.o: \ compile dnsqr.c uint16.h strerr.h buffer.h scan.h str.h byte.h \ error.h iopause.h taia.h tai.h uint64.h printpacket.h stralloc.h \ gen_alloc.h parsetype.h dns.h stralloc.h iopause.h taia.h ./compile dnsqr.c dnstrace: \ load dnstrace.o dd.o iopause.o printrecord.o parsetype.o dns.a env.a \ libtai.a alloc.a buffer.a unix.a byte.a socket.lib ./load dnstrace dd.o iopause.o printrecord.o parsetype.o \ dns.a env.a libtai.a alloc.a buffer.a unix.a byte.a `cat \ socket.lib` dnstrace.o: \ compile dnstrace.c uint16.h uint32.h fmt.h str.h byte.h ip4.h \ gen_alloc.h gen_allocdefs.h exit.h buffer.h stralloc.h gen_alloc.h \ error.h strerr.h iopause.h taia.h tai.h uint64.h printrecord.h \ stralloc.h alloc.h parsetype.h dd.h dns.h stralloc.h iopause.h taia.h ./compile dnstrace.c dnstracesort: \ warn-auto.sh dnstracesort.sh conf-home cat warn-auto.sh dnstracesort.sh \ | sed s}HOME}"`head -1 conf-home`"}g \ > dnstracesort chmod 755 dnstracesort dnstxt: \ load dnstxt.o iopause.o dns.a env.a libtai.a alloc.a buffer.a unix.a \ byte.a socket.lib ./load dnstxt iopause.o dns.a env.a libtai.a alloc.a \ buffer.a unix.a byte.a `cat socket.lib` dnstxt.o: \ compile dnstxt.c buffer.h exit.h strerr.h dns.h stralloc.h \ gen_alloc.h iopause.h taia.h tai.h uint64.h taia.h ./compile dnstxt.c droproot.o: \ compile droproot.c env.h scan.h prot.h strerr.h ./compile droproot.c env.a: \ makelib env.o ./makelib env.a env.o env.o: \ compile env.c str.h env.h ./compile env.c error.o: \ compile error.c error.h ./compile error.c error_str.o: \ compile error_str.c error.h ./compile error_str.c fmt_ulong.o: \ compile fmt_ulong.c fmt.h ./compile fmt_ulong.c generic-conf.o: \ compile generic-conf.c strerr.h buffer.h open.h generic-conf.h \ buffer.h ./compile generic-conf.c getln.o: \ compile getln.c byte.h getln.h buffer.h stralloc.h gen_alloc.h ./compile getln.c getln2.o: \ compile getln2.c byte.h getln.h buffer.h stralloc.h gen_alloc.h ./compile getln2.c getopt.a: \ makelib sgetopt.o subgetopt.o ./makelib getopt.a sgetopt.o subgetopt.o hasdevtcp.h: \ systype hasdevtcp.h1 hasdevtcp.h2 ( case "`cat systype`" in \ sunos-5.*) cat hasdevtcp.h2 ;; \ *) cat hasdevtcp.h1 ;; \ esac ) > hasdevtcp.h hasshsgr.h: \ choose compile load tryshsgr.c hasshsgr.h1 hasshsgr.h2 chkshsgr \ warn-shsgr ./chkshsgr || ( cat warn-shsgr; exit 1 ) ./choose clr tryshsgr hasshsgr.h1 hasshsgr.h2 > hasshsgr.h hier.o: \ compile hier.c auto_home.h ./compile hier.c install: \ load install.o hier.o auto_home.o buffer.a unix.a byte.a ./load install hier.o auto_home.o buffer.a unix.a byte.a install.o: \ compile install.c buffer.h strerr.h error.h open.h exit.h ./compile install.c instcheck: \ load instcheck.o hier.o auto_home.o buffer.a unix.a byte.a ./load instcheck hier.o auto_home.o buffer.a unix.a byte.a instcheck.o: \ compile instcheck.c strerr.h error.h exit.h ./compile instcheck.c iopause.h: \ choose compile load trypoll.c iopause.h1 iopause.h2 ./choose clr trypoll iopause.h1 iopause.h2 > iopause.h iopause.o: \ compile iopause.c taia.h tai.h uint64.h select.h iopause.h taia.h ./compile iopause.c ip4_fmt.o: \ compile ip4_fmt.c fmt.h ip4.h ./compile ip4_fmt.c ip4_scan.o: \ compile ip4_scan.c scan.h ip4.h ./compile ip4_scan.c it: \ prog install instcheck libtai.a: \ makelib tai_add.o tai_now.o tai_pack.o tai_sub.o tai_uint.o \ tai_unpack.o taia_add.o taia_approx.o taia_frac.o taia_less.o \ taia_now.o taia_pack.o taia_sub.o taia_tai.o taia_uint.o ./makelib libtai.a tai_add.o tai_now.o tai_pack.o \ tai_sub.o tai_uint.o tai_unpack.o taia_add.o taia_approx.o \ taia_frac.o taia_less.o taia_now.o taia_pack.o taia_sub.o \ taia_tai.o taia_uint.o load: \ warn-auto.sh conf-ld ( cat warn-auto.sh; \ echo 'main="$$1"; shift'; \ echo exec "`head -1 conf-ld`" \ '-o "$$main" "$$main".o $${1+"$$@"}' \ ) > load chmod 755 load log.o: \ compile log.c buffer.h uint32.h uint16.h error.h byte.h log.h \ uint64.h ./compile log.c makelib: \ warn-auto.sh systype ( cat warn-auto.sh; \ echo 'main="$$1"; shift'; \ echo 'rm -f "$$main"'; \ echo 'ar cr "$$main" $${1+"$$@"}'; \ case "`cat systype`" in \ sunos-5.*) ;; \ unix_sv*) ;; \ irix64-*) ;; \ irix-*) ;; \ dgux-*) ;; \ hp-ux-*) ;; \ sco*) ;; \ *) echo 'ranlib "$$main"' ;; \ esac \ ) > makelib chmod 755 makelib ndelay_off.o: \ compile ndelay_off.c ndelay.h ./compile ndelay_off.c ndelay_on.o: \ compile ndelay_on.c ndelay.h ./compile ndelay_on.c okclient.o: \ compile okclient.c str.h ip4.h okclient.h ./compile okclient.c open_read.o: \ compile open_read.c open.h ./compile open_read.c open_trunc.o: \ compile open_trunc.c open.h ./compile open_trunc.c openreadclose.o: \ compile openreadclose.c error.h open.h readclose.h stralloc.h \ gen_alloc.h openreadclose.h stralloc.h ./compile openreadclose.c parsetype.o: \ compile parsetype.c scan.h byte.h case.h dns.h stralloc.h gen_alloc.h \ iopause.h taia.h tai.h uint64.h taia.h uint16.h parsetype.h ./compile parsetype.c pickdns: \ load pickdns.o server.o response.o droproot.o qlog.o prot.o dns.a \ env.a libtai.a cdb.a alloc.a buffer.a unix.a byte.a socket.lib ./load pickdns server.o response.o droproot.o qlog.o \ prot.o dns.a env.a libtai.a cdb.a alloc.a buffer.a unix.a \ byte.a `cat socket.lib` pickdns-conf: \ load pickdns-conf.o generic-conf.o auto_home.o buffer.a unix.a byte.a ./load pickdns-conf generic-conf.o auto_home.o buffer.a \ unix.a byte.a pickdns-conf.o: \ compile pickdns-conf.c strerr.h exit.h auto_home.h generic-conf.h \ buffer.h ./compile pickdns-conf.c pickdns-data: \ load pickdns-data.o cdb.a dns.a alloc.a buffer.a unix.a byte.a ./load pickdns-data cdb.a dns.a alloc.a buffer.a unix.a \ byte.a pickdns-data.o: \ compile pickdns-data.c buffer.h exit.h cdb_make.h buffer.h uint32.h \ open.h alloc.h gen_allocdefs.h stralloc.h gen_alloc.h getln.h \ buffer.h stralloc.h case.h strerr.h str.h byte.h scan.h fmt.h ip4.h \ dns.h stralloc.h iopause.h taia.h tai.h uint64.h taia.h ./compile pickdns-data.c pickdns.o: \ compile pickdns.c byte.h case.h dns.h stralloc.h gen_alloc.h \ iopause.h taia.h tai.h uint64.h taia.h open.h cdb.h uint32.h \ response.h uint32.h ./compile pickdns.c printpacket.o: \ compile printpacket.c uint16.h uint32.h error.h byte.h dns.h \ stralloc.h gen_alloc.h iopause.h taia.h tai.h uint64.h taia.h \ printrecord.h stralloc.h printpacket.h stralloc.h ./compile printpacket.c printrecord.o: \ compile printrecord.c uint16.h uint32.h error.h byte.h dns.h \ stralloc.h gen_alloc.h iopause.h taia.h tai.h uint64.h taia.h \ printrecord.h stralloc.h ./compile printrecord.c prog: \ dnscache-conf dnscache walldns-conf walldns rbldns-conf rbldns \ rbldns-data pickdns-conf pickdns pickdns-data tinydns-conf tinydns \ tinydns-data tinydns-get tinydns-edit axfr-get axfrdns-conf axfrdns \ dnsip dnsipq dnsname dnstxt dnsmx dnsfilter random-ip dnsqr dnsq \ dnstrace dnstracesort cachetest utime rts prot.o: \ compile prot.c hasshsgr.h prot.h ./compile prot.c qlog.o: \ compile qlog.c buffer.h qlog.h uint16.h ./compile qlog.c query.o: \ compile query.c error.h roots.h log.h uint64.h case.h cache.h \ uint32.h uint64.h byte.h dns.h stralloc.h gen_alloc.h iopause.h \ taia.h tai.h uint64.h taia.h uint64.h uint32.h uint16.h dd.h alloc.h \ response.h uint32.h query.h dns.h uint32.h ./compile query.c random-ip: \ load random-ip.o dns.a libtai.a buffer.a unix.a byte.a ./load random-ip dns.a libtai.a buffer.a unix.a byte.a random-ip.o: \ compile random-ip.c buffer.h exit.h fmt.h scan.h dns.h stralloc.h \ gen_alloc.h iopause.h taia.h tai.h uint64.h taia.h ./compile random-ip.c rbldns: \ load rbldns.o server.o response.o dd.o droproot.o qlog.o prot.o dns.a \ env.a libtai.a cdb.a alloc.a buffer.a unix.a byte.a socket.lib ./load rbldns server.o response.o dd.o droproot.o qlog.o \ prot.o dns.a env.a libtai.a cdb.a alloc.a buffer.a unix.a \ byte.a `cat socket.lib` rbldns-conf: \ load rbldns-conf.o generic-conf.o auto_home.o buffer.a unix.a byte.a ./load rbldns-conf generic-conf.o auto_home.o buffer.a \ unix.a byte.a rbldns-conf.o: \ compile rbldns-conf.c strerr.h exit.h auto_home.h generic-conf.h \ buffer.h ./compile rbldns-conf.c rbldns-data: \ load rbldns-data.o cdb.a alloc.a buffer.a unix.a byte.a ./load rbldns-data cdb.a alloc.a buffer.a unix.a byte.a rbldns-data.o: \ compile rbldns-data.c buffer.h exit.h cdb_make.h buffer.h uint32.h \ open.h stralloc.h gen_alloc.h getln.h buffer.h stralloc.h strerr.h \ byte.h scan.h fmt.h ip4.h ./compile rbldns-data.c rbldns.o: \ compile rbldns.c str.h byte.h ip4.h open.h env.h cdb.h uint32.h dns.h \ stralloc.h gen_alloc.h iopause.h taia.h tai.h uint64.h taia.h dd.h \ strerr.h response.h uint32.h ./compile rbldns.c readclose.o: \ compile readclose.c error.h readclose.h stralloc.h gen_alloc.h ./compile readclose.c response.o: \ compile response.c dns.h stralloc.h gen_alloc.h iopause.h taia.h \ tai.h uint64.h taia.h byte.h uint16.h response.h uint32.h ./compile response.c roots.o: \ compile roots.c open.h error.h str.h byte.h error.h direntry.h ip4.h \ dns.h stralloc.h gen_alloc.h iopause.h taia.h tai.h uint64.h taia.h \ openreadclose.h stralloc.h roots.h ./compile roots.c rts: \ warn-auto.sh rts.sh conf-home cat warn-auto.sh rts.sh \ | sed s}HOME}"`head -1 conf-home`"}g \ > rts chmod 755 rts scan_ulong.o: \ compile scan_ulong.c scan.h ./compile scan_ulong.c seek_set.o: \ compile seek_set.c seek.h ./compile seek_set.c select.h: \ choose compile trysysel.c select.h1 select.h2 ./choose c trysysel select.h1 select.h2 > select.h server.o: \ compile server.c byte.h case.h env.h buffer.h strerr.h ip4.h uint16.h \ ndelay.h socket.h uint16.h droproot.h qlog.h uint16.h response.h \ uint32.h dns.h stralloc.h gen_alloc.h iopause.h taia.h tai.h uint64.h \ taia.h ./compile server.c setup: \ it install ./install sgetopt.o: \ compile sgetopt.c buffer.h sgetopt.h subgetopt.h subgetopt.h ./compile sgetopt.c socket.lib: \ trylsock.c compile load ( ( ./compile trylsock.c && \ ./load trylsock -lsocket -lnsl ) >/dev/null 2>&1 \ && echo -lsocket -lnsl || exit 0 ) > socket.lib rm -f trylsock.o trylsock socket_accept.o: \ compile socket_accept.c byte.h socket.h uint16.h ./compile socket_accept.c socket_bind.o: \ compile socket_bind.c byte.h socket.h uint16.h ./compile socket_bind.c socket_conn.o: \ compile socket_conn.c byte.h socket.h uint16.h ./compile socket_conn.c socket_listen.o: \ compile socket_listen.c socket.h uint16.h ./compile socket_listen.c socket_recv.o: \ compile socket_recv.c byte.h socket.h uint16.h ./compile socket_recv.c socket_send.o: \ compile socket_send.c byte.h socket.h uint16.h ./compile socket_send.c socket_tcp.o: \ compile socket_tcp.c ndelay.h socket.h uint16.h ./compile socket_tcp.c socket_udp.o: \ compile socket_udp.c ndelay.h socket.h uint16.h ./compile socket_udp.c str_chr.o: \ compile str_chr.c str.h ./compile str_chr.c str_diff.o: \ compile str_diff.c str.h ./compile str_diff.c str_len.o: \ compile str_len.c str.h ./compile str_len.c str_rchr.o: \ compile str_rchr.c str.h ./compile str_rchr.c str_start.o: \ compile str_start.c str.h ./compile str_start.c stralloc_cat.o: \ compile stralloc_cat.c byte.h stralloc.h gen_alloc.h ./compile stralloc_cat.c stralloc_catb.o: \ compile stralloc_catb.c stralloc.h gen_alloc.h byte.h ./compile stralloc_catb.c stralloc_cats.o: \ compile stralloc_cats.c byte.h str.h stralloc.h gen_alloc.h ./compile stralloc_cats.c stralloc_copy.o: \ compile stralloc_copy.c byte.h stralloc.h gen_alloc.h ./compile stralloc_copy.c stralloc_eady.o: \ compile stralloc_eady.c alloc.h stralloc.h gen_alloc.h \ gen_allocdefs.h ./compile stralloc_eady.c stralloc_num.o: \ compile stralloc_num.c stralloc.h gen_alloc.h ./compile stralloc_num.c stralloc_opyb.o: \ compile stralloc_opyb.c stralloc.h gen_alloc.h byte.h ./compile stralloc_opyb.c stralloc_opys.o: \ compile stralloc_opys.c byte.h str.h stralloc.h gen_alloc.h ./compile stralloc_opys.c stralloc_pend.o: \ compile stralloc_pend.c alloc.h stralloc.h gen_alloc.h \ gen_allocdefs.h ./compile stralloc_pend.c strerr_die.o: \ compile strerr_die.c buffer.h exit.h strerr.h ./compile strerr_die.c strerr_sys.o: \ compile strerr_sys.c error.h strerr.h ./compile strerr_sys.c subgetopt.o: \ compile subgetopt.c subgetopt.h ./compile subgetopt.c systype: \ find-systype.sh conf-cc conf-ld trycpp.c x86cpuid.c ( cat warn-auto.sh; \ echo CC=\'`head -1 conf-cc`\'; \ echo LD=\'`head -1 conf-ld`\'; \ cat find-systype.sh; \ ) | sh > systype tai_add.o: \ compile tai_add.c tai.h uint64.h ./compile tai_add.c tai_now.o: \ compile tai_now.c tai.h uint64.h ./compile tai_now.c tai_pack.o: \ compile tai_pack.c tai.h uint64.h ./compile tai_pack.c tai_sub.o: \ compile tai_sub.c tai.h uint64.h ./compile tai_sub.c tai_uint.o: \ compile tai_uint.c tai.h uint64.h ./compile tai_uint.c tai_unpack.o: \ compile tai_unpack.c tai.h uint64.h ./compile tai_unpack.c taia_add.o: \ compile taia_add.c taia.h tai.h uint64.h ./compile taia_add.c taia_approx.o: \ compile taia_approx.c taia.h tai.h uint64.h ./compile taia_approx.c taia_frac.o: \ compile taia_frac.c taia.h tai.h uint64.h ./compile taia_frac.c taia_less.o: \ compile taia_less.c taia.h tai.h uint64.h ./compile taia_less.c taia_now.o: \ compile taia_now.c taia.h tai.h uint64.h ./compile taia_now.c taia_pack.o: \ compile taia_pack.c taia.h tai.h uint64.h ./compile taia_pack.c taia_sub.o: \ compile taia_sub.c taia.h tai.h uint64.h ./compile taia_sub.c taia_tai.o: \ compile taia_tai.c taia.h tai.h uint64.h ./compile taia_tai.c taia_uint.o: \ compile taia_uint.c taia.h tai.h uint64.h ./compile taia_uint.c tdlookup.o: \ compile tdlookup.c uint16.h open.h tai.h uint64.h cdb.h uint32.h \ byte.h case.h dns.h stralloc.h gen_alloc.h iopause.h taia.h tai.h \ taia.h seek.h response.h uint32.h ./compile tdlookup.c timeoutread.o: \ compile timeoutread.c error.h iopause.h taia.h tai.h uint64.h \ timeoutread.h ./compile timeoutread.c timeoutwrite.o: \ compile timeoutwrite.c error.h iopause.h taia.h tai.h uint64.h \ timeoutwrite.h ./compile timeoutwrite.c tinydns: \ load tinydns.o server.o droproot.o tdlookup.o response.o qlog.o \ prot.o dns.a libtai.a env.a cdb.a alloc.a buffer.a unix.a byte.a \ socket.lib ./load tinydns server.o droproot.o tdlookup.o response.o \ qlog.o prot.o dns.a libtai.a env.a cdb.a alloc.a buffer.a \ unix.a byte.a `cat socket.lib` tinydns-conf: \ load tinydns-conf.o generic-conf.o auto_home.o buffer.a unix.a byte.a ./load tinydns-conf generic-conf.o auto_home.o buffer.a \ unix.a byte.a tinydns-conf.o: \ compile tinydns-conf.c strerr.h exit.h auto_home.h generic-conf.h \ buffer.h ./compile tinydns-conf.c tinydns-data: \ load tinydns-data.o cdb.a dns.a alloc.a buffer.a unix.a byte.a ./load tinydns-data cdb.a dns.a alloc.a buffer.a unix.a \ byte.a tinydns-data.o: \ compile tinydns-data.c uint16.h uint32.h str.h byte.h fmt.h ip4.h \ exit.h case.h scan.h buffer.h strerr.h getln.h buffer.h stralloc.h \ gen_alloc.h cdb_make.h buffer.h uint32.h stralloc.h open.h dns.h \ stralloc.h iopause.h taia.h tai.h uint64.h taia.h ./compile tinydns-data.c tinydns-edit: \ load tinydns-edit.o dns.a alloc.a buffer.a unix.a byte.a ./load tinydns-edit dns.a alloc.a buffer.a unix.a byte.a tinydns-edit.o: \ compile tinydns-edit.c stralloc.h gen_alloc.h buffer.h exit.h open.h \ getln.h buffer.h stralloc.h strerr.h scan.h byte.h str.h fmt.h ip4.h \ dns.h stralloc.h iopause.h taia.h tai.h uint64.h taia.h ./compile tinydns-edit.c tinydns-get: \ load tinydns-get.o tdlookup.o response.o printpacket.o printrecord.o \ parsetype.o dns.a libtai.a cdb.a buffer.a alloc.a unix.a byte.a ./load tinydns-get tdlookup.o response.o printpacket.o \ printrecord.o parsetype.o dns.a libtai.a cdb.a buffer.a \ alloc.a unix.a byte.a tinydns-get.o: \ compile tinydns-get.c str.h byte.h scan.h exit.h stralloc.h \ gen_alloc.h buffer.h strerr.h uint16.h response.h uint32.h case.h \ printpacket.h stralloc.h parsetype.h ip4.h dns.h stralloc.h iopause.h \ taia.h tai.h uint64.h taia.h ./compile tinydns-get.c tinydns.o: \ compile tinydns.c dns.h stralloc.h gen_alloc.h iopause.h taia.h tai.h \ uint64.h taia.h ./compile tinydns.c uint16_pack.o: \ compile uint16_pack.c uint16.h ./compile uint16_pack.c uint16_unpack.o: \ compile uint16_unpack.c uint16.h ./compile uint16_unpack.c uint32.h: \ tryulong32.c compile load uint32.h1 uint32.h2 ( ( ./compile tryulong32.c && ./load tryulong32 && \ ./tryulong32 ) >/dev/null 2>&1 \ && cat uint32.h2 || cat uint32.h1 ) > uint32.h rm -f tryulong32.o tryulong32 uint32_pack.o: \ compile uint32_pack.c uint32.h ./compile uint32_pack.c uint32_unpack.o: \ compile uint32_unpack.c uint32.h ./compile uint32_unpack.c uint64.h: \ choose compile load tryulong64.c uint64.h1 uint64.h2 ./choose clr tryulong64 uint64.h1 uint64.h2 > uint64.h unix.a: \ makelib buffer_read.o buffer_write.o error.o error_str.o ndelay_off.o \ ndelay_on.o open_read.o open_trunc.o openreadclose.o readclose.o \ seek_set.o socket_accept.o socket_bind.o socket_conn.o \ socket_listen.o socket_recv.o socket_send.o socket_tcp.o socket_udp.o ./makelib unix.a buffer_read.o buffer_write.o error.o \ error_str.o ndelay_off.o ndelay_on.o open_read.o \ open_trunc.o openreadclose.o readclose.o seek_set.o \ socket_accept.o socket_bind.o socket_conn.o socket_listen.o \ socket_recv.o socket_send.o socket_tcp.o socket_udp.o utime: \ load utime.o byte.a ./load utime byte.a utime.o: \ compile utime.c scan.h exit.h ./compile utime.c walldns: \ load walldns.o server.o response.o droproot.o qlog.o prot.o dd.o \ dns.a env.a cdb.a alloc.a buffer.a unix.a byte.a socket.lib ./load walldns server.o response.o droproot.o qlog.o \ prot.o dd.o dns.a env.a cdb.a alloc.a buffer.a unix.a \ byte.a `cat socket.lib` walldns-conf: \ load walldns-conf.o generic-conf.o auto_home.o buffer.a unix.a byte.a ./load walldns-conf generic-conf.o auto_home.o buffer.a \ unix.a byte.a walldns-conf.o: \ compile walldns-conf.c strerr.h exit.h auto_home.h generic-conf.h \ buffer.h ./compile walldns-conf.c walldns.o: \ compile walldns.c byte.h dns.h stralloc.h gen_alloc.h iopause.h \ taia.h tai.h uint64.h taia.h dd.h response.h uint32.h ./compile walldns.c tinydyndns-0.4.2.debian1/README000066400000000000000000000002421103424076200160770ustar00rootroot00000000000000djbdns 1.05 20010211 Copyright 2001 D. J. Bernstein djbdns home page: http://cr.yp.to/djbdns.html Installation instructions: http://cr.yp.to/djbdns/install.html tinydyndns-0.4.2.debian1/SYSDEPS000066400000000000000000000001421103424076200162730ustar00rootroot00000000000000VERSION systype uint32.h uint64.h select.h iopause.h direntry.h hasshsgr.h hasdevtcp.h socket.lib tinydyndns-0.4.2.debian1/TARGETS000066400000000000000000000044661103424076200162670ustar00rootroot00000000000000load compile systype hasdevtcp.h uint32.h choose uint64.h dnscache-conf.o generic-conf.o auto-str.o makelib buffer.o buffer_1.o buffer_2.o buffer_copy.o buffer_get.o buffer_put.o strerr_die.o strerr_sys.o buffer.a buffer_read.o buffer_write.o error.o error_str.o ndelay_off.o ndelay_on.o open_read.o open_trunc.o openreadclose.o readclose.o seek_set.o socket_accept.o socket_bind.o socket_conn.o socket_listen.o socket_recv.o socket_send.o socket_tcp.o socket_udp.o unix.a byte_chr.o byte_copy.o byte_cr.o byte_diff.o byte_zero.o case_diffb.o case_diffs.o case_lowerb.o fmt_ulong.o ip4_fmt.o ip4_scan.o scan_ulong.o str_chr.o str_diff.o str_len.o str_rchr.o str_start.o uint16_pack.o uint16_unpack.o uint32_pack.o uint32_unpack.o byte.a auto-str auto_home.c auto_home.o tai_add.o tai_now.o tai_pack.o tai_sub.o tai_uint.o tai_unpack.o taia_add.o taia_approx.o taia_frac.o taia_less.o taia_now.o taia_pack.o taia_sub.o taia_tai.o taia_uint.o libtai.a dnscache-conf iopause.h dnscache.o droproot.o okclient.o log.o cache.o query.o response.o dd.o direntry.h roots.o select.h iopause.o chkshsgr.o chkshsgr hasshsgr.h prot.o dns_dfd.o dns_domain.o dns_dtda.o dns_ip.o dns_ipq.o dns_mx.o dns_name.o dns_nd.o dns_packet.o dns_random.o dns_rcip.o dns_rcrw.o dns_resolve.o dns_sortip.o dns_transmit.o dns_txt.o dns.a env.o env.a alloc.o alloc_re.o getln.o getln2.o stralloc_cat.o stralloc_catb.o stralloc_cats.o stralloc_copy.o stralloc_eady.o stralloc_num.o stralloc_opyb.o stralloc_opys.o stralloc_pend.o alloc.a socket.lib dnscache walldns-conf.o walldns-conf walldns.o server.o qlog.o cdb.o cdb_hash.o cdb_make.o cdb.a walldns rbldns-conf.o rbldns-conf rbldns.o rbldns rbldns-data.o rbldns-data pickdns-conf.o pickdns-conf pickdns.o pickdns pickdns-data.o pickdns-data tinydns-conf.o tinydns-conf tinydns.o tdlookup.o tinydns tinydns-data.o tinydns-data tinydns-get.o printpacket.o printrecord.o parsetype.o tinydns-get tinydns-edit.o tinydns-edit axfr-get.o timeoutread.o timeoutwrite.o axfr-get axfrdns-conf.o axfrdns-conf axfrdns.o axfrdns dnsip.o dnsip dnsipq.o dnsipq dnsname.o dnsname dnstxt.o dnstxt dnsmx.o dnsmx dnsfilter.o sgetopt.o subgetopt.o getopt.a dnsfilter random-ip.o random-ip dnsqr.o dnsqr dnsq.o dnsq dnstrace.o dnstrace dnstracesort cachetest.o cachetest utime.o utime rts prog install.o hier.o install instcheck.o instcheck it setup check tinydyndns-0.4.2.debian1/TINYDNS000066400000000000000000000016151103424076200162770ustar00rootroot00000000000000The tinydns data.cdb format is subject to change. If you want to write code that relies on something here, let me know. Keys starting with the two bytes \000\045 are locations. The rest of the key is an IP prefix, normally between 0 and 4 bytes long. The data is a 2-byte location. Other keys are owner names for DNS records. The data begins with a header in the following format: * a 2-byte type; * either \075, or \076 with a 2-byte location; * a 4-byte TTL; * an 8-byte timestamp. (Exception: Wildcard records replace \075 with \052 and \076 with \053; also, the owner name omits the wildcard.) The data continues in a type-specific format: * SOA: first domain name, second domain name, 20-byte miscellany. * NS or PTR or CNAME: domain name. * MX: 2-byte preference, domain name. * Other types: no special structure. Domain names, types, and numbers are in DNS packet format. tinydyndns-0.4.2.debian1/TODO000066400000000000000000000005301103424076200157070ustar00rootroot00000000000000end-to-end nym-based security link-level security try to get the root authorities to set up a secure, usable NS-list system have dnscache-conf keep track of copies of dnsroots.global incorporate automatic NS-list upgrades consider dead-server table in dnscache or in kernel IPv6 lookups maybe reverse IPv6 lookups; what a mess DNS over IPv6 tinydyndns-0.4.2.debian1/VERSION000066400000000000000000000000141103424076200162640ustar00rootroot00000000000000djbdns 1.05 tinydyndns-0.4.2.debian1/alloc.c000066400000000000000000000014521103424076200164610ustar00rootroot00000000000000#include #include "alloc.h" #include "error.h" #define ALIGNMENT 16 /* XXX: assuming that this alignment is enough */ #define SPACE 2048 /* must be multiple of ALIGNMENT */ typedef union { char irrelevant[ALIGNMENT]; double d; } aligned; static aligned realspace[SPACE / ALIGNMENT]; #define space ((char *) realspace) static unsigned int avail = SPACE; /* multiple of ALIGNMENT; 0<=avail<=SPACE */ /*@null@*//*@out@*/char *alloc(n) unsigned int n; { char *x; n = ALIGNMENT + n - (n & (ALIGNMENT - 1)); /* XXX: could overflow */ if (n <= avail) { avail -= n; return space + avail; } x = malloc(n); if (!x) errno = error_nomem; return x; } void alloc_free(x) char *x; { if (x >= space) if (x < space + SPACE) return; /* XXX: assuming that pointers are flat */ free(x); } tinydyndns-0.4.2.debian1/alloc.h000066400000000000000000000002031103424076200164570ustar00rootroot00000000000000#ifndef ALLOC_H #define ALLOC_H extern /*@null@*//*@out@*/char *alloc(); extern void alloc_free(); extern int alloc_re(); #endif tinydyndns-0.4.2.debian1/alloc_re.c000066400000000000000000000003261103424076200171460ustar00rootroot00000000000000#include "alloc.h" #include "byte.h" int alloc_re(x,m,n) char **x; unsigned int m; unsigned int n; { char *y; y = alloc(n); if (!y) return 0; byte_copy(y,m,*x); alloc_free(*x); *x = y; return 1; } tinydyndns-0.4.2.debian1/auto-str.c000066400000000000000000000013161103424076200171440ustar00rootroot00000000000000#include "buffer.h" #include "exit.h" char bspace[256]; buffer b = BUFFER_INIT(buffer_unixwrite,1,bspace,sizeof bspace); void puts(const char *s) { if (buffer_puts(&b,s) == -1) _exit(111); } int main(int argc,char **argv) { char *name; char *value; unsigned char ch; char octal[4]; name = argv[1]; if (!name) _exit(100); value = argv[2]; if (!value) _exit(100); puts("const char "); puts(name); puts("[] = \"\\\n"); while (ch = *value++) { puts("\\"); octal[3] = 0; octal[2] = '0' + (ch & 7); ch >>= 3; octal[1] = '0' + (ch & 7); ch >>= 3; octal[0] = '0' + (ch & 7); puts(octal); } puts("\\\n\";\n"); if (buffer_flush(&b) == -1) _exit(111); _exit(0); } tinydyndns-0.4.2.debian1/auto_home.h000066400000000000000000000001201103424076200173430ustar00rootroot00000000000000#ifndef AUTO_HOME_H #define AUTO_HOME_H extern const char auto_home[]; #endif tinydyndns-0.4.2.debian1/axfr-get.c000066400000000000000000000241321103424076200171040ustar00rootroot00000000000000#include #include #include "uint32.h" #include "uint16.h" #include "stralloc.h" #include "error.h" #include "strerr.h" #include "getln.h" #include "buffer.h" #include "exit.h" #include "open.h" #include "scan.h" #include "byte.h" #include "str.h" #include "ip4.h" #include "timeoutread.h" #include "timeoutwrite.h" #include "dns.h" #define FATAL "axfr-get: fatal: " void die_usage(void) { strerr_die1x(100,"axfr-get: usage: axfr-get zone fn fn.tmp"); } void die_generate(void) { strerr_die2sys(111,FATAL,"unable to generate AXFR query: "); } void die_parse(void) { strerr_die2sys(111,FATAL,"unable to parse AXFR results: "); } unsigned int x_copy(char *buf,unsigned int len,unsigned int pos,char *out,unsigned int outlen) { pos = dns_packet_copy(buf,len,pos,out,outlen); if (!pos) die_parse(); return pos; } unsigned int x_getname(char *buf,unsigned int len,unsigned int pos,char **out) { pos = dns_packet_getname(buf,len,pos,out); if (!pos) die_parse(); return pos; } unsigned int x_skipname(char *buf,unsigned int len,unsigned int pos) { pos = dns_packet_skipname(buf,len,pos); if (!pos) die_parse(); return pos; } static char *zone; unsigned int zonelen; char *fn; char *fntmp; void die_netread(void) { strerr_die2sys(111,FATAL,"unable to read from network: "); } void die_netwrite(void) { strerr_die2sys(111,FATAL,"unable to write to network: "); } void die_read(void) { strerr_die4sys(111,FATAL,"unable to read ",fn,": "); } void die_write(void) { strerr_die4sys(111,FATAL,"unable to write ",fntmp,": "); } int saferead(int fd,char *buf,unsigned int len) { int r; r = timeoutread(60,fd,buf,len); if (r == 0) { errno = error_proto; die_parse(); } if (r <= 0) die_netread(); return r; } int safewrite(int fd,char *buf,unsigned int len) { int r; r = timeoutwrite(60,fd,buf,len); if (r <= 0) die_netwrite(); return r; } char netreadspace[1024]; buffer netread = BUFFER_INIT(saferead,6,netreadspace,sizeof netreadspace); char netwritespace[1024]; buffer netwrite = BUFFER_INIT(safewrite,7,netwritespace,sizeof netwritespace); void netget(char *buf,unsigned int len) { int r; while (len > 0) { r = buffer_get(&netread,buf,len); buf += r; len -= r; } } int fd; buffer b; char bspace[1024]; void put(char *buf,unsigned int len) { if (buffer_put(&b,buf,len) == -1) die_write(); } int printable(char ch) { if (ch == '.') return 1; if ((ch >= 'a') && (ch <= 'z')) return 1; if ((ch >= '0') && (ch <= '9')) return 1; if ((ch >= 'A') && (ch <= 'Z')) return 1; if (ch == '-') return 1; return 0; } static char *d1; static char *d2; static char *d3; stralloc line; int match; int numsoa; unsigned int doit(char *buf,unsigned int len,unsigned int pos) { char data[20]; uint32 ttl; uint16 dlen; uint16 typenum; uint32 u32; int i; pos = x_getname(buf,len,pos,&d1); pos = x_copy(buf,len,pos,data,10); uint16_unpack_big(data,&typenum); uint32_unpack_big(data + 4,&ttl); uint16_unpack_big(data + 8,&dlen); if (len - pos < dlen) { errno = error_proto; return 0; } len = pos + dlen; if (!dns_domain_suffix(d1,zone)) return len; if (byte_diff(data + 2,2,DNS_C_IN)) return len; if (byte_equal(data,2,DNS_T_SOA)) { if (++numsoa >= 2) return len; pos = x_getname(buf,len,pos,&d2); pos = x_getname(buf,len,pos,&d3); x_copy(buf,len,pos,data,20); uint32_unpack_big(data,&u32); if (!stralloc_copys(&line,"#")) return 0; if (!stralloc_catulong0(&line,u32,0)) return 0; if (!stralloc_cats(&line," auto axfr-get\n")) return 0; if (!stralloc_cats(&line,"Z")) return 0; if (!dns_domain_todot_cat(&line,d1)) return 0; if (!stralloc_cats(&line,":")) return 0; if (!dns_domain_todot_cat(&line,d2)) return 0; if (!stralloc_cats(&line,".:")) return 0; if (!dns_domain_todot_cat(&line,d3)) return 0; if (!stralloc_cats(&line,".")) return 0; for (i = 0;i < 5;++i) { uint32_unpack_big(data + 4 * i,&u32); if (!stralloc_cats(&line,":")) return 0; if (!stralloc_catulong0(&line,u32,0)) return 0; } } else if (byte_equal(data,2,DNS_T_NS)) { if (!stralloc_copys(&line,"&")) return 0; if (byte_equal(d1,2,"\1*")) { errno = error_proto; return 0; } if (!dns_domain_todot_cat(&line,d1)) return 0; if (!stralloc_cats(&line,"::")) return 0; x_getname(buf,len,pos,&d1); if (!dns_domain_todot_cat(&line,d1)) return 0; if (!stralloc_cats(&line,".")) return 0; } else if (byte_equal(data,2,DNS_T_CNAME)) { if (!stralloc_copys(&line,"C")) return 0; if (!dns_domain_todot_cat(&line,d1)) return 0; if (!stralloc_cats(&line,":")) return 0; x_getname(buf,len,pos,&d1); if (!dns_domain_todot_cat(&line,d1)) return 0; if (!stralloc_cats(&line,".")) return 0; } else if (byte_equal(data,2,DNS_T_PTR)) { if (!stralloc_copys(&line,"^")) return 0; if (!dns_domain_todot_cat(&line,d1)) return 0; if (!stralloc_cats(&line,":")) return 0; x_getname(buf,len,pos,&d1); if (!dns_domain_todot_cat(&line,d1)) return 0; if (!stralloc_cats(&line,".")) return 0; } else if (byte_equal(data,2,DNS_T_MX)) { uint16 dist; if (!stralloc_copys(&line,"@")) return 0; if (!dns_domain_todot_cat(&line,d1)) return 0; if (!stralloc_cats(&line,"::")) return 0; pos = x_copy(buf,len,pos,data,2); uint16_unpack_big(data,&dist); x_getname(buf,len,pos,&d1); if (!dns_domain_todot_cat(&line,d1)) return 0; if (!stralloc_cats(&line,".:")) return 0; if (!stralloc_catulong0(&line,dist,0)) return 0; } else if (byte_equal(data,2,DNS_T_A) && (dlen == 4)) { char ipstr[IP4_FMT]; if (!stralloc_copys(&line,"+")) return 0; if (!dns_domain_todot_cat(&line,d1)) return 0; if (!stralloc_cats(&line,":")) return 0; x_copy(buf,len,pos,data,4); if (!stralloc_catb(&line,ipstr,ip4_fmt(ipstr,data))) return 0; } else { unsigned char ch; unsigned char ch2; if (!stralloc_copys(&line,":")) return 0; if (!dns_domain_todot_cat(&line,d1)) return 0; if (!stralloc_cats(&line,":")) return 0; if (!stralloc_catulong0(&line,typenum,0)) return 0; if (!stralloc_cats(&line,":")) return 0; for (i = 0;i < dlen;++i) { pos = x_copy(buf,len,pos,data,1); ch = data[0]; if (printable(ch)) { if (!stralloc_catb(&line,&ch,1)) return 0; } else { if (!stralloc_cats(&line,"\\")) return 0; ch2 = '0' + ((ch >> 6) & 7); if (!stralloc_catb(&line,&ch2,1)) return 0; ch2 = '0' + ((ch >> 3) & 7); if (!stralloc_catb(&line,&ch2,1)) return 0; ch2 = '0' + (ch & 7); if (!stralloc_catb(&line,&ch2,1)) return 0; } } } if (!stralloc_cats(&line,":")) return 0; if (!stralloc_catulong0(&line,ttl,0)) return 0; if (!stralloc_cats(&line,"\n")) return 0; put(line.s,line.len); return len; } stralloc packet; int main(int argc,char **argv) { char out[20]; unsigned long u; uint16 dlen; unsigned int pos; uint32 oldserial = 0; uint32 newserial = 0; uint16 numqueries; uint16 numanswers; if (!*argv) die_usage(); if (!*++argv) die_usage(); if (!dns_domain_fromdot(&zone,*argv,str_len(*argv))) die_generate(); zonelen = dns_domain_length(zone); if (!*++argv) die_usage(); fn = *argv; if (!*++argv) die_usage(); fntmp = *argv; fd = open_read(fn); if (fd == -1) { if (errno != error_noent) die_read(); } else { buffer_init(&b,buffer_unixread,fd,bspace,sizeof bspace); if (getln(&b,&line,&match,'\n') == -1) die_read(); if (!stralloc_0(&line)) die_read(); if (line.s[0] == '#') { scan_ulong(line.s + 1,&u); oldserial = u; } close(fd); } if (!stralloc_copyb(&packet,"\0\0\0\0\0\1\0\0\0\0\0\0",12)) die_generate(); if (!stralloc_catb(&packet,zone,zonelen)) die_generate(); if (!stralloc_catb(&packet,DNS_T_SOA DNS_C_IN,4)) die_generate(); uint16_pack_big(out,packet.len); buffer_put(&netwrite,out,2); buffer_put(&netwrite,packet.s,packet.len); buffer_flush(&netwrite); netget(out,2); uint16_unpack_big(out,&dlen); if (!stralloc_ready(&packet,dlen)) die_parse(); netget(packet.s,dlen); packet.len = dlen; pos = x_copy(packet.s,packet.len,0,out,12); uint16_unpack_big(out + 4,&numqueries); uint16_unpack_big(out + 6,&numanswers); while (numqueries) { --numqueries; pos = x_skipname(packet.s,packet.len,pos); pos += 4; } if (!numanswers) { errno = error_proto; die_parse(); } pos = x_getname(packet.s,packet.len,pos,&d1); if (!dns_domain_equal(zone,d1)) { errno = error_proto; die_parse(); } pos = x_copy(packet.s,packet.len,pos,out,10); if (byte_diff(out,4,DNS_T_SOA DNS_C_IN)) { errno = error_proto; die_parse(); } pos = x_skipname(packet.s,packet.len,pos); pos = x_skipname(packet.s,packet.len,pos); pos = x_copy(packet.s,packet.len,pos,out,4); uint32_unpack_big(out,&newserial); if (oldserial && newserial) /* allow 0 for very recently modified zones */ if (oldserial == newserial) /* allow serial numbers to move backwards */ _exit(0); fd = open_trunc(fntmp); if (fd == -1) die_write(); buffer_init(&b,buffer_unixwrite,fd,bspace,sizeof bspace); if (!stralloc_copyb(&packet,"\0\0\0\0\0\1\0\0\0\0\0\0",12)) die_generate(); if (!stralloc_catb(&packet,zone,zonelen)) die_generate(); if (!stralloc_catb(&packet,DNS_T_AXFR DNS_C_IN,4)) die_generate(); uint16_pack_big(out,packet.len); buffer_put(&netwrite,out,2); buffer_put(&netwrite,packet.s,packet.len); buffer_flush(&netwrite); numsoa = 0; while (numsoa < 2) { netget(out,2); uint16_unpack_big(out,&dlen); if (!stralloc_ready(&packet,dlen)) die_parse(); netget(packet.s,dlen); packet.len = dlen; pos = x_copy(packet.s,packet.len,0,out,12); uint16_unpack_big(out + 4,&numqueries); while (numqueries) { --numqueries; pos = x_skipname(packet.s,packet.len,pos); pos += 4; } while (pos < packet.len) { pos = doit(packet.s,packet.len,pos); if (!pos) die_parse(); } } if (buffer_flush(&b) == -1) die_write(); if (fsync(fd) == -1) die_write(); if (close(fd) == -1) die_write(); /* NFS dorks */ if (rename(fntmp,fn) == -1) strerr_die6sys(111,FATAL,"unable to move ",fntmp," to ",fn,": "); _exit(0); } tinydyndns-0.4.2.debian1/axfrdns-conf.c000066400000000000000000000030051103424076200177530ustar00rootroot00000000000000#include #include #include "strerr.h" #include "exit.h" #include "auto_home.h" #include "generic-conf.h" #define FATAL "axfrdns-conf: fatal: " void usage(void) { strerr_die1x(100,"axfrdns-conf: usage: axfrdns-conf acct logacct /axfrdns /tinydns myip"); } char *dir; char *user; char *loguser; struct passwd *pw; char *myip; char *tinydns; int main(int argc,char **argv) { user = argv[1]; if (!user) usage(); loguser = argv[2]; if (!loguser) usage(); dir = argv[3]; if (!dir) usage(); if (dir[0] != '/') usage(); tinydns = argv[4]; if (!tinydns) usage(); if (tinydns[0] != '/') usage(); myip = argv[5]; if (!myip) usage(); pw = getpwnam(loguser); if (!pw) strerr_die3x(111,FATAL,"unknown account ",loguser); init(dir,FATAL); makelog(loguser,pw->pw_uid,pw->pw_gid); makedir("env"); perm(02755); start("env/ROOT"); outs(tinydns); outs("/root\n"); finish(); perm(0644); start("env/IP"); outs(myip); outs("\n"); finish(); perm(0644); start("run"); outs("#!/bin/sh\nexec 2>&1\nexec envdir ./env sh -c '\n exec envuidgid "); outs(user); outs(" softlimit -d300000 tcpserver -vDRHl0 -x tcp.cdb -- \"$IP\" 53 "); outs(auto_home); outs("/bin/axfrdns\n'\n"); finish(); perm(0755); start("Makefile"); outs("tcp.cdb: tcp\n"); outs("\ttcprules tcp.cdb tcp.tmp < tcp\n"); finish(); perm(0644); start("tcp"); outs("# sample line: 1.2.3.4:allow,AXFR=\"heaven.af.mil/3.2.1.in-addr.arpa\"\n"); outs(":deny\n"); finish(); perm(0644); _exit(0); } tinydyndns-0.4.2.debian1/axfrdns.c000066400000000000000000000203361103424076200170360ustar00rootroot00000000000000#include #include "droproot.h" #include "exit.h" #include "env.h" #include "uint32.h" #include "uint16.h" #include "ip4.h" #include "tai.h" #include "buffer.h" #include "timeoutread.h" #include "timeoutwrite.h" #include "open.h" #include "seek.h" #include "cdb.h" #include "stralloc.h" #include "strerr.h" #include "str.h" #include "byte.h" #include "case.h" #include "dns.h" #include "scan.h" #include "qlog.h" #include "response.h" extern int respond(char *,char *,char *); #define FATAL "axfrdns: fatal: " void nomem() { strerr_die2x(111,FATAL,"out of memory"); } void die_truncated() { strerr_die2x(111,FATAL,"truncated request"); } void die_netwrite() { strerr_die2sys(111,FATAL,"unable to write to network: "); } void die_netread() { strerr_die2sys(111,FATAL,"unable to read from network: "); } void die_outside() { strerr_die2x(111,FATAL,"unable to locate information in data.cdb"); } void die_cdbread() { strerr_die2sys(111,FATAL,"unable to read data.cdb: "); } void die_cdbformat() { strerr_die3x(111,FATAL,"unable to read data.cdb: ","format error"); } int safewrite(int fd,char *buf,unsigned int len) { int w; w = timeoutwrite(60,fd,buf,len); if (w <= 0) die_netwrite(); return w; } char netwritespace[1024]; buffer netwrite = BUFFER_INIT(safewrite,1,netwritespace,sizeof netwritespace); void print(char *buf,unsigned int len) { char tcpheader[2]; uint16_pack_big(tcpheader,len); buffer_put(&netwrite,tcpheader,2); buffer_put(&netwrite,buf,len); buffer_flush(&netwrite); } char *axfr; static char *axfrok; void axfrcheck(char *q) { int i; int j; if (!axfr) return; i = j = 0; for (;;) { if (!axfr[i] || (axfr[i] == '/')) { if (i > j) { if (!dns_domain_fromdot(&axfrok,axfr + j,i - j)) nomem(); if (dns_domain_equal(q,axfrok)) return; } j = i + 1; } if (!axfr[i]) break; ++i; } strerr_die2x(111,FATAL,"disallowed zone transfer request"); } static char *zone; unsigned int zonelen; char typeclass[4]; int fdcdb; buffer bcdb; char bcdbspace[1024]; void get(char *buf,unsigned int len) { int r; while (len > 0) { r = buffer_get(&bcdb,buf,len); if (r < 0) die_cdbread(); if (!r) die_cdbformat(); buf += r; len -= r; } } char ip[4]; unsigned long port; char clientloc[2]; struct tai now; char data[32767]; uint32 dlen; uint32 dpos; void copy(char *buf,unsigned int len) { dpos = dns_packet_copy(data,dlen,dpos,buf,len); if (!dpos) die_cdbread(); } void doname(stralloc *sa) { static char *d; dpos = dns_packet_getname(data,dlen,dpos,&d); if (!dpos) die_cdbread(); if (!stralloc_catb(sa,d,dns_domain_length(d))) nomem(); } int build(stralloc *sa,char *q,int flagsoa,char id[2]) { unsigned int rdatapos; char misc[20]; char type[2]; char recordloc[2]; char ttl[4]; char ttd[8]; struct tai cutoff; dpos = 0; copy(type,2); if (flagsoa) if (byte_diff(type,2,DNS_T_SOA)) return 0; if (!flagsoa) if (byte_equal(type,2,DNS_T_SOA)) return 0; if (!stralloc_copyb(sa,id,2)) nomem(); if (!stralloc_catb(sa,"\204\000\0\0\0\1\0\0\0\0",10)) nomem(); copy(misc,1); if ((misc[0] == '=' + 1) || (misc[0] == '*' + 1)) { --misc[0]; copy(recordloc,2); if (byte_diff(recordloc,2,clientloc)) return 0; } if (misc[0] == '*') { if (flagsoa) return 0; if (!stralloc_catb(sa,"\1*",2)) nomem(); } if (!stralloc_catb(sa,q,dns_domain_length(q))) nomem(); if (!stralloc_catb(sa,type,2)) nomem(); copy(ttl,4); copy(ttd,8); if (byte_diff(ttd,8,"\0\0\0\0\0\0\0\0")) { tai_unpack(ttd,&cutoff); if (byte_equal(ttl,4,"\0\0\0\0")) { if (tai_less(&cutoff,&now)) return 0; uint32_pack_big(ttl,2); } else if (!tai_less(&cutoff,&now)) return 0; } if (!stralloc_catb(sa,DNS_C_IN,2)) nomem(); if (!stralloc_catb(sa,ttl,4)) nomem(); if (!stralloc_catb(sa,"\0\0",2)) nomem(); rdatapos = sa->len; if (byte_equal(type,2,DNS_T_SOA)) { doname(sa); doname(sa); copy(misc,20); if (!stralloc_catb(sa,misc,20)) nomem(); } else if (byte_equal(type,2,DNS_T_NS) || byte_equal(type,2,DNS_T_PTR) || byte_equal(type,2,DNS_T_CNAME)) { doname(sa); } else if (byte_equal(type,2,DNS_T_MX)) { copy(misc,2); if (!stralloc_catb(sa,misc,2)) nomem(); doname(sa); } else if (!stralloc_catb(sa,data + dpos,dlen - dpos)) nomem(); if (sa->len > 65535) die_cdbformat(); uint16_pack_big(sa->s + rdatapos - 2,sa->len - rdatapos); return 1; } static struct cdb c; static char *q; static stralloc soa; static stralloc message; void doaxfr(char id[2]) { char key[512]; uint32 klen; char num[4]; uint32 eod; uint32 pos; int r; axfrcheck(zone); tai_now(&now); cdb_init(&c,fdcdb); byte_zero(clientloc,2); key[0] = 0; key[1] = '%'; byte_copy(key + 2,4,ip); r = cdb_find(&c,key,6); if (!r) r = cdb_find(&c,key,5); if (!r) r = cdb_find(&c,key,4); if (!r) r = cdb_find(&c,key,3); if (!r) r = cdb_find(&c,key,2); if (r == -1) die_cdbread(); if (r && (cdb_datalen(&c) == 2)) if (cdb_read(&c,clientloc,2,cdb_datapos(&c)) == -1) die_cdbread(); cdb_findstart(&c); for (;;) { r = cdb_findnext(&c,zone,zonelen); if (r == -1) die_cdbread(); if (!r) die_outside(); dlen = cdb_datalen(&c); if (dlen > sizeof data) die_cdbformat(); if (cdb_read(&c,data,dlen,cdb_datapos(&c)) == -1) die_cdbformat(); if (build(&soa,zone,1,id)) break; } cdb_free(&c); print(soa.s,soa.len); seek_begin(fdcdb); buffer_init(&bcdb,buffer_unixread,fdcdb,bcdbspace,sizeof bcdbspace); pos = 0; get(num,4); pos += 4; uint32_unpack(num,&eod); while (pos < 2048) { get(num,4); pos += 4; } while (pos < eod) { if (eod - pos < 8) die_cdbformat(); get(num,4); pos += 4; uint32_unpack(num,&klen); get(num,4); pos += 4; uint32_unpack(num,&dlen); if (eod - pos < klen) die_cdbformat(); pos += klen; if (eod - pos < dlen) die_cdbformat(); pos += dlen; if (klen > sizeof key) die_cdbformat(); get(key,klen); if (dlen > sizeof data) die_cdbformat(); get(data,dlen); if ((klen > 1) && (key[0] == 0)) continue; /* location */ if (klen < 1) die_cdbformat(); if (dns_packet_getname(key,klen,0,&q) != klen) die_cdbformat(); if (!dns_domain_suffix(q,zone)) continue; if (!build(&message,q,0,id)) continue; print(message.s,message.len); } print(soa.s,soa.len); } void netread(char *buf,unsigned int len) { int r; while (len > 0) { r = timeoutread(60,0,buf,len); if (r == 0) _exit(0); if (r < 0) die_netread(); buf += r; len -= r; } } char tcpheader[2]; char buf[512]; uint16 len; static char seed[128]; int main() { unsigned int pos; char header[12]; char qtype[2]; char qclass[2]; const char *x; droproot(FATAL); dns_random_init(seed); axfr = env_get("AXFR"); x = env_get("TCPREMOTEIP"); if (x && ip4_scan(x,ip)) ; else byte_zero(ip,4); x = env_get("TCPREMOTEPORT"); if (!x) x = "0"; scan_ulong(x,&port); for (;;) { netread(tcpheader,2); uint16_unpack_big(tcpheader,&len); if (len > 512) strerr_die2x(111,FATAL,"excessively large request"); netread(buf,len); pos = dns_packet_copy(buf,len,0,header,12); if (!pos) die_truncated(); if (header[2] & 254) strerr_die2x(111,FATAL,"bogus query"); if (header[4] || (header[5] != 1)) strerr_die2x(111,FATAL,"bogus query"); pos = dns_packet_getname(buf,len,pos,&zone); if (!pos) die_truncated(); zonelen = dns_domain_length(zone); pos = dns_packet_copy(buf,len,pos,qtype,2); if (!pos) die_truncated(); pos = dns_packet_copy(buf,len,pos,qclass,2); if (!pos) die_truncated(); if (byte_diff(qclass,2,DNS_C_IN) && byte_diff(qclass,2,DNS_C_ANY)) strerr_die2x(111,FATAL,"bogus query: bad class"); qlog(ip,port,header,zone,qtype," "); if (byte_equal(qtype,2,DNS_T_AXFR)) { case_lowerb(zone,zonelen); fdcdb = open_read("data.cdb"); if (fdcdb == -1) die_cdbread(); doaxfr(header); close(fdcdb); } else { if (!response_query(zone,qtype,qclass)) nomem(); response[2] |= 4; case_lowerb(zone,zonelen); response_id(header); response[3] &= ~128; if (!(header[2] & 1)) response[2] &= ~1; if (!respond(zone,qtype,ip)) die_outside(); print(response,response_len); } } } tinydyndns-0.4.2.debian1/buffer.c000066400000000000000000000002471103424076200166410ustar00rootroot00000000000000#include "buffer.h" void buffer_init(buffer *s,int (*op)(),int fd,char *buf,unsigned int len) { s->x = buf; s->fd = fd; s->op = op; s->p = 0; s->n = len; } tinydyndns-0.4.2.debian1/buffer.h000066400000000000000000000031221103424076200166410ustar00rootroot00000000000000#ifndef BUFFER_H #define BUFFER_H typedef struct buffer { char *x; unsigned int p; unsigned int n; int fd; int (*op)(); } buffer; #define BUFFER_INIT(op,fd,buf,len) { (buf), 0, (len), (fd), (op) } #define BUFFER_INSIZE 8192 #define BUFFER_OUTSIZE 8192 extern void buffer_init(buffer *,int (*)(),int,char *,unsigned int); extern int buffer_flush(buffer *); extern int buffer_put(buffer *,const char *,unsigned int); extern int buffer_putalign(buffer *,const char *,unsigned int); extern int buffer_putflush(buffer *,const char *,unsigned int); extern int buffer_puts(buffer *,const char *); extern int buffer_putsalign(buffer *,const char *); extern int buffer_putsflush(buffer *,const char *); #define buffer_PUTC(s,c) \ ( ((s)->n != (s)->p) \ ? ( (s)->x[(s)->p++] = (c), 0 ) \ : buffer_put((s),&(c),1) \ ) extern int buffer_get(buffer *,char *,unsigned int); extern int buffer_bget(buffer *,char *,unsigned int); extern int buffer_feed(buffer *); extern char *buffer_peek(buffer *); extern void buffer_seek(buffer *,unsigned int); #define buffer_PEEK(s) ( (s)->x + (s)->n ) #define buffer_SEEK(s,len) ( ( (s)->p -= (len) ) , ( (s)->n += (len) ) ) #define buffer_GETC(s,c) \ ( ((s)->p > 0) \ ? ( *(c) = (s)->x[(s)->n], buffer_SEEK((s),1), 1 ) \ : buffer_get((s),(c),1) \ ) extern int buffer_copy(buffer *,buffer *); extern int buffer_unixread(int,char *,unsigned int); extern int buffer_unixwrite(int,const char *,unsigned int); extern buffer *buffer_0; extern buffer *buffer_0small; extern buffer *buffer_1; extern buffer *buffer_1small; extern buffer *buffer_2; #endif tinydyndns-0.4.2.debian1/buffer_1.c000066400000000000000000000002531103424076200170560ustar00rootroot00000000000000#include "buffer.h" char buffer_1_space[BUFFER_OUTSIZE]; static buffer it = BUFFER_INIT(buffer_unixwrite,1,buffer_1_space,sizeof buffer_1_space); buffer *buffer_1 = ⁢ tinydyndns-0.4.2.debian1/buffer_2.c000066400000000000000000000002401103424076200170530ustar00rootroot00000000000000#include "buffer.h" char buffer_2_space[256]; static buffer it = BUFFER_INIT(buffer_unixwrite,2,buffer_2_space,sizeof buffer_2_space); buffer *buffer_2 = ⁢ tinydyndns-0.4.2.debian1/buffer_copy.c000066400000000000000000000004241103424076200176700ustar00rootroot00000000000000#include "buffer.h" int buffer_copy(buffer *bout,buffer *bin) { int n; char *x; for (;;) { n = buffer_feed(bin); if (n < 0) return -2; if (!n) return 0; x = buffer_PEEK(bin); if (buffer_put(bout,x,n) == -1) return -3; buffer_SEEK(bin,n); } } tinydyndns-0.4.2.debian1/buffer_get.c000066400000000000000000000023411103424076200174750ustar00rootroot00000000000000#include "buffer.h" #include "byte.h" #include "error.h" static int oneread(int (*op)(),int fd,char *buf,unsigned int len) { int r; for (;;) { r = op(fd,buf,len); if (r == -1) if (errno == error_intr) continue; return r; } } static int getthis(buffer *s,char *buf,unsigned int len) { if (len > s->p) len = s->p; s->p -= len; byte_copy(buf,len,s->x + s->n); s->n += len; return len; } int buffer_feed(buffer *s) { int r; if (s->p) return s->p; r = oneread(s->op,s->fd,s->x,s->n); if (r <= 0) return r; s->p = r; s->n -= r; if (s->n > 0) byte_copyr(s->x + s->n,r,s->x); return r; } int buffer_bget(buffer *s,char *buf,unsigned int len) { int r; if (s->p > 0) return getthis(s,buf,len); if (s->n <= len) return oneread(s->op,s->fd,buf,s->n); r = buffer_feed(s); if (r <= 0) return r; return getthis(s,buf,len); } int buffer_get(buffer *s,char *buf,unsigned int len) { int r; if (s->p > 0) return getthis(s,buf,len); if (s->n <= len) return oneread(s->op,s->fd,buf,len); r = buffer_feed(s); if (r <= 0) return r; return getthis(s,buf,len); } char *buffer_peek(buffer *s) { return s->x + s->n; } void buffer_seek(buffer *s,unsigned int len) { s->n += len; s->p -= len; } tinydyndns-0.4.2.debian1/buffer_put.c000066400000000000000000000033671103424076200175370ustar00rootroot00000000000000#include "buffer.h" #include "str.h" #include "byte.h" #include "error.h" static int allwrite(int (*op)(),int fd,const char *buf,unsigned int len) { int w; while (len) { w = op(fd,buf,len); if (w == -1) { if (errno == error_intr) continue; return -1; /* note that some data may have been written */ } if (w == 0) ; /* luser's fault */ buf += w; len -= w; } return 0; } int buffer_flush(buffer *s) { int p; p = s->p; if (!p) return 0; s->p = 0; return allwrite(s->op,s->fd,s->x,p); } int buffer_putalign(buffer *s,const char *buf,unsigned int len) { unsigned int n; while (len > (n = s->n - s->p)) { byte_copy(s->x + s->p,n,buf); s->p += n; buf += n; len -= n; if (buffer_flush(s) == -1) return -1; } /* now len <= s->n - s->p */ byte_copy(s->x + s->p,len,buf); s->p += len; return 0; } int buffer_put(buffer *s,const char *buf,unsigned int len) { unsigned int n; n = s->n; if (len > n - s->p) { if (buffer_flush(s) == -1) return -1; /* now s->p == 0 */ if (n < BUFFER_OUTSIZE) n = BUFFER_OUTSIZE; while (len > s->n) { if (n > len) n = len; if (allwrite(s->op,s->fd,buf,n) == -1) return -1; buf += n; len -= n; } } /* now len <= s->n - s->p */ byte_copy(s->x + s->p,len,buf); s->p += len; return 0; } int buffer_putflush(buffer *s,const char *buf,unsigned int len) { if (buffer_flush(s) == -1) return -1; return allwrite(s->op,s->fd,buf,len); } int buffer_putsalign(buffer *s,const char *buf) { return buffer_putalign(s,buf,str_len(buf)); } int buffer_puts(buffer *s,const char *buf) { return buffer_put(s,buf,str_len(buf)); } int buffer_putsflush(buffer *s,const char *buf) { return buffer_putflush(s,buf,str_len(buf)); } tinydyndns-0.4.2.debian1/buffer_read.c000066400000000000000000000001771103424076200176360ustar00rootroot00000000000000#include #include "buffer.h" int buffer_unixread(int fd,char *buf,unsigned int len) { return read(fd,buf,len); } tinydyndns-0.4.2.debian1/buffer_write.c000066400000000000000000000002071103424076200200470ustar00rootroot00000000000000#include #include "buffer.h" int buffer_unixwrite(int fd,const char *buf,unsigned int len) { return write(fd,buf,len); } tinydyndns-0.4.2.debian1/byte.h000066400000000000000000000004011103424076200163300ustar00rootroot00000000000000#ifndef BYTE_H #define BYTE_H extern unsigned int byte_chr(); extern unsigned int byte_rchr(); extern void byte_copy(); extern void byte_copyr(); extern int byte_diff(); extern void byte_zero(); #define byte_equal(s,n,t) (!byte_diff((s),(n),(t))) #endif tinydyndns-0.4.2.debian1/byte_chr.c000066400000000000000000000006021103424076200171620ustar00rootroot00000000000000#include "byte.h" unsigned int byte_chr(s,n,c) char *s; register unsigned int n; int c; { register char ch; register char *t; ch = c; t = s; for (;;) { if (!n) break; if (*t == ch) break; ++t; --n; if (!n) break; if (*t == ch) break; ++t; --n; if (!n) break; if (*t == ch) break; ++t; --n; if (!n) break; if (*t == ch) break; ++t; --n; } return t - s; } tinydyndns-0.4.2.debian1/byte_copy.c000066400000000000000000000004531103424076200173640ustar00rootroot00000000000000#include "byte.h" void byte_copy(to,n,from) register char *to; register unsigned int n; register char *from; { for (;;) { if (!n) return; *to++ = *from++; --n; if (!n) return; *to++ = *from++; --n; if (!n) return; *to++ = *from++; --n; if (!n) return; *to++ = *from++; --n; } } tinydyndns-0.4.2.debian1/byte_cr.c000066400000000000000000000005041103424076200170130ustar00rootroot00000000000000#include "byte.h" void byte_copyr(to,n,from) register char *to; register unsigned int n; register char *from; { to += n; from += n; for (;;) { if (!n) return; *--to = *--from; --n; if (!n) return; *--to = *--from; --n; if (!n) return; *--to = *--from; --n; if (!n) return; *--to = *--from; --n; } } tinydyndns-0.4.2.debian1/byte_diff.c000066400000000000000000000007051103424076200173220ustar00rootroot00000000000000#include "byte.h" int byte_diff(s,n,t) register char *s; register unsigned int n; register char *t; { for (;;) { if (!n) return 0; if (*s != *t) break; ++s; ++t; --n; if (!n) return 0; if (*s != *t) break; ++s; ++t; --n; if (!n) return 0; if (*s != *t) break; ++s; ++t; --n; if (!n) return 0; if (*s != *t) break; ++s; ++t; --n; } return ((int)(unsigned int)(unsigned char) *s) - ((int)(unsigned int)(unsigned char) *t); } tinydyndns-0.4.2.debian1/byte_zero.c000066400000000000000000000003461103424076200173720ustar00rootroot00000000000000#include "byte.h" void byte_zero(s,n) char *s; register unsigned int n; { for (;;) { if (!n) break; *s++ = 0; --n; if (!n) break; *s++ = 0; --n; if (!n) break; *s++ = 0; --n; if (!n) break; *s++ = 0; --n; } } tinydyndns-0.4.2.debian1/cache.c000066400000000000000000000106771103424076200164430ustar00rootroot00000000000000#include "alloc.h" #include "byte.h" #include "uint32.h" #include "exit.h" #include "tai.h" #include "cache.h" uint64 cache_motion = 0; static char *x = 0; static uint32 size; static uint32 hsize; static uint32 writer; static uint32 oldest; static uint32 unused; /* 100 <= size <= 1000000000. 4 <= hsize <= size/16. hsize is a power of 2. hsize <= writer <= oldest <= unused <= size. If oldest == unused then unused == size. x is a hash table with the following structure: x[0...hsize-1]: hsize/4 head links. x[hsize...writer-1]: consecutive entries, newest entry on the right. x[writer...oldest-1]: free space for new entries. x[oldest...unused-1]: consecutive entries, oldest entry on the left. x[unused...size-1]: unused. Each hash bucket is a linked list containing the following items: the head link, the newest entry, the second-newest entry, etc. Each link is a 4-byte number giving the xor of the positions of the adjacent items in the list. Entries are always inserted immediately after the head and removed at the tail. Each entry contains the following information: 4-byte link; 4-byte keylen; 4-byte datalen; 8-byte expire time; key; data. */ #define MAXKEYLEN 1000 #define MAXDATALEN 1000000 static void cache_impossible(void) { _exit(111); } static void set4(uint32 pos,uint32 u) { if (pos > size - 4) cache_impossible(); uint32_pack(x + pos,u); } static uint32 get4(uint32 pos) { uint32 result; if (pos > size - 4) cache_impossible(); uint32_unpack(x + pos,&result); return result; } static unsigned int hash(const char *key,unsigned int keylen) { unsigned int result = 5381; while (keylen) { result = (result << 5) + result; result ^= (unsigned char) *key; ++key; --keylen; } result <<= 2; result &= hsize - 4; return result; } char *cache_get(const char *key,unsigned int keylen,unsigned int *datalen,uint32 *ttl) { struct tai expire; struct tai now; uint32 pos; uint32 prevpos; uint32 nextpos; uint32 u; unsigned int loop; double d; if (!x) return 0; if (keylen > MAXKEYLEN) return 0; prevpos = hash(key,keylen); pos = get4(prevpos); loop = 0; while (pos) { if (get4(pos + 4) == keylen) { if (pos + 20 + keylen > size) cache_impossible(); if (byte_equal(key,keylen,x + pos + 20)) { tai_unpack(x + pos + 12,&expire); tai_now(&now); if (tai_less(&expire,&now)) return 0; tai_sub(&expire,&expire,&now); d = tai_approx(&expire); if (d > 604800) d = 604800; *ttl = d; u = get4(pos + 8); if (u > size - pos - 20 - keylen) cache_impossible(); *datalen = u; return x + pos + 20 + keylen; } } nextpos = prevpos ^ get4(pos); prevpos = pos; pos = nextpos; if (++loop > 100) return 0; /* to protect against hash flooding */ } return 0; } void cache_set(const char *key,unsigned int keylen,const char *data,unsigned int datalen,uint32 ttl) { struct tai now; struct tai expire; unsigned int entrylen; unsigned int keyhash; uint32 pos; if (!x) return; if (keylen > MAXKEYLEN) return; if (datalen > MAXDATALEN) return; if (!ttl) return; if (ttl > 604800) ttl = 604800; entrylen = keylen + datalen + 20; while (writer + entrylen > oldest) { if (oldest == unused) { if (writer <= hsize) return; unused = writer; oldest = hsize; writer = hsize; } pos = get4(oldest); set4(pos,get4(pos) ^ oldest); oldest += get4(oldest + 4) + get4(oldest + 8) + 20; if (oldest > unused) cache_impossible(); if (oldest == unused) { unused = size; oldest = size; } } keyhash = hash(key,keylen); tai_now(&now); tai_uint(&expire,ttl); tai_add(&expire,&expire,&now); pos = get4(keyhash); if (pos) set4(pos,get4(pos) ^ keyhash ^ writer); set4(writer,pos ^ keyhash); set4(writer + 4,keylen); set4(writer + 8,datalen); tai_pack(x + writer + 12,&expire); byte_copy(x + writer + 20,keylen,key); byte_copy(x + writer + 20 + keylen,datalen,data); set4(keyhash,writer); writer += entrylen; cache_motion += entrylen; } int cache_init(unsigned int cachesize) { if (x) { alloc_free(x); x = 0; } if (cachesize > 1000000000) cachesize = 1000000000; if (cachesize < 100) cachesize = 100; size = cachesize; hsize = 4; while (hsize <= (size >> 5)) hsize <<= 1; x = alloc(size); if (!x) return 0; byte_zero(x,size); writer = hsize; oldest = size; unused = size; return 1; } tinydyndns-0.4.2.debian1/cache.h000066400000000000000000000004611103424076200164360ustar00rootroot00000000000000#ifndef CACHE_H #define CACHE_H #include "uint32.h" #include "uint64.h" extern uint64 cache_motion; extern int cache_init(unsigned int); extern void cache_set(const char *,unsigned int,const char *,unsigned int,uint32); extern char *cache_get(const char *,unsigned int,unsigned int *,uint32 *); #endif tinydyndns-0.4.2.debian1/cachetest.c000066400000000000000000000010171103424076200173270ustar00rootroot00000000000000#include "buffer.h" #include "exit.h" #include "cache.h" #include "str.h" int main(int argc,char **argv) { int i; char *x; char *y; unsigned int u; uint32 ttl; if (!cache_init(200)) _exit(111); if (*argv) ++argv; while (x = *argv++) { i = str_chr(x,':'); if (x[i]) cache_set(x,i,x + i + 1,str_len(x) - i - 1,86400); else { y = cache_get(x,i,&u,&ttl); if (y) buffer_put(buffer_1,y,u); buffer_puts(buffer_1,"\n"); } } buffer_flush(buffer_1); _exit(0); } tinydyndns-0.4.2.debian1/case.h000066400000000000000000000006131103424076200163050ustar00rootroot00000000000000#ifndef CASE_H #define CASE_H extern void case_lowers(char *); extern void case_lowerb(char *,unsigned int); extern int case_diffs(const char *,const char *); extern int case_diffb(const char *,unsigned int,const char *); extern int case_starts(const char *,const char *); extern int case_startb(const char *,unsigned int,const char *); #define case_equals(s,t) (!case_diffs((s),(t))) #endif tinydyndns-0.4.2.debian1/case_diffb.c000066400000000000000000000006611103424076200174350ustar00rootroot00000000000000#include "case.h" int case_diffb(register const char *s,register unsigned int len,register const char *t) { register unsigned char x; register unsigned char y; while (len > 0) { --len; x = *s++ - 'A'; if (x <= 'Z' - 'A') x += 'a'; else x += 'A'; y = *t++ - 'A'; if (y <= 'Z' - 'A') y += 'a'; else y += 'A'; if (x != y) return ((int)(unsigned int) x) - ((int)(unsigned int) y); } return 0; } tinydyndns-0.4.2.debian1/case_diffs.c000066400000000000000000000006171103424076200174570ustar00rootroot00000000000000#include "case.h" int case_diffs(register const char *s,register const char *t) { register unsigned char x; register unsigned char y; for (;;) { x = *s++ - 'A'; if (x <= 'Z' - 'A') x += 'a'; else x += 'A'; y = *t++ - 'A'; if (y <= 'Z' - 'A') y += 'a'; else y += 'A'; if (x != y) break; if (!x) break; } return ((int)(unsigned int) x) - ((int)(unsigned int) y); } tinydyndns-0.4.2.debian1/case_lowerb.c000066400000000000000000000002711103424076200176520ustar00rootroot00000000000000#include "case.h" void case_lowerb(char *s,unsigned int len) { unsigned char x; while (len > 0) { --len; x = *s - 'A'; if (x <= 'Z' - 'A') *s = x + 'a'; ++s; } } tinydyndns-0.4.2.debian1/cdb.c000066400000000000000000000050601103424076200161160ustar00rootroot00000000000000/* Public domain. */ #include #include #include #include #include "error.h" #include "seek.h" #include "byte.h" #include "cdb.h" void cdb_free(struct cdb *c) { if (c->map) { munmap(c->map,c->size); c->map = 0; } } void cdb_findstart(struct cdb *c) { c->loop = 0; } void cdb_init(struct cdb *c,int fd) { struct stat st; char *x; cdb_free(c); cdb_findstart(c); c->fd = fd; if (fstat(fd,&st) == 0) if (st.st_size <= 0xffffffff) { x = mmap(0,st.st_size,PROT_READ,MAP_SHARED,fd,0); if (x + 1) { c->size = st.st_size; c->map = x; } } } int cdb_read(struct cdb *c,char *buf,unsigned int len,uint32 pos) { if (c->map) { if ((pos > c->size) || (c->size - pos < len)) goto FORMAT; byte_copy(buf,len,c->map + pos); } else { if (seek_set(c->fd,pos) == -1) return -1; while (len > 0) { int r; do r = read(c->fd,buf,len); while ((r == -1) && (errno == error_intr)); if (r == -1) return -1; if (r == 0) goto FORMAT; buf += r; len -= r; } } return 0; FORMAT: errno = error_proto; return -1; } static int match(struct cdb *c,const char *key,unsigned int len,uint32 pos) { char buf[32]; int n; while (len > 0) { n = sizeof buf; if (n > len) n = len; if (cdb_read(c,buf,n,pos) == -1) return -1; if (byte_diff(buf,n,key)) return 0; pos += n; key += n; len -= n; } return 1; } int cdb_findnext(struct cdb *c,const char *key,unsigned int len) { char buf[8]; uint32 pos; uint32 u; if (!c->loop) { u = cdb_hash(key,len); if (cdb_read(c,buf,8,(u << 3) & 2047) == -1) return -1; uint32_unpack(buf + 4,&c->hslots); if (!c->hslots) return 0; uint32_unpack(buf,&c->hpos); c->khash = u; u >>= 8; u %= c->hslots; u <<= 3; c->kpos = c->hpos + u; } while (c->loop < c->hslots) { if (cdb_read(c,buf,8,c->kpos) == -1) return -1; uint32_unpack(buf + 4,&pos); if (!pos) return 0; c->loop += 1; c->kpos += 8; if (c->kpos == c->hpos + (c->hslots << 3)) c->kpos = c->hpos; uint32_unpack(buf,&u); if (u == c->khash) { if (cdb_read(c,buf,8,pos) == -1) return -1; uint32_unpack(buf,&u); if (u == len) switch(match(c,key,len,pos + 8)) { case -1: return -1; case 1: uint32_unpack(buf + 4,&c->dlen); c->dpos = pos + 8 + len; return 1; } } } return 0; } int cdb_find(struct cdb *c,const char *key,unsigned int len) { cdb_findstart(c); return cdb_findnext(c,key,len); } tinydyndns-0.4.2.debian1/cdb.h000066400000000000000000000021271103424076200161240ustar00rootroot00000000000000/* Public domain. */ #ifndef CDB_H #define CDB_H #include "uint32.h" #define CDB_HASHSTART 5381 extern uint32 cdb_hashadd(uint32,unsigned char); extern uint32 cdb_hash(const char *,unsigned int); struct cdb { char *map; /* 0 if no map is available */ int fd; uint32 size; /* initialized if map is nonzero */ uint32 loop; /* number of hash slots searched under this key */ uint32 khash; /* initialized if loop is nonzero */ uint32 kpos; /* initialized if loop is nonzero */ uint32 hpos; /* initialized if loop is nonzero */ uint32 hslots; /* initialized if loop is nonzero */ uint32 dpos; /* initialized if cdb_findnext() returns 1 */ uint32 dlen; /* initialized if cdb_findnext() returns 1 */ } ; extern void cdb_free(struct cdb *); extern void cdb_init(struct cdb *,int fd); extern int cdb_read(struct cdb *,char *,unsigned int,uint32); extern void cdb_findstart(struct cdb *); extern int cdb_findnext(struct cdb *,const char *,unsigned int); extern int cdb_find(struct cdb *,const char *,unsigned int); #define cdb_datapos(c) ((c)->dpos) #define cdb_datalen(c) ((c)->dlen) #endif tinydyndns-0.4.2.debian1/cdb_hash.c000066400000000000000000000004351103424076200171220ustar00rootroot00000000000000/* Public domain. */ #include "cdb.h" uint32 cdb_hashadd(uint32 h,unsigned char c) { h += (h << 5); return h ^ c; } uint32 cdb_hash(const char *buf,unsigned int len) { uint32 h; h = CDB_HASHSTART; while (len) { h = cdb_hashadd(h,*buf++); --len; } return h; } tinydyndns-0.4.2.debian1/cdb_make.c000066400000000000000000000071731103424076200171220ustar00rootroot00000000000000/* Public domain. */ #include "seek.h" #include "error.h" #include "alloc.h" #include "cdb.h" #include "cdb_make.h" int cdb_make_start(struct cdb_make *c,int fd) { c->head = 0; c->split = 0; c->hash = 0; c->numentries = 0; c->fd = fd; c->pos = sizeof c->final; buffer_init(&c->b,buffer_unixwrite,fd,c->bspace,sizeof c->bspace); return seek_set(fd,c->pos); } static int posplus(struct cdb_make *c,uint32 len) { uint32 newpos = c->pos + len; if (newpos < len) { errno = error_nomem; return -1; } c->pos = newpos; return 0; } int cdb_make_addend(struct cdb_make *c,unsigned int keylen,unsigned int datalen,uint32 h) { struct cdb_hplist *head; head = c->head; if (!head || (head->num >= CDB_HPLIST)) { head = (struct cdb_hplist *) alloc(sizeof(struct cdb_hplist)); if (!head) return -1; head->num = 0; head->next = c->head; c->head = head; } head->hp[head->num].h = h; head->hp[head->num].p = c->pos; ++head->num; ++c->numentries; if (posplus(c,8) == -1) return -1; if (posplus(c,keylen) == -1) return -1; if (posplus(c,datalen) == -1) return -1; return 0; } int cdb_make_addbegin(struct cdb_make *c,unsigned int keylen,unsigned int datalen) { char buf[8]; if (keylen > 0xffffffff) { errno = error_nomem; return -1; } if (datalen > 0xffffffff) { errno = error_nomem; return -1; } uint32_pack(buf,keylen); uint32_pack(buf + 4,datalen); if (buffer_putalign(&c->b,buf,8) == -1) return -1; return 0; } int cdb_make_add(struct cdb_make *c,const char *key,unsigned int keylen,const char *data,unsigned int datalen) { if (cdb_make_addbegin(c,keylen,datalen) == -1) return -1; if (buffer_putalign(&c->b,key,keylen) == -1) return -1; if (buffer_putalign(&c->b,data,datalen) == -1) return -1; return cdb_make_addend(c,keylen,datalen,cdb_hash(key,keylen)); } int cdb_make_finish(struct cdb_make *c) { char buf[8]; int i; uint32 len; uint32 u; uint32 memsize; uint32 count; uint32 where; struct cdb_hplist *x; struct cdb_hp *hp; for (i = 0;i < 256;++i) c->count[i] = 0; for (x = c->head;x;x = x->next) { i = x->num; while (i--) ++c->count[255 & x->hp[i].h]; } memsize = 1; for (i = 0;i < 256;++i) { u = c->count[i] * 2; if (u > memsize) memsize = u; } memsize += c->numentries; /* no overflow possible up to now */ u = (uint32) 0 - (uint32) 1; u /= sizeof(struct cdb_hp); if (memsize > u) { errno = error_nomem; return -1; } c->split = (struct cdb_hp *) alloc(memsize * sizeof(struct cdb_hp)); if (!c->split) return -1; c->hash = c->split + c->numentries; u = 0; for (i = 0;i < 256;++i) { u += c->count[i]; /* bounded by numentries, so no overflow */ c->start[i] = u; } for (x = c->head;x;x = x->next) { i = x->num; while (i--) c->split[--c->start[255 & x->hp[i].h]] = x->hp[i]; } for (i = 0;i < 256;++i) { count = c->count[i]; len = count + count; /* no overflow possible */ uint32_pack(c->final + 8 * i,c->pos); uint32_pack(c->final + 8 * i + 4,len); for (u = 0;u < len;++u) c->hash[u].h = c->hash[u].p = 0; hp = c->split + c->start[i]; for (u = 0;u < count;++u) { where = (hp->h >> 8) % len; while (c->hash[where].p) if (++where == len) where = 0; c->hash[where] = *hp++; } for (u = 0;u < len;++u) { uint32_pack(buf,c->hash[u].h); uint32_pack(buf + 4,c->hash[u].p); if (buffer_putalign(&c->b,buf,8) == -1) return -1; if (posplus(c,8) == -1) return -1; } } if (buffer_flush(&c->b) == -1) return -1; if (seek_begin(c->fd) == -1) return -1; return buffer_putflush(&c->b,c->final,sizeof c->final); } tinydyndns-0.4.2.debian1/cdb_make.h000066400000000000000000000015661103424076200171270ustar00rootroot00000000000000/* Public domain. */ #ifndef CDB_MAKE_H #define CDB_MAKE_H #include "buffer.h" #include "uint32.h" #define CDB_HPLIST 1000 struct cdb_hp { uint32 h; uint32 p; } ; struct cdb_hplist { struct cdb_hp hp[CDB_HPLIST]; struct cdb_hplist *next; int num; } ; struct cdb_make { char bspace[8192]; char final[2048]; uint32 count[256]; uint32 start[256]; struct cdb_hplist *head; struct cdb_hp *split; /* includes space for hash */ struct cdb_hp *hash; uint32 numentries; buffer b; uint32 pos; int fd; } ; extern int cdb_make_start(struct cdb_make *,int); extern int cdb_make_addbegin(struct cdb_make *,unsigned int,unsigned int); extern int cdb_make_addend(struct cdb_make *,unsigned int,unsigned int,uint32); extern int cdb_make_add(struct cdb_make *,const char *,unsigned int,const char *,unsigned int); extern int cdb_make_finish(struct cdb_make *); #endif tinydyndns-0.4.2.debian1/chkshsgr.c000066400000000000000000000002171103424076200172010ustar00rootroot00000000000000#include "exit.h" int main() { short x[4]; x[0] = x[1] = 0; if (getgroups(1,x) == 0) if (setgroups(1,x) == -1) _exit(1); _exit(0); } tinydyndns-0.4.2.debian1/choose.sh000066400000000000000000000004021103424076200170310ustar00rootroot00000000000000 result="$4" case "$1" in *c*) ./compile $2.c >/dev/null 2>&1 || result="$3" ;; esac case "$1" in *l*) ./load $2 >/dev/null 2>&1 || result="$3" ;; esac case "$1" in *r*) ./$2 >/dev/null 2>&1 || result="$3" ;; esac rm -f $2.o $2 exec cat "$result" tinydyndns-0.4.2.debian1/conf-cc000066400000000000000000000002421103424076200164520ustar00rootroot00000000000000gcc -O2 -Wimplicit -Wunused -Wcomment -Wchar-subscripts -Wuninitialized -Wshadow -Wcast-qual -Wcast-align -Wwrite-strings This will be used to compile .c files. tinydyndns-0.4.2.debian1/conf-home000066400000000000000000000001301103424076200170110ustar00rootroot00000000000000/usr/local This is the dnscache home directory. Programs will be installed in .../bin. tinydyndns-0.4.2.debian1/conf-ld000066400000000000000000000000771103424076200164720ustar00rootroot00000000000000gcc -s This will be used to link .o files into an executable. tinydyndns-0.4.2.debian1/dd.c000066400000000000000000000013201103424076200157500ustar00rootroot00000000000000#include "dns.h" #include "dd.h" int dd(const char *q,const char *base,char ip[4]) { int j; unsigned int x; for (j = 0;;++j) { if (dns_domain_equal(q,base)) return j; if (j >= 4) return -1; if (*q <= 0) return -1; if (*q >= 4) return -1; if ((q[1] < '0') || (q[1] > '9')) return -1; x = q[1] - '0'; if (*q == 1) { ip[j] = x; q += 2; continue; } if (!x) return -1; if ((q[2] < '0') || (q[2] > '9')) return -1; x = x * 10 + (q[2] - '0'); if (*q == 2) { ip[j] = x; q += 3; continue; } if ((q[3] < '0') || (q[3] > '9')) return -1; x = x * 10 + (q[3] - '0'); if (x > 255) return -1; ip[j] = x; q += 4; } } tinydyndns-0.4.2.debian1/dd.h000066400000000000000000000001241103424076200157560ustar00rootroot00000000000000#ifndef DD_H #define DD_H extern int dd(const char *,const char *,char *); #endif tinydyndns-0.4.2.debian1/direntry.h1000066400000000000000000000002211103424076200173060ustar00rootroot00000000000000#ifndef DIRENTRY_H #define DIRENTRY_H /* sysdep: -dirent */ #include #include #define direntry struct direct #endif tinydyndns-0.4.2.debian1/direntry.h2000066400000000000000000000002201103424076200173060ustar00rootroot00000000000000#ifndef DIRENTRY_H #define DIRENTRY_H /* sysdep: +dirent */ #include #include #define direntry struct dirent #endif tinydyndns-0.4.2.debian1/dns.h000066400000000000000000000056271103424076200161700ustar00rootroot00000000000000#ifndef DNS_H #define DNS_H #include "stralloc.h" #include "iopause.h" #include "taia.h" #define DNS_C_IN "\0\1" #define DNS_C_ANY "\0\377" #define DNS_T_A "\0\1" #define DNS_T_NS "\0\2" #define DNS_T_CNAME "\0\5" #define DNS_T_SOA "\0\6" #define DNS_T_PTR "\0\14" #define DNS_T_HINFO "\0\15" #define DNS_T_MX "\0\17" #define DNS_T_TXT "\0\20" #define DNS_T_RP "\0\21" #define DNS_T_SIG "\0\30" #define DNS_T_KEY "\0\31" #define DNS_T_AAAA "\0\34" #define DNS_T_AXFR "\0\374" #define DNS_T_ANY "\0\377" struct dns_transmit { char *query; /* 0, or dynamically allocated */ unsigned int querylen; char *packet; /* 0, or dynamically allocated */ unsigned int packetlen; int s1; /* 0, or 1 + an open file descriptor */ int tcpstate; unsigned int udploop; unsigned int curserver; struct taia deadline; unsigned int pos; const char *servers; char localip[4]; char qtype[2]; } ; extern void dns_random_init(const char *); extern unsigned int dns_random(unsigned int); extern void dns_sortip(char *,unsigned int); extern void dns_domain_free(char **); extern int dns_domain_copy(char **,const char *); extern unsigned int dns_domain_length(const char *); extern int dns_domain_equal(const char *,const char *); extern int dns_domain_suffix(const char *,const char *); extern unsigned int dns_domain_suffixpos(const char *,const char *); extern int dns_domain_fromdot(char **,const char *,unsigned int); extern int dns_domain_todot_cat(stralloc *,const char *); extern unsigned int dns_packet_copy(const char *,unsigned int,unsigned int,char *,unsigned int); extern unsigned int dns_packet_getname(const char *,unsigned int,unsigned int,char **); extern unsigned int dns_packet_skipname(const char *,unsigned int,unsigned int); extern int dns_transmit_start(struct dns_transmit *,const char *,int,const char *,const char *,const char *); extern void dns_transmit_free(struct dns_transmit *); extern void dns_transmit_io(struct dns_transmit *,iopause_fd *,struct taia *); extern int dns_transmit_get(struct dns_transmit *,const iopause_fd *,const struct taia *); extern int dns_resolvconfip(char *); extern int dns_resolve(const char *,const char *); extern struct dns_transmit dns_resolve_tx; extern int dns_ip4_packet(stralloc *,const char *,unsigned int); extern int dns_ip4(stralloc *,const stralloc *); extern int dns_name_packet(stralloc *,const char *,unsigned int); extern void dns_name4_domain(char *,const char *); #define DNS_NAME4_DOMAIN 31 extern int dns_name4(stralloc *,const char *); extern int dns_txt_packet(stralloc *,const char *,unsigned int); extern int dns_txt(stralloc *,const stralloc *); extern int dns_mx_packet(stralloc *,const char *,unsigned int); extern int dns_mx(stralloc *,const stralloc *); extern int dns_resolvconfrewrite(stralloc *); extern int dns_ip4_qualify_rules(stralloc *,stralloc *,const stralloc *,const stralloc *); extern int dns_ip4_qualify(stralloc *,stralloc *,const stralloc *); #endif tinydyndns-0.4.2.debian1/dns_dfd.c000066400000000000000000000026151103424076200167720ustar00rootroot00000000000000#include "error.h" #include "alloc.h" #include "byte.h" #include "dns.h" int dns_domain_fromdot(char **out,const char *buf,unsigned int n) { char label[63]; unsigned int labellen = 0; /* <= sizeof label */ char name[255]; unsigned int namelen = 0; /* <= sizeof name */ char ch; char *x; errno = error_proto; for (;;) { if (!n) break; ch = *buf++; --n; if (ch == '.') { if (labellen) { if (namelen + labellen + 1 > sizeof name) return 0; name[namelen++] = labellen; byte_copy(name + namelen,labellen,label); namelen += labellen; labellen = 0; } continue; } if (ch == '\\') { if (!n) break; ch = *buf++; --n; if ((ch >= '0') && (ch <= '7')) { ch -= '0'; if (n && (*buf >= '0') && (*buf <= '7')) { ch <<= 3; ch += *buf - '0'; ++buf; --n; if (n && (*buf >= '0') && (*buf <= '7')) { ch <<= 3; ch += *buf - '0'; ++buf; --n; } } } } if (labellen >= sizeof label) return 0; label[labellen++] = ch; } if (labellen) { if (namelen + labellen + 1 > sizeof name) return 0; name[namelen++] = labellen; byte_copy(name + namelen,labellen,label); namelen += labellen; labellen = 0; } if (namelen + 1 > sizeof name) return 0; name[namelen++] = 0; x = alloc(namelen); if (!x) return 0; byte_copy(x,namelen,name); if (*out) alloc_free(*out); *out = x; return 1; } tinydyndns-0.4.2.debian1/dns_domain.c000066400000000000000000000023551103424076200175050ustar00rootroot00000000000000#include "error.h" #include "alloc.h" #include "case.h" #include "byte.h" #include "dns.h" unsigned int dns_domain_length(const char *dn) { const char *x; unsigned char c; x = dn; while (c = *x++) x += (unsigned int) c; return x - dn; } void dns_domain_free(char **out) { if (*out) { alloc_free(*out); *out = 0; } } int dns_domain_copy(char **out,const char *in) { unsigned int len; char *x; len = dns_domain_length(in); x = alloc(len); if (!x) return 0; byte_copy(x,len,in); if (*out) alloc_free(*out); *out = x; return 1; } int dns_domain_equal(const char *dn1,const char *dn2) { unsigned int len; len = dns_domain_length(dn1); if (len != dns_domain_length(dn2)) return 0; if (case_diffb(dn1,len,dn2)) return 0; /* safe since 63 < 'A' */ return 1; } int dns_domain_suffix(const char *big,const char *little) { unsigned char c; for (;;) { if (dns_domain_equal(big,little)) return 1; c = *big++; if (!c) return 0; big += c; } } unsigned int dns_domain_suffixpos(const char *big,const char *little) { const char *orig = big; unsigned char c; for (;;) { if (dns_domain_equal(big,little)) return big - orig; c = *big++; if (!c) return 0; big += c; } } tinydyndns-0.4.2.debian1/dns_dtda.c000066400000000000000000000013741103424076200171520ustar00rootroot00000000000000#include "stralloc.h" #include "dns.h" int dns_domain_todot_cat(stralloc *out,const char *d) { char ch; char ch2; unsigned char ch3; char buf[4]; if (!*d) return stralloc_append(out,"."); for (;;) { ch = *d++; while (ch--) { ch2 = *d++; if ((ch2 >= 'A') && (ch2 <= 'Z')) ch2 += 32; if (((ch2 >= 'a') && (ch2 <= 'z')) || ((ch2 >= '0') && (ch2 <= '9')) || (ch2 == '-') || (ch2 == '_')) { if (!stralloc_append(out,&ch2)) return 0; } else { ch3 = ch2; buf[3] = '0' + (ch3 & 7); ch3 >>= 3; buf[2] = '0' + (ch3 & 7); ch3 >>= 3; buf[1] = '0' + (ch3 & 7); buf[0] = '\\'; if (!stralloc_catb(out,buf,4)) return 0; } } if (!*d) return 1; if (!stralloc_append(out,".")) return 0; } } tinydyndns-0.4.2.debian1/dns_ip.c000066400000000000000000000034161103424076200166450ustar00rootroot00000000000000#include "stralloc.h" #include "uint16.h" #include "byte.h" #include "dns.h" int dns_ip4_packet(stralloc *out,const char *buf,unsigned int len) { unsigned int pos; char header[12]; uint16 numanswers; uint16 datalen; if (!stralloc_copys(out,"")) return -1; pos = dns_packet_copy(buf,len,0,header,12); if (!pos) return -1; uint16_unpack_big(header + 6,&numanswers); pos = dns_packet_skipname(buf,len,pos); if (!pos) return -1; pos += 4; while (numanswers--) { pos = dns_packet_skipname(buf,len,pos); if (!pos) return -1; pos = dns_packet_copy(buf,len,pos,header,10); if (!pos) return -1; uint16_unpack_big(header + 8,&datalen); if (byte_equal(header,2,DNS_T_A)) if (byte_equal(header + 2,2,DNS_C_IN)) if (datalen == 4) { if (!dns_packet_copy(buf,len,pos,header,4)) return -1; if (!stralloc_catb(out,header,4)) return -1; } pos += datalen; } dns_sortip(out->s,out->len); return 0; } static char *q = 0; int dns_ip4(stralloc *out,const stralloc *fqdn) { unsigned int i; char code; char ch; if (!stralloc_copys(out,"")) return -1; code = 0; for (i = 0;i <= fqdn->len;++i) { if (i < fqdn->len) ch = fqdn->s[i]; else ch = '.'; if ((ch == '[') || (ch == ']')) continue; if (ch == '.') { if (!stralloc_append(out,&code)) return -1; code = 0; continue; } if ((ch >= '0') && (ch <= '9')) { code *= 10; code += ch - '0'; continue; } if (!dns_domain_fromdot(&q,fqdn->s,fqdn->len)) return -1; if (dns_resolve(q,DNS_T_A) == -1) return -1; if (dns_ip4_packet(out,dns_resolve_tx.packet,dns_resolve_tx.packetlen) == -1) return -1; dns_transmit_free(&dns_resolve_tx); dns_domain_free(&q); return 0; } out->len &= ~3; return 0; } tinydyndns-0.4.2.debian1/dns_ipq.c000066400000000000000000000034101103424076200170200ustar00rootroot00000000000000#include "stralloc.h" #include "case.h" #include "byte.h" #include "str.h" #include "dns.h" static int doit(stralloc *work,const char *rule) { char ch; unsigned int colon; unsigned int prefixlen; ch = *rule++; if ((ch != '?') && (ch != '=') && (ch != '*') && (ch != '-')) return 1; colon = str_chr(rule,':'); if (!rule[colon]) return 1; if (work->len < colon) return 1; prefixlen = work->len - colon; if ((ch == '=') && prefixlen) return 1; if (case_diffb(rule,colon,work->s + prefixlen)) return 1; if (ch == '?') { if (byte_chr(work->s,prefixlen,'.') < prefixlen) return 1; if (byte_chr(work->s,prefixlen,'[') < prefixlen) return 1; if (byte_chr(work->s,prefixlen,']') < prefixlen) return 1; } work->len = prefixlen; if (ch == '-') work->len = 0; return stralloc_cats(work,rule + colon + 1); } int dns_ip4_qualify_rules(stralloc *out,stralloc *fqdn,const stralloc *in,const stralloc *rules) { unsigned int i; unsigned int j; unsigned int plus; unsigned int fqdnlen; if (!stralloc_copy(fqdn,in)) return -1; for (j = i = 0;j < rules->len;++j) if (!rules->s[j]) { if (!doit(fqdn,rules->s + i)) return -1; i = j + 1; } fqdnlen = fqdn->len; plus = byte_chr(fqdn->s,fqdnlen,'+'); if (plus >= fqdnlen) return dns_ip4(out,fqdn); i = plus + 1; for (;;) { j = byte_chr(fqdn->s + i,fqdnlen - i,'+'); byte_copy(fqdn->s + plus,j,fqdn->s + i); fqdn->len = plus + j; if (dns_ip4(out,fqdn) == -1) return -1; if (out->len) return 0; i += j; if (i >= fqdnlen) return 0; ++i; } } int dns_ip4_qualify(stralloc *out,stralloc *fqdn,const stralloc *in) { static stralloc rules; if (dns_resolvconfrewrite(&rules) == -1) return -1; return dns_ip4_qualify_rules(out,fqdn,in,&rules); } tinydyndns-0.4.2.debian1/dns_mx.c000066400000000000000000000025551103424076200166640ustar00rootroot00000000000000#include "stralloc.h" #include "byte.h" #include "uint16.h" #include "dns.h" static char *q = 0; int dns_mx_packet(stralloc *out,const char *buf,unsigned int len) { unsigned int pos; char header[12]; char pref[2]; uint16 numanswers; uint16 datalen; if (!stralloc_copys(out,"")) return -1; pos = dns_packet_copy(buf,len,0,header,12); if (!pos) return -1; uint16_unpack_big(header + 6,&numanswers); pos = dns_packet_skipname(buf,len,pos); if (!pos) return -1; pos += 4; while (numanswers--) { pos = dns_packet_skipname(buf,len,pos); if (!pos) return -1; pos = dns_packet_copy(buf,len,pos,header,10); if (!pos) return -1; uint16_unpack_big(header + 8,&datalen); if (byte_equal(header,2,DNS_T_MX)) if (byte_equal(header + 2,2,DNS_C_IN)) { if (!dns_packet_copy(buf,len,pos,pref,2)) return -1; if (!dns_packet_getname(buf,len,pos + 2,&q)) return -1; if (!stralloc_catb(out,pref,2)) return -1; if (!dns_domain_todot_cat(out,q)) return -1; if (!stralloc_0(out)) return -1; } pos += datalen; } return 0; } int dns_mx(stralloc *out,const stralloc *fqdn) { if (!dns_domain_fromdot(&q,fqdn->s,fqdn->len)) return -1; if (dns_resolve(q,DNS_T_MX) == -1) return -1; if (dns_mx_packet(out,dns_resolve_tx.packet,dns_resolve_tx.packetlen) == -1) return -1; dns_transmit_free(&dns_resolve_tx); dns_domain_free(&q); return 0; } tinydyndns-0.4.2.debian1/dns_name.c000066400000000000000000000023511103424076200171520ustar00rootroot00000000000000#include "stralloc.h" #include "uint16.h" #include "byte.h" #include "dns.h" static char *q = 0; int dns_name_packet(stralloc *out,const char *buf,unsigned int len) { unsigned int pos; char header[12]; uint16 numanswers; uint16 datalen; if (!stralloc_copys(out,"")) return -1; pos = dns_packet_copy(buf,len,0,header,12); if (!pos) return -1; uint16_unpack_big(header + 6,&numanswers); pos = dns_packet_skipname(buf,len,pos); if (!pos) return -1; pos += 4; while (numanswers--) { pos = dns_packet_skipname(buf,len,pos); if (!pos) return -1; pos = dns_packet_copy(buf,len,pos,header,10); if (!pos) return -1; uint16_unpack_big(header + 8,&datalen); if (byte_equal(header,2,DNS_T_PTR)) if (byte_equal(header + 2,2,DNS_C_IN)) { if (!dns_packet_getname(buf,len,pos,&q)) return -1; if (!dns_domain_todot_cat(out,q)) return -1; return 0; } pos += datalen; } return 0; } int dns_name4(stralloc *out,const char ip[4]) { char name[DNS_NAME4_DOMAIN]; dns_name4_domain(name,ip); if (dns_resolve(name,DNS_T_PTR) == -1) return -1; if (dns_name_packet(out,dns_resolve_tx.packet,dns_resolve_tx.packetlen) == -1) return -1; dns_transmit_free(&dns_resolve_tx); dns_domain_free(&q); return 0; } tinydyndns-0.4.2.debian1/dns_nd.c000066400000000000000000000012631103424076200166340ustar00rootroot00000000000000#include "byte.h" #include "fmt.h" #include "dns.h" void dns_name4_domain(char name[DNS_NAME4_DOMAIN],const char ip[4]) { unsigned int namelen; unsigned int i; namelen = 0; i = fmt_ulong(name + namelen + 1,(unsigned long) (unsigned char) ip[3]); name[namelen++] = i; namelen += i; i = fmt_ulong(name + namelen + 1,(unsigned long) (unsigned char) ip[2]); name[namelen++] = i; namelen += i; i = fmt_ulong(name + namelen + 1,(unsigned long) (unsigned char) ip[1]); name[namelen++] = i; namelen += i; i = fmt_ulong(name + namelen + 1,(unsigned long) (unsigned char) ip[0]); name[namelen++] = i; namelen += i; byte_copy(name + namelen,14,"\7in-addr\4arpa\0"); } tinydyndns-0.4.2.debian1/dns_packet.c000066400000000000000000000033051103424076200175010ustar00rootroot00000000000000/* DNS should have used LZ77 instead of its own sophomoric compression algorithm. */ #include "error.h" #include "dns.h" unsigned int dns_packet_copy(const char *buf,unsigned int len,unsigned int pos,char *out,unsigned int outlen) { while (outlen) { if (pos >= len) { errno = error_proto; return 0; } *out = buf[pos++]; ++out; --outlen; } return pos; } unsigned int dns_packet_skipname(const char *buf,unsigned int len,unsigned int pos) { unsigned char ch; for (;;) { if (pos >= len) break; ch = buf[pos++]; if (ch >= 192) return pos + 1; if (ch >= 64) break; if (!ch) return pos; pos += ch; } errno = error_proto; return 0; } unsigned int dns_packet_getname(const char *buf,unsigned int len,unsigned int pos,char **d) { unsigned int loop = 0; unsigned int state = 0; unsigned int firstcompress = 0; unsigned int where; unsigned char ch; char name[255]; unsigned int namelen = 0; for (;;) { if (pos >= len) goto PROTO; ch = buf[pos++]; if (++loop >= 1000) goto PROTO; if (state) { if (namelen + 1 > sizeof name) goto PROTO; name[namelen++] = ch; --state; } else { while (ch >= 192) { where = ch; where -= 192; where <<= 8; if (pos >= len) goto PROTO; ch = buf[pos++]; if (!firstcompress) firstcompress = pos; pos = where + ch; if (pos >= len) goto PROTO; ch = buf[pos++]; if (++loop >= 1000) goto PROTO; } if (ch >= 64) goto PROTO; if (namelen + 1 > sizeof name) goto PROTO; name[namelen++] = ch; if (!ch) break; state = ch; } } if (!dns_domain_copy(d,name)) return 0; if (firstcompress) return firstcompress; return pos; PROTO: errno = error_proto; return 0; } tinydyndns-0.4.2.debian1/dns_random.c000066400000000000000000000025301103424076200175110ustar00rootroot00000000000000#include #include "dns.h" #include "taia.h" #include "uint32.h" static uint32 seed[32]; static uint32 in[12]; static uint32 out[8]; static int outleft = 0; #define ROTATE(x,b) (((x) << (b)) | ((x) >> (32 - (b)))) #define MUSH(i,b) x = t[i] += (((x ^ seed[i]) + sum) ^ ROTATE(x,b)); static void surf(void) { uint32 t[12]; uint32 x; uint32 sum = 0; int r; int i; int loop; for (i = 0;i < 12;++i) t[i] = in[i] ^ seed[12 + i]; for (i = 0;i < 8;++i) out[i] = seed[24 + i]; x = t[11]; for (loop = 0;loop < 2;++loop) { for (r = 0;r < 16;++r) { sum += 0x9e3779b9; MUSH(0,5) MUSH(1,7) MUSH(2,9) MUSH(3,13) MUSH(4,5) MUSH(5,7) MUSH(6,9) MUSH(7,13) MUSH(8,5) MUSH(9,7) MUSH(10,9) MUSH(11,13) } for (i = 0;i < 8;++i) out[i] ^= t[i + 4]; } } void dns_random_init(const char data[128]) { int i; struct taia t; char tpack[16]; for (i = 0;i < 32;++i) uint32_unpack(data + 4 * i,seed + i); taia_now(&t); taia_pack(tpack,&t); for (i = 0;i < 4;++i) uint32_unpack(tpack + 4 * i,in + 4 + i); in[8] = getpid(); in[9] = getppid(); /* more space in 10 and 11, but this is probably enough */ } unsigned int dns_random(unsigned int n) { if (!n) return 0; if (!outleft) { if (!++in[0]) if (!++in[1]) if (!++in[2]) ++in[3]; surf(); outleft = 8; } return out[--outleft] % n; } tinydyndns-0.4.2.debian1/dns_rcip.c000066400000000000000000000032271103424076200171720ustar00rootroot00000000000000#include "taia.h" #include "openreadclose.h" #include "byte.h" #include "ip4.h" #include "env.h" #include "dns.h" static stralloc data = {0}; static int init(char ip[64]) { int i; int j; int iplen = 0; char *x; x = env_get("DNSCACHEIP"); if (x) while (iplen <= 60) { if (*x == '.') ++x; else { i = ip4_scan(x,ip + iplen); if (!i) break; x += i; iplen += 4; } } if (!iplen) { i = openreadclose("/etc/resolv.conf",&data,64); if (i == -1) return -1; if (i) { if (!stralloc_append(&data,"\n")) return -1; i = 0; for (j = 0;j < data.len;++j) if (data.s[j] == '\n') { if (byte_equal("nameserver ",11,data.s + i) || byte_equal("nameserver\t",11,data.s + i)) { i += 10; while ((data.s[i] == ' ') || (data.s[i] == '\t')) ++i; if (iplen <= 60) if (ip4_scan(data.s + i,ip + iplen)) { if (byte_equal(ip + iplen,4,"\0\0\0\0")) byte_copy(ip + iplen,4,"\177\0\0\1"); iplen += 4; } } i = j + 1; } } } if (!iplen) { byte_copy(ip,4,"\177\0\0\1"); iplen = 4; } byte_zero(ip + iplen,64 - iplen); return 0; } static int ok = 0; static unsigned int uses; static struct taia deadline; static char ip[64]; /* defined if ok */ int dns_resolvconfip(char s[64]) { struct taia now; taia_now(&now); if (taia_less(&deadline,&now)) ok = 0; if (!uses) ok = 0; if (!ok) { if (init(ip) == -1) return -1; taia_uint(&deadline,600); taia_add(&deadline,&now,&deadline); uses = 10000; ok = 1; } --uses; byte_copy(s,64,ip); return 0; } tinydyndns-0.4.2.debian1/dns_rcrw.c000066400000000000000000000064011103424076200172070ustar00rootroot00000000000000#include #include "taia.h" #include "env.h" #include "byte.h" #include "str.h" #include "openreadclose.h" #include "dns.h" static stralloc data = {0}; static int init(stralloc *rules) { char host[256]; const char *x; int i; int j; int k; if (!stralloc_copys(rules,"")) return -1; x = env_get("DNSREWRITEFILE"); if (!x) x = "/etc/dnsrewrite"; i = openreadclose(x,&data,64); if (i == -1) return -1; if (i) { if (!stralloc_append(&data,"\n")) return -1; i = 0; for (j = 0;j < data.len;++j) if (data.s[j] == '\n') { if (!stralloc_catb(rules,data.s + i,j - i)) return -1; while (rules->len) { if (rules->s[rules->len - 1] != ' ') if (rules->s[rules->len - 1] != '\t') if (rules->s[rules->len - 1] != '\r') break; --rules->len; } if (!stralloc_0(rules)) return -1; i = j + 1; } return 0; } x = env_get("LOCALDOMAIN"); if (x) { if (!stralloc_copys(&data,x)) return -1; if (!stralloc_append(&data," ")) return -1; if (!stralloc_copys(rules,"?:")) return -1; i = 0; for (j = 0;j < data.len;++j) if (data.s[j] == ' ') { if (!stralloc_cats(rules,"+.")) return -1; if (!stralloc_catb(rules,data.s + i,j - i)) return -1; i = j + 1; } if (!stralloc_0(rules)) return -1; if (!stralloc_cats(rules,"*.:")) return -1; if (!stralloc_0(rules)) return -1; return 0; } i = openreadclose("/etc/resolv.conf",&data,64); if (i == -1) return -1; if (i) { if (!stralloc_append(&data,"\n")) return -1; i = 0; for (j = 0;j < data.len;++j) if (data.s[j] == '\n') { if (byte_equal("search ",7,data.s + i) || byte_equal("search\t",7,data.s + i) || byte_equal("domain ",7,data.s + i) || byte_equal("domain\t",7,data.s + i)) { if (!stralloc_copys(rules,"?:")) return -1; i += 7; while (i < j) { k = byte_chr(data.s + i,j - i,' '); k = byte_chr(data.s + i,k,'\t'); if (!k) { ++i; continue; } if (!stralloc_cats(rules,"+.")) return -1; if (!stralloc_catb(rules,data.s + i,k)) return -1; i += k; } if (!stralloc_0(rules)) return -1; if (!stralloc_cats(rules,"*.:")) return -1; if (!stralloc_0(rules)) return -1; return 0; } i = j + 1; } } host[0] = 0; if (gethostname(host,sizeof host) == -1) return -1; host[(sizeof host) - 1] = 0; i = str_chr(host,'.'); if (host[i]) { if (!stralloc_copys(rules,"?:")) return -1; if (!stralloc_cats(rules,host + i)) return -1; if (!stralloc_0(rules)) return -1; } if (!stralloc_cats(rules,"*.:")) return -1; if (!stralloc_0(rules)) return -1; return 0; } static int ok = 0; static unsigned int uses; static struct taia deadline; static stralloc rules = {0}; /* defined if ok */ int dns_resolvconfrewrite(stralloc *out) { struct taia now; taia_now(&now); if (taia_less(&deadline,&now)) ok = 0; if (!uses) ok = 0; if (!ok) { if (init(&rules) == -1) return -1; taia_uint(&deadline,600); taia_add(&deadline,&now,&deadline); uses = 10000; ok = 1; } --uses; if (!stralloc_copy(out,&rules)) return -1; return 0; } tinydyndns-0.4.2.debian1/dns_resolve.c000066400000000000000000000013051103424076200177070ustar00rootroot00000000000000#include "iopause.h" #include "taia.h" #include "byte.h" #include "dns.h" struct dns_transmit dns_resolve_tx = {0}; int dns_resolve(const char *q,const char qtype[2]) { struct taia stamp; struct taia deadline; char servers[64]; iopause_fd x[1]; int r; if (dns_resolvconfip(servers) == -1) return -1; if (dns_transmit_start(&dns_resolve_tx,servers,1,q,qtype,"\0\0\0\0") == -1) return -1; for (;;) { taia_now(&stamp); taia_uint(&deadline,120); taia_add(&deadline,&deadline,&stamp); dns_transmit_io(&dns_resolve_tx,x,&deadline); iopause(x,1,&deadline,&stamp); r = dns_transmit_get(&dns_resolve_tx,x,&stamp); if (r == -1) return -1; if (r == 1) return 0; } } tinydyndns-0.4.2.debian1/dns_sortip.c000066400000000000000000000006321103424076200175520ustar00rootroot00000000000000#include "byte.h" #include "dns.h" /* XXX: sort servers by configurable notion of closeness? */ /* XXX: pay attention to competence of each server? */ void dns_sortip(char *s,unsigned int n) { unsigned int i; char tmp[4]; n >>= 2; while (n > 1) { i = dns_random(n); --n; byte_copy(tmp,4,s + (i << 2)); byte_copy(s + (i << 2),4,s + (n << 2)); byte_copy(s + (n << 2),4,tmp); } } tinydyndns-0.4.2.debian1/dns_transmit.c000066400000000000000000000202241103424076200200720ustar00rootroot00000000000000#include #include #include #include "socket.h" #include "alloc.h" #include "error.h" #include "byte.h" #include "uint16.h" #include "dns.h" static int serverwantstcp(const char *buf,unsigned int len) { char out[12]; if (!dns_packet_copy(buf,len,0,out,12)) return 1; if (out[2] & 2) return 1; return 0; } static int serverfailed(const char *buf,unsigned int len) { char out[12]; unsigned int rcode; if (!dns_packet_copy(buf,len,0,out,12)) return 1; rcode = out[3]; rcode &= 15; if (rcode && (rcode != 3)) { errno = error_again; return 1; } return 0; } static int irrelevant(const struct dns_transmit *d,const char *buf,unsigned int len) { char out[12]; char *dn; unsigned int pos; pos = dns_packet_copy(buf,len,0,out,12); if (!pos) return 1; if (byte_diff(out,2,d->query + 2)) return 1; if (out[4] != 0) return 1; if (out[5] != 1) return 1; dn = 0; pos = dns_packet_getname(buf,len,pos,&dn); if (!pos) return 1; if (!dns_domain_equal(dn,d->query + 14)) { alloc_free(dn); return 1; } alloc_free(dn); pos = dns_packet_copy(buf,len,pos,out,4); if (!pos) return 1; if (byte_diff(out,2,d->qtype)) return 1; if (byte_diff(out + 2,2,DNS_C_IN)) return 1; return 0; } static void packetfree(struct dns_transmit *d) { if (!d->packet) return; alloc_free(d->packet); d->packet = 0; } static void queryfree(struct dns_transmit *d) { if (!d->query) return; alloc_free(d->query); d->query = 0; } static void socketfree(struct dns_transmit *d) { if (!d->s1) return; close(d->s1 - 1); d->s1 = 0; } void dns_transmit_free(struct dns_transmit *d) { queryfree(d); socketfree(d); packetfree(d); } static int randombind(struct dns_transmit *d) { int j; for (j = 0;j < 10;++j) if (socket_bind4(d->s1 - 1,d->localip,1025 + dns_random(64510)) == 0) return 0; if (socket_bind4(d->s1 - 1,d->localip,0) == 0) return 0; return -1; } static const int timeouts[4] = { 1, 3, 11, 45 }; static int thisudp(struct dns_transmit *d) { const char *ip; socketfree(d); while (d->udploop < 4) { for (;d->curserver < 16;++d->curserver) { ip = d->servers + 4 * d->curserver; if (byte_diff(ip,4,"\0\0\0\0")) { d->query[2] = dns_random(256); d->query[3] = dns_random(256); d->s1 = 1 + socket_udp(); if (!d->s1) { dns_transmit_free(d); return -1; } if (randombind(d) == -1) { dns_transmit_free(d); return -1; } if (socket_connect4(d->s1 - 1,ip,53) == 0) if (send(d->s1 - 1,d->query + 2,d->querylen - 2,0) == d->querylen - 2) { struct taia now; taia_now(&now); taia_uint(&d->deadline,timeouts[d->udploop]); taia_add(&d->deadline,&d->deadline,&now); d->tcpstate = 0; return 0; } socketfree(d); } } ++d->udploop; d->curserver = 0; } dns_transmit_free(d); return -1; } static int firstudp(struct dns_transmit *d) { d->curserver = 0; return thisudp(d); } static int nextudp(struct dns_transmit *d) { ++d->curserver; return thisudp(d); } static int thistcp(struct dns_transmit *d) { struct taia now; const char *ip; socketfree(d); packetfree(d); for (;d->curserver < 16;++d->curserver) { ip = d->servers + 4 * d->curserver; if (byte_diff(ip,4,"\0\0\0\0")) { d->query[2] = dns_random(256); d->query[3] = dns_random(256); d->s1 = 1 + socket_tcp(); if (!d->s1) { dns_transmit_free(d); return -1; } if (randombind(d) == -1) { dns_transmit_free(d); return -1; } taia_now(&now); taia_uint(&d->deadline,10); taia_add(&d->deadline,&d->deadline,&now); if (socket_connect4(d->s1 - 1,ip,53) == 0) { d->tcpstate = 2; return 0; } if ((errno == error_inprogress) || (errno == error_wouldblock)) { d->tcpstate = 1; return 0; } socketfree(d); } } dns_transmit_free(d); return -1; } static int firsttcp(struct dns_transmit *d) { d->curserver = 0; return thistcp(d); } static int nexttcp(struct dns_transmit *d) { ++d->curserver; return thistcp(d); } int dns_transmit_start(struct dns_transmit *d,const char servers[64],int flagrecursive,const char *q,const char qtype[2],const char localip[4]) { unsigned int len; dns_transmit_free(d); errno = error_io; len = dns_domain_length(q); d->querylen = len + 18; d->query = alloc(d->querylen); if (!d->query) return -1; uint16_pack_big(d->query,len + 16); byte_copy(d->query + 2,12,flagrecursive ? "\0\0\1\0\0\1\0\0\0\0\0\0" : "\0\0\0\0\0\1\0\0\0\0\0\0gcc-bug-workaround"); byte_copy(d->query + 14,len,q); byte_copy(d->query + 14 + len,2,qtype); byte_copy(d->query + 16 + len,2,DNS_C_IN); byte_copy(d->qtype,2,qtype); d->servers = servers; byte_copy(d->localip,4,localip); d->udploop = flagrecursive ? 1 : 0; if (len + 16 > 512) return firsttcp(d); return firstudp(d); } void dns_transmit_io(struct dns_transmit *d,iopause_fd *x,struct taia *deadline) { x->fd = d->s1 - 1; switch(d->tcpstate) { case 0: case 3: case 4: case 5: x->events = IOPAUSE_READ; break; case 1: case 2: x->events = IOPAUSE_WRITE; break; } if (taia_less(&d->deadline,deadline)) *deadline = d->deadline; } int dns_transmit_get(struct dns_transmit *d,const iopause_fd *x,const struct taia *when) { char udpbuf[513]; unsigned char ch; int r; int fd; errno = error_io; fd = d->s1 - 1; if (!x->revents) { if (taia_less(when,&d->deadline)) return 0; errno = error_timeout; if (d->tcpstate == 0) return nextudp(d); return nexttcp(d); } if (d->tcpstate == 0) { /* have attempted to send UDP query to each server udploop times have sent query to curserver on UDP socket s */ r = recv(fd,udpbuf,sizeof udpbuf,0); if (r <= 0) { if (errno == error_connrefused) if (d->udploop == 2) return 0; return nextudp(d); } if (r + 1 > sizeof udpbuf) return 0; if (irrelevant(d,udpbuf,r)) return 0; if (serverwantstcp(udpbuf,r)) return firsttcp(d); if (serverfailed(udpbuf,r)) { if (d->udploop == 2) return 0; return nextudp(d); } socketfree(d); d->packetlen = r; d->packet = alloc(d->packetlen); if (!d->packet) { dns_transmit_free(d); return -1; } byte_copy(d->packet,d->packetlen,udpbuf); queryfree(d); return 1; } if (d->tcpstate == 1) { /* have sent connection attempt to curserver on TCP socket s pos not defined */ if (!socket_connected(fd)) return nexttcp(d); d->pos = 0; d->tcpstate = 2; return 0; } if (d->tcpstate == 2) { /* have connection to curserver on TCP socket s have sent pos bytes of query */ r = write(fd,d->query + d->pos,d->querylen - d->pos); if (r <= 0) return nexttcp(d); d->pos += r; if (d->pos == d->querylen) { struct taia now; taia_now(&now); taia_uint(&d->deadline,10); taia_add(&d->deadline,&d->deadline,&now); d->tcpstate = 3; } return 0; } if (d->tcpstate == 3) { /* have sent entire query to curserver on TCP socket s pos not defined */ r = read(fd,&ch,1); if (r <= 0) return nexttcp(d); d->packetlen = ch; d->tcpstate = 4; return 0; } if (d->tcpstate == 4) { /* have sent entire query to curserver on TCP socket s pos not defined have received one byte of packet length into packetlen */ r = read(fd,&ch,1); if (r <= 0) return nexttcp(d); d->packetlen <<= 8; d->packetlen += ch; d->tcpstate = 5; d->pos = 0; d->packet = alloc(d->packetlen); if (!d->packet) { dns_transmit_free(d); return -1; } return 0; } if (d->tcpstate == 5) { /* have sent entire query to curserver on TCP socket s have received entire packet length into packetlen packet is allocated have received pos bytes of packet */ r = read(fd,d->packet + d->pos,d->packetlen - d->pos); if (r <= 0) return nexttcp(d); d->pos += r; if (d->pos < d->packetlen) return 0; socketfree(d); if (irrelevant(d,d->packet,d->packetlen)) return nexttcp(d); if (serverwantstcp(d->packet,d->packetlen)) return nexttcp(d); if (serverfailed(d->packet,d->packetlen)) return nexttcp(d); queryfree(d); return 1; } return 0; } tinydyndns-0.4.2.debian1/dns_txt.c000066400000000000000000000027041103424076200170530ustar00rootroot00000000000000#include "stralloc.h" #include "uint16.h" #include "byte.h" #include "dns.h" int dns_txt_packet(stralloc *out,const char *buf,unsigned int len) { unsigned int pos; char header[12]; uint16 numanswers; uint16 datalen; char ch; unsigned int txtlen; int i; if (!stralloc_copys(out,"")) return -1; pos = dns_packet_copy(buf,len,0,header,12); if (!pos) return -1; uint16_unpack_big(header + 6,&numanswers); pos = dns_packet_skipname(buf,len,pos); if (!pos) return -1; pos += 4; while (numanswers--) { pos = dns_packet_skipname(buf,len,pos); if (!pos) return -1; pos = dns_packet_copy(buf,len,pos,header,10); if (!pos) return -1; uint16_unpack_big(header + 8,&datalen); if (byte_equal(header,2,DNS_T_TXT)) if (byte_equal(header + 2,2,DNS_C_IN)) { if (pos + datalen > len) return -1; txtlen = 0; for (i = 0;i < datalen;++i) { ch = buf[pos + i]; if (!txtlen) txtlen = (unsigned char) ch; else { --txtlen; if (ch < 32) ch = '?'; if (ch > 126) ch = '?'; if (!stralloc_append(out,&ch)) return -1; } } } pos += datalen; } return 0; } static char *q = 0; int dns_txt(stralloc *out,const stralloc *fqdn) { if (!dns_domain_fromdot(&q,fqdn->s,fqdn->len)) return -1; if (dns_resolve(q,DNS_T_TXT) == -1) return -1; if (dns_txt_packet(out,dns_resolve_tx.packet,dns_resolve_tx.packetlen) == -1) return -1; dns_transmit_free(&dns_resolve_tx); dns_domain_free(&q); return 0; } tinydyndns-0.4.2.debian1/dnscache-conf.c000066400000000000000000000106641103424076200200670ustar00rootroot00000000000000#include #include #include #include "hasdevtcp.h" #ifdef HASDEVTCP #include #endif #include #include "strerr.h" #include "buffer.h" #include "uint32.h" #include "taia.h" #include "str.h" #include "open.h" #include "error.h" #include "exit.h" #include "auto_home.h" #include "generic-conf.h" #define FATAL "dnscache-conf: fatal: " void usage(void) { strerr_die1x(100,"dnscache-conf: usage: dnscache-conf acct logacct /dnscache [ myip ]"); } int fdrootservers; char rootserversbuf[64]; buffer ssrootservers; char *dir; char *user; char *loguser; struct passwd *pw; const char *myip; uint32 seed[32]; int seedpos = 0; void seed_adduint32(uint32 u) { int i; seed[seedpos] += u; if (++seedpos == 32) { for (i = 0;i < 32;++i) { u = ((u ^ seed[i]) + 0x9e3779b9) ^ (u << 7) ^ (u >> 25); seed[i] = u; } seedpos = 0; } } void seed_addtime(void) { struct taia t; char tpack[TAIA_PACK]; int i; taia_now(&t); taia_pack(tpack,&t); for (i = 0;i < TAIA_PACK;++i) seed_adduint32(tpack[i]); } int main(int argc,char **argv) { seed_addtime(); seed_adduint32(getpid()); seed_adduint32(getppid()); seed_adduint32(getuid()); seed_adduint32(getgid()); user = argv[1]; if (!user) usage(); loguser = argv[2]; if (!loguser) usage(); dir = argv[3]; if (!dir) usage(); if (dir[0] != '/') usage(); myip = argv[4]; if (!myip) myip = "127.0.0.1"; pw = getpwnam(loguser); seed_addtime(); if (!pw) strerr_die3x(111,FATAL,"unknown account ",loguser); if (chdir(auto_home) == -1) strerr_die4sys(111,FATAL,"unable to switch to ",auto_home,": "); fdrootservers = open_read("/etc/dnsroots.local"); if (fdrootservers == -1) { if (errno != error_noent) strerr_die2sys(111,FATAL,"unable to open /etc/dnsroots.local: "); fdrootservers = open_read("/etc/dnsroots.global"); if (fdrootservers == -1) strerr_die2sys(111,FATAL,"unable to open /etc/dnsroots.global: "); } init(dir,FATAL); seed_addtime(); makedir("log"); seed_addtime(); perm(02755); seed_addtime(); makedir("log/main"); seed_addtime(); owner(pw->pw_uid,pw->pw_gid); seed_addtime(); perm(02755); seed_addtime(); start("log/status"); finish(); seed_addtime(); owner(pw->pw_uid,pw->pw_gid); seed_addtime(); perm(0644); seed_addtime(); makedir("env"); seed_addtime(); perm(02755); seed_addtime(); start("env/ROOT"); outs(dir); outs("/root\n"); finish(); seed_addtime(); perm(0644); seed_addtime(); start("env/IP"); outs(myip); outs("\n"); finish(); seed_addtime(); perm(0644); seed_addtime(); start("env/IPSEND"); outs("0.0.0.0\n"); finish(); seed_addtime(); perm(0644); seed_addtime(); start("env/CACHESIZE"); outs("1000000\n"); finish(); seed_addtime(); perm(0644); seed_addtime(); start("env/DATALIMIT"); outs("3000000\n"); finish(); seed_addtime(); perm(0644); seed_addtime(); start("run"); outs("#!/bin/sh\nexec 2>&1\nexec #include "env.h" #include "exit.h" #include "scan.h" #include "strerr.h" #include "error.h" #include "ip4.h" #include "uint16.h" #include "uint64.h" #include "socket.h" #include "dns.h" #include "taia.h" #include "byte.h" #include "roots.h" #include "fmt.h" #include "iopause.h" #include "query.h" #include "alloc.h" #include "response.h" #include "cache.h" #include "ndelay.h" #include "log.h" #include "okclient.h" #include "droproot.h" static int packetquery(char *buf,unsigned int len,char **q,char qtype[2],char qclass[2],char id[2]) { unsigned int pos; char header[12]; errno = error_proto; pos = dns_packet_copy(buf,len,0,header,12); if (!pos) return 0; if (header[2] & 128) return 0; /* must not respond to responses */ if (!(header[2] & 1)) return 0; /* do not respond to non-recursive queries */ if (header[2] & 120) return 0; if (header[2] & 2) return 0; if (byte_diff(header + 4,2,"\0\1")) return 0; pos = dns_packet_getname(buf,len,pos,q); if (!pos) return 0; pos = dns_packet_copy(buf,len,pos,qtype,2); if (!pos) return 0; pos = dns_packet_copy(buf,len,pos,qclass,2); if (!pos) return 0; if (byte_diff(qclass,2,DNS_C_IN) && byte_diff(qclass,2,DNS_C_ANY)) return 0; byte_copy(id,2,header); return 1; } static char myipoutgoing[4]; static char myipincoming[4]; static char buf[1024]; uint64 numqueries = 0; static int udp53; #define MAXUDP 200 static struct udpclient { struct query q; struct taia start; uint64 active; /* query number, if active; otherwise 0 */ iopause_fd *io; char ip[4]; uint16 port; char id[2]; } u[MAXUDP]; int uactive = 0; void u_drop(int j) { if (!u[j].active) return; log_querydrop(&u[j].active); u[j].active = 0; --uactive; } void u_respond(int j) { if (!u[j].active) return; response_id(u[j].id); if (response_len > 512) response_tc(); socket_send4(udp53,response,response_len,u[j].ip,u[j].port); log_querydone(&u[j].active,response_len); u[j].active = 0; --uactive; } void u_new(void) { int j; int i; struct udpclient *x; int len; static char *q = 0; char qtype[2]; char qclass[2]; for (j = 0;j < MAXUDP;++j) if (!u[j].active) break; if (j >= MAXUDP) { j = 0; for (i = 1;i < MAXUDP;++i) if (taia_less(&u[i].start,&u[j].start)) j = i; errno = error_timeout; u_drop(j); } x = u + j; taia_now(&x->start); len = socket_recv4(udp53,buf,sizeof buf,x->ip,&x->port); if (len == -1) return; if (len >= sizeof buf) return; if (x->port < 1024) if (x->port != 53) return; if (!okclient(x->ip)) return; if (!packetquery(buf,len,&q,qtype,qclass,x->id)) return; x->active = ++numqueries; ++uactive; log_query(&x->active,x->ip,x->port,x->id,q,qtype); switch(query_start(&x->q,q,qtype,qclass,myipoutgoing)) { case -1: u_drop(j); return; case 1: u_respond(j); } } static int tcp53; #define MAXTCP 20 struct tcpclient { struct query q; struct taia start; struct taia timeout; uint64 active; /* query number or 1, if active; otherwise 0 */ iopause_fd *io; char ip[4]; /* send response to this address */ uint16 port; /* send response to this port */ char id[2]; int tcp; /* open TCP socket, if active */ int state; char *buf; /* 0, or dynamically allocated of length len */ unsigned int len; unsigned int pos; } t[MAXTCP]; int tactive = 0; /* state 1: buf 0; normal state at beginning of TCP connection state 2: buf 0; have read 1 byte of query packet length into len state 3: buf allocated; have read pos bytes of buf state 0: buf 0; handling query in q state -1: buf allocated; have written pos bytes */ void t_free(int j) { if (!t[j].buf) return; alloc_free(t[j].buf); t[j].buf = 0; } void t_timeout(int j) { struct taia now; if (!t[j].active) return; taia_now(&now); taia_uint(&t[j].timeout,10); taia_add(&t[j].timeout,&t[j].timeout,&now); } void t_close(int j) { if (!t[j].active) return; t_free(j); log_tcpclose(t[j].ip,t[j].port); close(t[j].tcp); t[j].active = 0; --tactive; } void t_drop(int j) { log_querydrop(&t[j].active); errno = error_pipe; t_close(j); } void t_respond(int j) { if (!t[j].active) return; log_querydone(&t[j].active,response_len); response_id(t[j].id); t[j].len = response_len + 2; t_free(j); t[j].buf = alloc(response_len + 2); if (!t[j].buf) { t_close(j); return; } uint16_pack_big(t[j].buf,response_len); byte_copy(t[j].buf + 2,response_len,response); t[j].pos = 0; t[j].state = -1; } void t_rw(int j) { struct tcpclient *x; char ch; static char *q = 0; char qtype[2]; char qclass[2]; int r; x = t + j; if (x->state == -1) { r = write(x->tcp,x->buf + x->pos,x->len - x->pos); if (r <= 0) { t_close(j); return; } x->pos += r; if (x->pos == x->len) { t_free(j); x->state = 1; /* could drop connection immediately */ } return; } r = read(x->tcp,&ch,1); if (r == 0) { errno = error_pipe; t_close(j); return; } if (r < 0) { t_close(j); return; } if (x->state == 1) { x->len = (unsigned char) ch; x->len <<= 8; x->state = 2; return; } if (x->state == 2) { x->len += (unsigned char) ch; if (!x->len) { errno = error_proto; t_close(j); return; } x->buf = alloc(x->len); if (!x->buf) { t_close(j); return; } x->pos = 0; x->state = 3; return; } if (x->state != 3) return; /* impossible */ x->buf[x->pos++] = ch; if (x->pos < x->len) return; if (!packetquery(x->buf,x->len,&q,qtype,qclass,x->id)) { t_close(j); return; } x->active = ++numqueries; log_query(&x->active,x->ip,x->port,x->id,q,qtype); switch(query_start(&x->q,q,qtype,qclass,myipoutgoing)) { case -1: t_drop(j); return; case 1: t_respond(j); return; } t_free(j); x->state = 0; } void t_new(void) { int i; int j; struct tcpclient *x; for (j = 0;j < MAXTCP;++j) if (!t[j].active) break; if (j >= MAXTCP) { j = 0; for (i = 1;i < MAXTCP;++i) if (taia_less(&t[i].start,&t[j].start)) j = i; errno = error_timeout; if (t[j].state == 0) t_drop(j); else t_close(j); } x = t + j; taia_now(&x->start); x->tcp = socket_accept4(tcp53,x->ip,&x->port); if (x->tcp == -1) return; if (x->port < 1024) if (x->port != 53) { close(x->tcp); return; } if (!okclient(x->ip)) { close(x->tcp); return; } if (ndelay_on(x->tcp) == -1) { close(x->tcp); return; } /* Linux bug */ x->active = 1; ++tactive; x->state = 1; t_timeout(j); log_tcpopen(x->ip,x->port); } iopause_fd io[3 + MAXUDP + MAXTCP]; iopause_fd *udp53io; iopause_fd *tcp53io; static void doit(void) { int j; struct taia deadline; struct taia stamp; int iolen; int r; for (;;) { taia_now(&stamp); taia_uint(&deadline,120); taia_add(&deadline,&deadline,&stamp); iolen = 0; udp53io = io + iolen++; udp53io->fd = udp53; udp53io->events = IOPAUSE_READ; tcp53io = io + iolen++; tcp53io->fd = tcp53; tcp53io->events = IOPAUSE_READ; for (j = 0;j < MAXUDP;++j) if (u[j].active) { u[j].io = io + iolen++; query_io(&u[j].q,u[j].io,&deadline); } for (j = 0;j < MAXTCP;++j) if (t[j].active) { t[j].io = io + iolen++; if (t[j].state == 0) query_io(&t[j].q,t[j].io,&deadline); else { if (taia_less(&t[j].timeout,&deadline)) deadline = t[j].timeout; t[j].io->fd = t[j].tcp; t[j].io->events = (t[j].state > 0) ? IOPAUSE_READ : IOPAUSE_WRITE; } } iopause(io,iolen,&deadline,&stamp); for (j = 0;j < MAXUDP;++j) if (u[j].active) { r = query_get(&u[j].q,u[j].io,&stamp); if (r == -1) u_drop(j); if (r == 1) u_respond(j); } for (j = 0;j < MAXTCP;++j) if (t[j].active) { if (t[j].io->revents) t_timeout(j); if (t[j].state == 0) { r = query_get(&t[j].q,t[j].io,&stamp); if (r == -1) t_drop(j); if (r == 1) t_respond(j); } else if (t[j].io->revents || taia_less(&t[j].timeout,&stamp)) t_rw(j); } if (udp53io) if (udp53io->revents) u_new(); if (tcp53io) if (tcp53io->revents) t_new(); } } #define FATAL "dnscache: fatal: " char seed[128]; int main() { char *x; unsigned long cachesize; x = env_get("IP"); if (!x) strerr_die2x(111,FATAL,"$IP not set"); if (!ip4_scan(x,myipincoming)) strerr_die3x(111,FATAL,"unable to parse IP address ",x); udp53 = socket_udp(); if (udp53 == -1) strerr_die2sys(111,FATAL,"unable to create UDP socket: "); if (socket_bind4_reuse(udp53,myipincoming,53) == -1) strerr_die2sys(111,FATAL,"unable to bind UDP socket: "); tcp53 = socket_tcp(); if (tcp53 == -1) strerr_die2sys(111,FATAL,"unable to create TCP socket: "); if (socket_bind4_reuse(tcp53,myipincoming,53) == -1) strerr_die2sys(111,FATAL,"unable to bind TCP socket: "); droproot(FATAL); socket_tryreservein(udp53,131072); byte_zero(seed,sizeof seed); read(0,seed,sizeof seed); dns_random_init(seed); close(0); x = env_get("IPSEND"); if (!x) strerr_die2x(111,FATAL,"$IPSEND not set"); if (!ip4_scan(x,myipoutgoing)) strerr_die3x(111,FATAL,"unable to parse IP address ",x); x = env_get("CACHESIZE"); if (!x) strerr_die2x(111,FATAL,"$CACHESIZE not set"); scan_ulong(x,&cachesize); if (!cache_init(cachesize)) strerr_die3x(111,FATAL,"not enough memory for cache of size ",x); if (env_get("HIDETTL")) response_hidettl(); if (env_get("FORWARDONLY")) query_forwardonly(); if (!roots_init()) strerr_die2sys(111,FATAL,"unable to read servers: "); if (socket_listen(tcp53,20) == -1) strerr_die2sys(111,FATAL,"unable to listen on TCP socket: "); log_startup(); doit(); } tinydyndns-0.4.2.debian1/dnsfilter.c000066400000000000000000000111541103424076200173610ustar00rootroot00000000000000#include #include "strerr.h" #include "buffer.h" #include "stralloc.h" #include "alloc.h" #include "dns.h" #include "ip4.h" #include "byte.h" #include "scan.h" #include "taia.h" #include "sgetopt.h" #include "iopause.h" #include "error.h" #include "exit.h" #define FATAL "dnsfilter: fatal: " void nomem(void) { strerr_die2x(111,FATAL,"out of memory"); } struct line { stralloc left; stralloc middle; stralloc right; struct dns_transmit dt; int flagactive; iopause_fd *io; } *x; struct line tmp; unsigned int xmax = 1000; unsigned int xnum = 0; unsigned int numactive = 0; unsigned int maxactive = 10; static stralloc partial; char inbuf[1024]; int inbuflen = 0; iopause_fd *inio; int flag0 = 1; iopause_fd *io; int iolen; char servers[64]; char ip[4]; char name[DNS_NAME4_DOMAIN]; void errout(int i) { int j; if (!stralloc_copys(&x[i].middle,":")) nomem(); if (!stralloc_cats(&x[i].middle,error_str(errno))) nomem(); for (j = 0;j < x[i].middle.len;++j) if (x[i].middle.s[j] == ' ') x[i].middle.s[j] = '-'; } int main(int argc,char **argv) { struct taia stamp; struct taia deadline; int opt; unsigned long u; int i; int j; int r; while ((opt = getopt(argc,argv,"c:l:")) != opteof) switch(opt) { case 'c': scan_ulong(optarg,&u); if (u < 1) u = 1; if (u > 1000) u = 1000; maxactive = u; break; case 'l': scan_ulong(optarg,&u); if (u < 1) u = 1; if (u > 1000000) u = 1000000; xmax = u; break; default: strerr_die1x(111,"dnsfilter: usage: dnsfilter [ -c concurrency ] [ -l lines ]"); } x = (struct line *) alloc(xmax * sizeof(struct line)); if (!x) nomem(); byte_zero(x,xmax * sizeof(struct line)); io = (iopause_fd *) alloc((xmax + 1) * sizeof(iopause_fd)); if (!io) nomem(); if (!stralloc_copys(&partial,"")) nomem(); while (flag0 || inbuflen || partial.len || xnum) { taia_now(&stamp); taia_uint(&deadline,120); taia_add(&deadline,&deadline,&stamp); iolen = 0; if (flag0) if (inbuflen < sizeof inbuf) { inio = io + iolen++; inio->fd = 0; inio->events = IOPAUSE_READ; } for (i = 0;i < xnum;++i) if (x[i].flagactive) { x[i].io = io + iolen++; dns_transmit_io(&x[i].dt,x[i].io,&deadline); } iopause(io,iolen,&deadline,&stamp); if (flag0) if (inbuflen < sizeof inbuf) if (inio->revents) { r = read(0,inbuf + inbuflen,(sizeof inbuf) - inbuflen); if (r <= 0) flag0 = 0; else inbuflen += r; } for (i = 0;i < xnum;++i) if (x[i].flagactive) { r = dns_transmit_get(&x[i].dt,x[i].io,&stamp); if (r == -1) { errout(i); x[i].flagactive = 0; --numactive; } else if (r == 1) { if (dns_name_packet(&x[i].middle,x[i].dt.packet,x[i].dt.packetlen) == -1) errout(i); if (x[i].middle.len) if (!stralloc_cats(&x[i].left,"=")) nomem(); x[i].flagactive = 0; --numactive; } } for (;;) { if (xnum && !x[0].flagactive) { buffer_put(buffer_1,x[0].left.s,x[0].left.len); buffer_put(buffer_1,x[0].middle.s,x[0].middle.len); buffer_put(buffer_1,x[0].right.s,x[0].right.len); buffer_flush(buffer_1); --xnum; tmp = x[0]; for (i = 0;i < xnum;++i) x[i] = x[i + 1]; x[xnum] = tmp; continue; } if ((xnum < xmax) && (numactive < maxactive)) { i = byte_chr(inbuf,inbuflen,'\n'); if (inbuflen && (i == inbuflen)) { if (!stralloc_catb(&partial,inbuf,inbuflen)) nomem(); inbuflen = 0; continue; } if ((i < inbuflen) || (!flag0 && partial.len)) { if (i < inbuflen) ++i; if (!stralloc_catb(&partial,inbuf,i)) nomem(); inbuflen -= i; for (j = 0;j < inbuflen;++j) inbuf[j] = inbuf[j + i]; if (partial.len) { i = byte_chr(partial.s,partial.len,'\n'); i = byte_chr(partial.s,i,'\t'); i = byte_chr(partial.s,i,' '); if (!stralloc_copyb(&x[xnum].left,partial.s,i)) nomem(); if (!stralloc_copys(&x[xnum].middle,"")) nomem(); if (!stralloc_copyb(&x[xnum].right,partial.s + i,partial.len - i)) nomem(); x[xnum].flagactive = 0; partial.len = i; if (!stralloc_0(&partial)) nomem(); if (ip4_scan(partial.s,ip)) { dns_name4_domain(name,ip); if (dns_resolvconfip(servers) == -1) strerr_die2sys(111,FATAL,"unable to read /etc/resolv.conf: "); if (dns_transmit_start(&x[xnum].dt,servers,1,name,DNS_T_PTR,"\0\0\0\0") == -1) errout(xnum); else { x[xnum].flagactive = 1; ++numactive; } } ++xnum; } partial.len = 0; continue; } } break; } } _exit(0); } tinydyndns-0.4.2.debian1/dnsip.c000066400000000000000000000013511103424076200165020ustar00rootroot00000000000000#include "buffer.h" #include "exit.h" #include "strerr.h" #include "ip4.h" #include "dns.h" #define FATAL "dnsip: fatal: " static char seed[128]; static stralloc fqdn; static stralloc out; char str[IP4_FMT]; int main(int argc,char **argv) { int i; dns_random_init(seed); if (*argv) ++argv; while (*argv) { if (!stralloc_copys(&fqdn,*argv)) strerr_die2x(111,FATAL,"out of memory"); if (dns_ip4(&out,&fqdn) == -1) strerr_die4sys(111,FATAL,"unable to find IP address for ",*argv,": "); for (i = 0;i + 4 <= out.len;i += 4) { buffer_put(buffer_1,str,ip4_fmt(str,out.s + i)); buffer_puts(buffer_1," "); } buffer_puts(buffer_1,"\n"); ++argv; } buffer_flush(buffer_1); _exit(0); } tinydyndns-0.4.2.debian1/dnsipq.c000066400000000000000000000015211103424076200166620ustar00rootroot00000000000000#include "buffer.h" #include "exit.h" #include "strerr.h" #include "ip4.h" #include "dns.h" #define FATAL "dnsipq: fatal: " static char seed[128]; static stralloc in; static stralloc fqdn; static stralloc out; char str[IP4_FMT]; int main(int argc,char **argv) { int i; dns_random_init(seed); if (*argv) ++argv; while (*argv) { if (!stralloc_copys(&in,*argv)) strerr_die2x(111,FATAL,"out of memory"); if (dns_ip4_qualify(&out,&fqdn,&in) == -1) strerr_die4sys(111,FATAL,"unable to find IP address for ",*argv,": "); buffer_put(buffer_1,fqdn.s,fqdn.len); buffer_puts(buffer_1," "); for (i = 0;i + 4 <= out.len;i += 4) { buffer_put(buffer_1,str,ip4_fmt(str,out.s + i)); buffer_puts(buffer_1," "); } buffer_puts(buffer_1,"\n"); ++argv; } buffer_flush(buffer_1); _exit(0); } tinydyndns-0.4.2.debian1/dnsmx.c000066400000000000000000000024201103424076200165140ustar00rootroot00000000000000#include "buffer.h" #include "exit.h" #include "strerr.h" #include "uint16.h" #include "byte.h" #include "str.h" #include "fmt.h" #include "dns.h" #define FATAL "dnsmx: fatal: " void nomem(void) { strerr_die2x(111,FATAL,"out of memory"); } static char seed[128]; static stralloc fqdn; static char *q; static stralloc out; char strnum[FMT_ULONG]; int main(int argc,char **argv) { int i; int j; uint16 pref; dns_random_init(seed); if (*argv) ++argv; while (*argv) { if (!stralloc_copys(&fqdn,*argv)) nomem(); if (dns_mx(&out,&fqdn) == -1) strerr_die4sys(111,FATAL,"unable to find MX records for ",*argv,": "); if (!out.len) { if (!dns_domain_fromdot(&q,*argv,str_len(*argv))) nomem(); if (!stralloc_copys(&out,"0 ")) nomem(); if (!dns_domain_todot_cat(&out,q)) nomem(); if (!stralloc_cats(&out,"\n")) nomem(); buffer_put(buffer_1,out.s,out.len); } else { i = 0; while (i + 2 < out.len) { j = byte_chr(out.s + i + 2,out.len - i - 2,0); uint16_unpack_big(out.s + i,&pref); buffer_put(buffer_1,strnum,fmt_ulong(strnum,pref)); buffer_puts(buffer_1," "); buffer_put(buffer_1,out.s + i + 2,j); buffer_puts(buffer_1,"\n"); i += j + 3; } } ++argv; } buffer_flush(buffer_1); _exit(0); } tinydyndns-0.4.2.debian1/dnsname.c000066400000000000000000000011551103424076200170140ustar00rootroot00000000000000#include "buffer.h" #include "exit.h" #include "strerr.h" #include "ip4.h" #include "dns.h" #define FATAL "dnsname: fatal: " static char seed[128]; char ip[4]; static stralloc out; int main(int argc,char **argv) { dns_random_init(seed); if (*argv) ++argv; while (*argv) { if (!ip4_scan(*argv,ip)) strerr_die3x(111,FATAL,"unable to parse IP address ",*argv); if (dns_name4(&out,ip) == -1) strerr_die4sys(111,FATAL,"unable to find host name for ",*argv,": "); buffer_put(buffer_1,out.s,out.len); buffer_puts(buffer_1,"\n"); ++argv; } buffer_flush(buffer_1); _exit(0); } tinydyndns-0.4.2.debian1/dnsq.c000066400000000000000000000040231103424076200163310ustar00rootroot00000000000000#include "uint16.h" #include "strerr.h" #include "buffer.h" #include "scan.h" #include "str.h" #include "byte.h" #include "error.h" #include "ip4.h" #include "iopause.h" #include "printpacket.h" #include "parsetype.h" #include "dns.h" #define FATAL "dnsq: fatal: " void usage(void) { strerr_die1x(100,"dnsq: usage: dnsq type name server"); } void oops(void) { strerr_die2sys(111,FATAL,"unable to parse: "); } static struct dns_transmit tx; int resolve(char *q,char qtype[2],char servers[64]) { struct taia stamp; struct taia deadline; iopause_fd x[1]; int r; if (dns_transmit_start(&tx,servers,0,q,qtype,"\0\0\0\0") == -1) return -1; for (;;) { taia_now(&stamp); taia_uint(&deadline,120); taia_add(&deadline,&deadline,&stamp); dns_transmit_io(&tx,x,&deadline); iopause(x,1,&deadline,&stamp); r = dns_transmit_get(&tx,x,&stamp); if (r == -1) return -1; if (r == 1) break; } return 0; } char servers[64]; static stralloc ip; static stralloc fqdn; char type[2]; static char *q; static stralloc out; static char seed[128]; int main(int argc,char **argv) { uint16 u16; dns_random_init(seed); if (!*argv) usage(); if (!*++argv) usage(); if (!parsetype(*argv,type)) usage(); if (!*++argv) usage(); if (!dns_domain_fromdot(&q,*argv,str_len(*argv))) oops(); if (!*++argv) usage(); if (!stralloc_copys(&out,*argv)) oops(); if (dns_ip4_qualify(&ip,&fqdn,&out) == -1) oops(); if (ip.len >= 64) ip.len = 64; byte_zero(servers,64); byte_copy(servers,ip.len,ip.s); if (!stralloc_copys(&out,"")) oops(); uint16_unpack_big(type,&u16); if (!stralloc_catulong0(&out,u16,0)) oops(); if (!stralloc_cats(&out," ")) oops(); if (!dns_domain_todot_cat(&out,q)) oops(); if (!stralloc_cats(&out,":\n")) oops(); if (resolve(q,type,servers) == -1) { if (!stralloc_cats(&out,error_str(errno))) oops(); if (!stralloc_cats(&out,"\n")) oops(); } else { if (!printpacket_cat(&out,tx.packet,tx.packetlen)) oops(); } buffer_putflush(buffer_1,out.s,out.len); _exit(0); } tinydyndns-0.4.2.debian1/dnsqr.c000066400000000000000000000025771103424076200165270ustar00rootroot00000000000000#include "uint16.h" #include "strerr.h" #include "buffer.h" #include "scan.h" #include "str.h" #include "byte.h" #include "error.h" #include "iopause.h" #include "printpacket.h" #include "parsetype.h" #include "dns.h" #define FATAL "dnsqr: fatal: " void usage(void) { strerr_die1x(100,"dnsqr: usage: dnsqr type name"); } void oops(void) { strerr_die2sys(111,FATAL,"unable to parse: "); } char type[2]; static char *q; static stralloc out; static char seed[128]; int main(int argc,char **argv) { uint16 u16; dns_random_init(seed); if (!*argv) usage(); if (!*++argv) usage(); if (!parsetype(*argv,type)) usage(); if (!*++argv) usage(); if (!dns_domain_fromdot(&q,*argv,str_len(*argv))) oops(); if (*++argv) usage(); if (!stralloc_copys(&out,"")) oops(); uint16_unpack_big(type,&u16); if (!stralloc_catulong0(&out,u16,0)) oops(); if (!stralloc_cats(&out," ")) oops(); if (!dns_domain_todot_cat(&out,q)) oops(); if (!stralloc_cats(&out,":\n")) oops(); if (dns_resolve(q,type) == -1) { if (!stralloc_cats(&out,error_str(errno))) oops(); if (!stralloc_cats(&out,"\n")) oops(); } else { if (dns_resolve_tx.packetlen < 4) oops(); dns_resolve_tx.packet[2] &= ~1; dns_resolve_tx.packet[3] &= ~128; if (!printpacket_cat(&out,dns_resolve_tx.packet,dns_resolve_tx.packetlen)) oops(); } buffer_putflush(buffer_1,out.s,out.len); _exit(0); } tinydyndns-0.4.2.debian1/dnsroots.global000066400000000000000000000002441103424076200202560ustar00rootroot00000000000000198.41.0.4 128.9.0.107 192.33.4.12 128.8.10.90 192.203.230.10 192.5.5.241 192.112.36.4 128.63.2.53 192.36.148.17 198.41.0.10 193.0.14.129 198.32.64.12 202.12.27.33 tinydyndns-0.4.2.debian1/dnstrace.c000066400000000000000000000307111103424076200171720ustar00rootroot00000000000000#include "uint16.h" #include "uint32.h" #include "fmt.h" #include "str.h" #include "byte.h" #include "ip4.h" #include "gen_alloc.h" #include "gen_allocdefs.h" #include "exit.h" #include "buffer.h" #include "stralloc.h" #include "error.h" #include "strerr.h" #include "iopause.h" #include "printrecord.h" #include "alloc.h" #include "parsetype.h" #include "dd.h" #include "dns.h" #define FATAL "dnstrace: fatal: " void nomem(void) { strerr_die2x(111,FATAL,"out of memory"); } void usage(void) { strerr_die1x(100,"dnstrace: usage: dnstrace type name rootip ..."); } static stralloc querystr; char ipstr[IP4_FMT]; static stralloc tmp; void printdomain(const char *d) { if (!stralloc_copys(&tmp,"")) nomem(); if (!dns_domain_todot_cat(&tmp,d)) nomem(); buffer_put(buffer_1,tmp.s,tmp.len); } static struct dns_transmit tx; int resolve(char *q,char qtype[2],char ip[4]) { struct taia start; struct taia stamp; struct taia deadline; char servers[64]; iopause_fd x[1]; int r; taia_now(&start); byte_zero(servers,64); byte_copy(servers,4,ip); if (dns_transmit_start(&tx,servers,0,q,qtype,"\0\0\0\0") == -1) return -1; for (;;) { taia_now(&stamp); taia_uint(&deadline,120); taia_add(&deadline,&deadline,&stamp); dns_transmit_io(&tx,x,&deadline); iopause(x,1,&deadline,&stamp); r = dns_transmit_get(&tx,x,&stamp); if (r == -1) return -1; if (r == 1) break; } taia_now(&stamp); taia_sub(&stamp,&stamp,&start); taia_uint(&deadline,1); if (taia_less(&deadline,&stamp)) { buffer_put(buffer_1,querystr.s,querystr.len); buffer_puts(buffer_1,"ALERT:took more than 1 second\n"); } return 0; } struct address { char *owner; char ip[4]; } ; GEN_ALLOC_typedef(address_alloc,struct address,s,len,a) GEN_ALLOC_readyplus(address_alloc,struct address,s,len,a,i,n,x,30,address_alloc_readyplus) GEN_ALLOC_append(address_alloc,struct address,s,len,a,i,n,x,30,address_alloc_readyplus,address_alloc_append) static address_alloc address; struct ns { char *owner; char *ns; } ; GEN_ALLOC_typedef(ns_alloc,struct ns,s,len,a) GEN_ALLOC_readyplus(ns_alloc,struct ns,s,len,a,i,n,x,30,ns_alloc_readyplus) GEN_ALLOC_append(ns_alloc,struct ns,s,len,a,i,n,x,30,ns_alloc_readyplus,ns_alloc_append) static ns_alloc ns; struct query { char *owner; char type[2]; } ; GEN_ALLOC_typedef(query_alloc,struct query,s,len,a) GEN_ALLOC_readyplus(query_alloc,struct query,s,len,a,i,n,x,30,query_alloc_readyplus) GEN_ALLOC_append(query_alloc,struct query,s,len,a,i,n,x,30,query_alloc_readyplus,query_alloc_append) static query_alloc query; struct qt { char *owner; char type[2]; char *control; char ip[4]; } ; GEN_ALLOC_typedef(qt_alloc,struct qt,s,len,a) GEN_ALLOC_readyplus(qt_alloc,struct qt,s,len,a,i,n,x,30,qt_alloc_readyplus) GEN_ALLOC_append(qt_alloc,struct qt,s,len,a,i,n,x,30,qt_alloc_readyplus,qt_alloc_append) static qt_alloc qt; void qt_add(const char *q,const char type[2],const char *control,const char ip[4]) { struct qt x; int i; if (!*q) return; /* don't ask the roots about our artificial . host */ for (i = 0;i < qt.len;++i) if (dns_domain_equal(qt.s[i].owner,q)) if (dns_domain_equal(qt.s[i].control,control)) if (byte_equal(qt.s[i].type,2,type)) if (byte_equal(qt.s[i].ip,4,ip)) return; byte_zero(&x,sizeof x); if (!dns_domain_copy(&x.owner,q)) nomem(); if (!dns_domain_copy(&x.control,control)) nomem(); byte_copy(x.type,2,type); byte_copy(x.ip,4,ip); if (!qt_alloc_append(&qt,&x)) nomem(); } void query_add(const char *owner,const char type[2]) { struct query x; int i; int j; for (i = 0;i < query.len;++i) if (dns_domain_equal(query.s[i].owner,owner)) if (byte_equal(query.s[i].type,2,type)) return; byte_zero(&x,sizeof x); if (!dns_domain_copy(&x.owner,owner)) nomem(); byte_copy(x.type,2,type); if (!query_alloc_append(&query,&x)) nomem(); for (i = 0;i < ns.len;++i) if (dns_domain_suffix(owner,ns.s[i].owner)) for (j = 0;j < address.len;++j) if (dns_domain_equal(ns.s[i].ns,address.s[j].owner)) qt_add(owner,type,ns.s[i].owner,address.s[j].ip); } void ns_add(const char *owner,const char *server) { struct ns x; int i; int j; buffer_put(buffer_1,querystr.s,querystr.len); buffer_puts(buffer_1,"NS:"); printdomain(owner); buffer_puts(buffer_1,":"); printdomain(server); buffer_puts(buffer_1,"\n"); for (i = 0;i < ns.len;++i) if (dns_domain_equal(ns.s[i].owner,owner)) if (dns_domain_equal(ns.s[i].ns,server)) return; query_add(server,DNS_T_A); byte_zero(&x,sizeof x); if (!dns_domain_copy(&x.owner,owner)) nomem(); if (!dns_domain_copy(&x.ns,server)) nomem(); if (!ns_alloc_append(&ns,&x)) nomem(); for (i = 0;i < query.len;++i) if (dns_domain_suffix(query.s[i].owner,owner)) for (j = 0;j < address.len;++j) if (dns_domain_equal(server,address.s[j].owner)) qt_add(query.s[i].owner,query.s[i].type,owner,address.s[j].ip); } void address_add(const char *owner,const char ip[4]) { struct address x; int i; int j; buffer_put(buffer_1,querystr.s,querystr.len); buffer_puts(buffer_1,"A:"); printdomain(owner); buffer_puts(buffer_1,":"); buffer_put(buffer_1,ipstr,ip4_fmt(ipstr,ip)); buffer_puts(buffer_1,"\n"); for (i = 0;i < address.len;++i) if (dns_domain_equal(address.s[i].owner,owner)) if (byte_equal(address.s[i].ip,4,ip)) return; byte_zero(&x,sizeof x); if (!dns_domain_copy(&x.owner,owner)) nomem(); byte_copy(x.ip,4,ip); if (!address_alloc_append(&address,&x)) nomem(); for (i = 0;i < ns.len;++i) if (dns_domain_equal(ns.s[i].ns,owner)) for (j = 0;j < query.len;++j) if (dns_domain_suffix(query.s[j].owner,ns.s[i].owner)) qt_add(query.s[j].owner,query.s[j].type,ns.s[i].owner,ip); } char seed[128]; static char *t1; static char *t2; static char *referral; static char *cname; static int typematch(const char rtype[2],const char qtype[2]) { return byte_equal(qtype,2,rtype) || byte_equal(qtype,2,DNS_T_ANY); } void parsepacket(const char *buf,unsigned int len,const char *d,const char dtype[2],const char *control) { char misc[20]; char header[12]; unsigned int pos; uint16 numanswers; unsigned int posanswers; uint16 numauthority; unsigned int posauthority; uint16 numglue; unsigned int posglue; uint16 datalen; unsigned int rcode; int flagout; int flagcname; int flagreferral; int flagsoa; int j; const char *x; pos = dns_packet_copy(buf,len,0,header,12); if (!pos) goto DIE; pos = dns_packet_skipname(buf,len,pos); if (!pos) goto DIE; pos += 4; uint16_unpack_big(header + 6,&numanswers); uint16_unpack_big(header + 8,&numauthority); uint16_unpack_big(header + 10,&numglue); rcode = header[3] & 15; if (rcode && (rcode != 3)) { errno = error_proto; goto DIE; } /* impossible */ flagout = 0; flagcname = 0; flagreferral = 0; flagsoa = 0; posanswers = pos; for (j = 0;j < numanswers;++j) { pos = dns_packet_getname(buf,len,pos,&t1); if (!pos) goto DIE; pos = dns_packet_copy(buf,len,pos,header,10); if (!pos) goto DIE; if (dns_domain_equal(t1,d)) if (byte_equal(header + 2,2,DNS_C_IN)) if (typematch(header,dtype)) flagout = 1; else if (typematch(header,DNS_T_CNAME)) { if (!dns_packet_getname(buf,len,pos,&cname)) goto DIE; flagcname = 1; } uint16_unpack_big(header + 8,&datalen); pos += datalen; } posauthority = pos; for (j = 0;j < numauthority;++j) { pos = dns_packet_getname(buf,len,pos,&t1); if (!pos) goto DIE; pos = dns_packet_copy(buf,len,pos,header,10); if (!pos) goto DIE; if (typematch(header,DNS_T_SOA)) flagsoa = 1; else if (typematch(header,DNS_T_NS)) { flagreferral = 1; if (!dns_domain_copy(&referral,t1)) goto DIE; } uint16_unpack_big(header + 8,&datalen); pos += datalen; } posglue = pos; if (!flagcname && !rcode && !flagout && flagreferral && !flagsoa) if (dns_domain_equal(referral,control) || !dns_domain_suffix(referral,control)) { buffer_put(buffer_1,querystr.s,querystr.len); buffer_puts(buffer_1,"ALERT:lame server; refers to "); printdomain(referral); buffer_puts(buffer_1,"\n"); return; } pos = posanswers; for (j = 0;j < numanswers + numauthority + numglue;++j) { pos = dns_packet_getname(buf,len,pos,&t1); if (!pos) goto DIE; pos = dns_packet_copy(buf,len,pos,header,10); if (!pos) goto DIE; uint16_unpack_big(header + 8,&datalen); if (dns_domain_suffix(t1,control)) if (byte_equal(header + 2,2,DNS_C_IN)) { if (typematch(header,DNS_T_NS)) { if (!dns_packet_getname(buf,len,pos,&t2)) goto DIE; ns_add(t1,t2); } else if (typematch(header,DNS_T_A) && datalen == 4) { if (!dns_packet_copy(buf,len,pos,misc,4)) goto DIE; address_add(t1,misc); } } pos += datalen; } if (flagcname) { query_add(cname,dtype); buffer_put(buffer_1,querystr.s,querystr.len); buffer_puts(buffer_1,"CNAME:"); printdomain(cname); buffer_puts(buffer_1,"\n"); return; } if (rcode == 3) { buffer_put(buffer_1,querystr.s,querystr.len); buffer_puts(buffer_1,"NXDOMAIN\n"); return; } if (flagout || flagsoa || !flagreferral) { if (!flagout) { buffer_put(buffer_1,querystr.s,querystr.len); buffer_puts(buffer_1,"NODATA\n"); return; } pos = posanswers; for (j = 0;j < numanswers + numauthority + numglue;++j) { pos = printrecord(&tmp,buf,len,pos,d,dtype); if (!pos) goto DIE; if (tmp.len) { buffer_put(buffer_1,querystr.s,querystr.len); buffer_puts(buffer_1,"answer:"); buffer_put(buffer_1,tmp.s,tmp.len); /* includes \n */ } } return; } if (!dns_domain_suffix(d,referral)) goto DIE; buffer_put(buffer_1,querystr.s,querystr.len); buffer_puts(buffer_1,"see:"); printdomain(referral); buffer_puts(buffer_1,"\n"); return; DIE: x = error_str(errno); buffer_put(buffer_1,querystr.s,querystr.len); buffer_puts(buffer_1,"ALERT:unable to parse response packet; "); buffer_puts(buffer_1,x); buffer_puts(buffer_1,"\n"); } int main(int argc,char **argv) { static stralloc out; static stralloc fqdn; static stralloc udn; static char *q; char *control; char type[2]; char ip[64]; int i; uint16 u16; dns_random_init(seed); if (!stralloc_copys(&querystr,"0:.:.:start:")) nomem(); if (!address_alloc_readyplus(&address,1)) nomem(); if (!query_alloc_readyplus(&query,1)) nomem(); if (!ns_alloc_readyplus(&ns,1)) nomem(); if (!qt_alloc_readyplus(&qt,1)) nomem(); if (!*argv) usage(); if (!*++argv) usage(); if (!parsetype(*argv,type)) usage(); if (!*++argv) usage(); if (!dns_domain_fromdot(&q,*argv,str_len(*argv))) nomem(); query_add(q,type); ns_add("",""); while (*++argv) { if (!stralloc_copys(&udn,*argv)) nomem(); if (dns_ip4_qualify(&out,&fqdn,&udn) == -1) nomem(); /* XXX */ for (i = 0;i + 4 <= out.len;i += 4) address_add("",out.s + i); } for (i = 0;i < qt.len;++i) { if (!dns_domain_copy(&q,qt.s[i].owner)) nomem(); control = qt.s[i].control; if (!dns_domain_suffix(q,control)) continue; byte_copy(type,2,qt.s[i].type); byte_copy(ip,4,qt.s[i].ip); if (!stralloc_copys(&querystr,"")) nomem(); uint16_unpack_big(type,&u16); if (!stralloc_catulong0(&querystr,u16,0)) nomem(); if (!stralloc_cats(&querystr,":")) nomem(); if (!dns_domain_todot_cat(&querystr,q)) nomem(); if (!stralloc_cats(&querystr,":")) nomem(); if (!dns_domain_todot_cat(&querystr,control)) nomem(); if (!stralloc_cats(&querystr,":")) nomem(); if (!stralloc_catb(&querystr,ipstr,ip4_fmt(ipstr,ip))) nomem(); if (!stralloc_cats(&querystr,":")) nomem(); buffer_put(buffer_1,querystr.s,querystr.len); buffer_puts(buffer_1,"tx\n"); buffer_flush(buffer_1); if (resolve(q,type,ip) == -1) { const char *x = error_str(errno); buffer_put(buffer_1,querystr.s,querystr.len); buffer_puts(buffer_1,"ALERT:query failed; "); buffer_puts(buffer_1,x); buffer_puts(buffer_1,"\n"); } else parsepacket(tx.packet,tx.packetlen,q,type,control); if (dns_domain_equal(q,"\011localhost\0")) { buffer_put(buffer_1,querystr.s,querystr.len); buffer_puts(buffer_1,"ALERT:some caches do not handle localhost internally\n"); address_add(q,"\177\0\0\1"); } if (dd(q,"",ip) == 4) { buffer_put(buffer_1,querystr.s,querystr.len); buffer_puts(buffer_1,"ALERT:some caches do not handle IP addresses internally\n"); address_add(q,ip); } buffer_flush(buffer_1); } _exit(0); } tinydyndns-0.4.2.debian1/dnstracesort.sh000066400000000000000000000016571103424076200203010ustar00rootroot00000000000000awk -F: ' BEGIN { OFS=":" } { if ($5 == "tx") next if ($5 == "A") { print "glue",$6,$3,$4,"answer",$6" A "$7 next } if ($5 == "NS") { print "glue",$6,$3,$4,"answer",$6" NS "$7 next } print } ' | sort -t: +0 -2 +4 +3 -4 +2 -3 | uniq | awk -F: ' { type = $1 q = $2 c = $3 ip = sprintf("%-16s",$4) if (q != lastq) { print ""; lastq = q } if ($5 == "ALERT") { result = "A\bAL\bLE\bER\bRT\bT:\b: " $6 } else if ($5 == "answer") { if (index($6,q" ") == 1) $6 = substr($6,length(q) + 2) result = $6 } else if ($5 == "see") { result = "see " $6 } else if ($5 == "CNAME") { result = "CNAME "$6 } else result = $5 if (c != ".") { q = substr(q,1,length(q) - length(c)) for (i = 1;i <= length(c);++i) { ci = substr(c,i,1) q = q "_\b" ci } } print type,q,ip,result } ' tinydyndns-0.4.2.debian1/dnstxt.c000066400000000000000000000011351103424076200167110ustar00rootroot00000000000000#include "buffer.h" #include "exit.h" #include "strerr.h" #include "dns.h" #define FATAL "dnstxt: fatal: " static char seed[128]; static stralloc fqdn; static stralloc out; int main(int argc,char **argv) { dns_random_init(seed); if (*argv) ++argv; while (*argv) { if (!stralloc_copys(&fqdn,*argv)) strerr_die2x(111,FATAL,"out of memory"); if (dns_txt(&out,&fqdn) == -1) strerr_die4sys(111,FATAL,"unable to find TXT records for ",*argv,": "); buffer_put(buffer_1,out.s,out.len); buffer_puts(buffer_1,"\n"); ++argv; } buffer_flush(buffer_1); _exit(0); } tinydyndns-0.4.2.debian1/doc/000077500000000000000000000000001103424076200157665ustar00rootroot00000000000000tinydyndns-0.4.2.debian1/doc/configuration.html000066400000000000000000000047371103424076200215360ustar00rootroot00000000000000 tinydyndns - configuration G. Pape
tinydyndns

tinydyndns - configuration


Before starting the pop-before-dyndns service, you will make to have four decisions:
  • The pop-before-dyndns account name, normally tinydyn. The tinydns program runs under this account. If this account does not exist, create it now.
  • The DNS log account name, normally dnslog. Logging programs run under this account. If this account does not exist, create it now.
  • The domain name for the pop-before-dyndns service, say dyn.smarden.org.
  • The IP address the pop-before-dyndns service will use, say 5.6.7.8.
Create the tinydyndns service directories by running the tinydyndns-conf program.
 # tinydyndns-conf tinydyn dnslog /etc/tinydyn 5.6.7.8 dyn.smarden.org
Tell svscan about the new services:
 # ln -s /etc/tinydyn /service/
 # ln -s /etc/tinydyn/pop /service/tinydyn-pop
Wait five seconds for the services to start and check the logs:
 # less /service/tinydyn/log/main/current
 # less /service/tinydyn-pop/log/main/current
Now tell the pop-before-dyndns service about a dynamic hostname it should handle, say floyd:
 # su - tinydyn
 $ cd /etc/tinydyn/pop
 $ ./setpasswd floyd guest
Activate this hostname by connecting to the tinydyn-pop service as user floyd:
 $ telnet 5.6.7.8 110
 Trying 5.6.7.8...
 Connected to 5.6.7.8.
 Escape character is '^]'.
 +OK <8746.1015174596@dyn.smarden.org>
 USER floyd
 +OK
 PASS guest
 +OK
 QUIT
 Connection closed by foreign host.
 $
Check the tinydyn service for this dynamic hostname:
 $ dnsq a floyd.dyn.smarden.org 5.6.7.8
The output should show your system's IP address in the answer section.

To tell the tinydyn service about more dynamic hostnames, just run the setpasswd script as user tinydyn as shown above.

Finally, tell the administrator of smarden.org to delegate the domain dyn.smarden.org to the server a.ns.dyn.smarden.org running on IP address 5.6.7.8.


Gerrit Pape <pape@smarden.org>
tinydyndns-0.4.2.debian1/doc/failover.html000066400000000000000000000105671103424076200204740ustar00rootroot00000000000000 tinydyndns - failover G. Pape
tinydyndns

tinydyndns - failover


Overview
Prepare failover for tinydyndns DNS service
Prepare failover for tinydyndns POP service

How to switch services to the failover machine


What can make the tinydyndns service fail?

  1. The nameserver handling the delegation to the tinydyndns domain is unavailable
  2. The nameserver running the tinydyndns service is unavailable
  3. The POP server handling the POP service for tinydyndns is unavailable (normally the same server as in 2.)

How can I provide failover services in these cases?

  1. Make sure you have multiple nameservers providing the delegation to the tinydyndns domain. Refer to the djbdns documentation on how to replicate your DNS service. To provide failover for your tinydyndns services, you need to have control over the servers handling the delegation.
  2. tinydyndns doesn't support automatic replication of its dynamic DNS data, so the tinydyndns domain cannot be handled by multiple servers simultaneously. But you can prepare one or more additional machines to handle the tinydyndns services in case the primary machine is unavailable, see below.
  3. To be able to switch over the POP service to another machine in case the primary machine is unavailable, you need to replicate the POP password database for the dynamic hosts whenever it changes, so that the failover machine knows about all dynamic host names that are handled by this tinydyndns service. See below on how to do this.

How to prepare a failover service for dynamic DNS data

Simply configure tinydyndns on the machine that should take over the tinydyndns and POP service in case the primary server is unavailable. Of course configure tinydyndns to handle the same domain name as the primary tinydyndns server, on an IP address of this failover server.

Adjust the TTL (time to live) of the delegation to the tinydyndns domain to your need (say four hours). This is the worst case downtime of the tinydyndns service in case the primary tinydyndns server gets unavailable, and after the administrator takes action. Switching over the services currently needs manual intervention.

How to automatically replicate the POP password database

The tinydyndns password database is changed by the ./setpasswd script only. To have the database replicated automatically when setpasswd is run, add a line that copies or syncs the passwd file to the failover machine to the end of the setpasswd script (remove the last line ``exit 0'' first).

E.g.: A primary tinydyndns service runs on a.ns.dyn.smarden.org. The failover service is prepared on a server with the IP address a.b.c.d. Add this line to /service/tinydyndns-pop/setpasswd on a.ns.dyn.smarden.org:

 # cd /service/tinydyn-pop/
 # cat >>setpasswd <<EOT
 rsync -e ssh passwd a.b.c.d:/service/tinydyn-pop/passwd
 EOT
 #

How do I switch services to the failover machine

First rebuild the data.cdb from the current passwd database on the failover machine:
 # cd /service/tinydyn/root
 # make rebuild
 ...
 #
Now change the delegation on all available DNS servers that handle the delegation to your tinydyndns domain to delegate the domain to the IP address of the failover machine is running tinydyndns on.

That's it. Within the next four hours (or whatever you've set as TTL), clients that try to update there dynamic DNS entry, and clients that ask for dynamic IP addresses of hosts in your tinydyndns domain, will switch to contact your failover machine.


Gerrit Pape <pape@smarden.org>
tinydyndns-0.4.2.debian1/doc/fake-pop3.html000066400000000000000000000014451103424076200204450ustar00rootroot00000000000000 tinydyndns - fake-pop3 client G. Pape
tinydyndns

tinydyndns - fake-pop3 client


Since the POP mailbox used by the pop-before-dyndns service never contains mail, there is no need to run a real pop3 client. On Unix you can use this fake-pop3 script as tinydyndns client:
 #!/bin/sh
 USER=floyd
 PASS=guest
 tcpclient dyn.smarden.org 110 sh -c "exec 0<&6; exec 1>&7
   echo USER $USER
   read input
   echo PASS $PASS
   read input
   echo QUIT
   read input"

Gerrit Pape <pape@smarden.org>
tinydyndns-0.4.2.debian1/doc/fake-pop3.sh000066400000000000000000000002621103424076200201070ustar00rootroot00000000000000#!/bin/sh USER=floyd PASS=guest tcpclient dyn.smarden.org 110 sh -c "exec 0<&6; exec 1>&7 echo USER $USER read input echo PASS $PASS read input echo QUIT read input" tinydyndns-0.4.2.debian1/doc/fake-pop3d.html000066400000000000000000000024631103424076200206120ustar00rootroot00000000000000 tinydyndns - fake-pop3d G. Pape
tinydyndns

tinydyndns - fake-pop3d


Since the POP mailbox used by the pop-before-dyndns service never contains mail, there is no need to run a real pop3 server, and for having a Maildir/ at all. You can test to replace the pop3front-maildir in /etc/tinydyn/pop/run with this fake-pop3d script:
 #!/bin/sh
 echo '+OK '
 read input
 if [ "$input" = 'LIST' ]; then
   echo '+OK'
   echo '.'
 elif [ "$input" = 'STAT' ]; then
   echo '+OK 0 0'
 fi
 read input
 echo '+OK'
 exit 0
An example /etc/tinydyn/pop/run script:
 #!/bin/sh
 exec softlimit -m 4000000 envdir ./env tcpserver -vRH a.b.c.d 110 \
   pop3front-auth dyn.smarden.org \
     cvm-pwfile sh -c '
       echo "login: $USER: $TCPREMOTEIP" >&7
       cd /etc/tinydyn/root
       setlock data.cdb \
       tinydyndns-update $USER.dyn.smarden.org $TCPREMOTEIP >&7 2>&1
       cd /etc/tinydyn/pop
       exec /etc/tinydyn/pop/fake-pop3d
     ' 2>&1 7>&1

Gerrit Pape <pape@smarden.org>
tinydyndns-0.4.2.debian1/doc/fake-pop3d.sh000066400000000000000000000002521103424076200202520ustar00rootroot00000000000000#!/bin/sh echo '+OK ' read input if [ "$input" = 'LIST' ]; then echo '+OK' echo '.' elif [ "$input" = 'STAT' ]; then echo '+OK 0 0' fi read input echo '+OK' exit 0 tinydyndns-0.4.2.debian1/doc/index.html000066400000000000000000000055661103424076200177770ustar00rootroot00000000000000 tinydyndns - pop-before-dyndns service using djbdns G. Pape

tinydyndns - pop-before-dyndns service using djbdns


How to install tinydyndns
Upgrading from previous versions of tinydyndns

How to configure tinydyndns
How to provide a failover solution

The tinydyndns-conf program
The tinydyndns-update program
The tinydyndns-data program

A fake-pop3d script
A fake-pop3 script


tinydyndns provides a simple and powerful dynamic DNS solution. The usage is nearly fool proof, feel free to test it:

There is a pop-before-dyndns service running on dyn.smarden.org. This service knows about the dynamic hostname floyd.dyn.smarden.org and handles it respectively. Simply connect to the POP mailbox floyd@dyn.smarden.org with your favorite POP3 client to update the DNS record floyd.dyn.smarden.org. Don't worry, the POP mailbox always is empty, you never get mail from it.

Easy to remember:

  • Check the POP mailbox floyd@dyn.smarden.org for
  • Updating the DNS record floyd.dyn.smarden.org

Test it:
 $ telnet dyn.smarden.org 110
 Trying a.b.c.d...
 Connected to dyn.smarden.org.
 Escape character is '^]'.
 +OK <8746.1015174596@dyn.smarden.org>
 USER floyd
 +OK
 PASS guest
 +OK
 QUIT
 Connection closed by foreign host.
 $
Check the dynamic hostname:
  $ dnsipq floyd.dyn.smarden.org
The output should contain your system's IP address.
See Installation for installing tinydyndns, and Configuration for setting up your own pop-before-dyndns service or something similar.
tinydyndns is discussed on the <misc@list.smarden.org> mailing list. To subscribe send an empty email to <misc-subscribe@list.smarden.org>. Send an empty email to <misc-help@list.smarden.org> for more information about this list.

A mailing list archive is available at gmane.org.


Thanks go to the Innominate Security Technologies AG for sponsoring this project.
Gerrit Pape <pape@smarden.org>
tinydyndns-0.4.2.debian1/doc/install.html000066400000000000000000000042131103424076200203220ustar00rootroot00000000000000 tinydyndns - installation G. Pape
tinydyndns

tinydyndns - installation


Check that you have the recent version of daemontools, djbdns, mailfront and cvm installed.

If you run Debian GNU/Linux (woody, sarge, or sid), just add the location of the smarden debian packages to the apt sources.list and do:

 # apt-get update
 # apt-get install daemontools djbdns mailfront cvm

tinydyndns uses the djbdns sources to build. Download djbdns-1.05.tar.gz and tinydyndns-0.4.2.tar.gz and unpack the archives:

 # gunzip djbdns-1.05.tar
 # tar -xpf djbdns-1.05.tar
 # rm djbdns-1.05.tar
 # gunzip tinydyndns-0.4.2.tar
 # tar -xpf tinydyndns-0.4.2.tar
 # rm tinydyndns-0.4.2.tar
Note that you possibly need to apply a patch to djbdns when using newer version of glibc. If so, see djbdns.org.

Copy the source files of tinydyndns into the djbdns source directory and compile the tinydyndns programs:

 # cp tinydyndns-0.4.2/* djbdns-1.05/
 # cd djbdns-1.05
 # make -f Makefile.tinydyndns
Install the tinydyndns programs in /usr/local/bin:
 # make -f Makefile.tinydyndns install-tinydyndns
If you want to make the man pages available, compress them and copy them into a directory man will look in (see $MANPATH):
 # gzip tinydyndns-*.8
 # install -m0644 tinydyndns-*.8.gz /usr/local/man/man8/

See Configuration for setting up your own pop-before-dyndns service or something similar.
Gerrit Pape <pape@smarden.org>
tinydyndns-0.4.2.debian1/doc/tinydyndns-conf.8.html000066400000000000000000000047071103424076200221600ustar00rootroot00000000000000 tinydyndns-conf(8) manual page G. Pape
tinydyndns

Name

tinydyndns-conf - sets up a pop-before-dyndns service

Synopsis

tinydyndns-conf acct logacct dir myip mydomain

Description

tinydyndns-conf creates a service directory dir that runs tinydns(8), and a service directory dir/pop that runs a pop3 service and updates tinydns’ database after a successful login.

You can run the services under svscan(8) or runsvdir(8) by creating symbolic links in the /service directory:

ln -s dir /service/dir
ln -s dir/pop /service/dir-pop

The service will start within five seconds, and will be restarted upon reboot. You can use svc(8) to control the service.

tinydyndns-conf runs

tinydns-conf acct logacct dir myip

to set up a DNS publication service.

tinydyndns-conf modifies dir/root/Makefile to not run tinydns-data(8) upon normal request.

tinydyndns-conf arranges for tcpserver(1) to listen on TCP port 110, and to start pop3front-auth(8), cvm-pwfile(8), and after a successful login tinydyndns-update(8), and pop3front-maildir(8) upon connections.

tinydyndns-conf creates a setpasswd script and a default passwd database in dir/pop for the use with cvm-pwfile(8).

See Also

tinydyndns-update(8), tinydyndns-data(8), tinydns(8), tcpserver(1), pop3front-auth(8), cvm-pwfile(8), pop3front-maildir(8)

http://smarden.org/tinydyndns/

Author

Gerrit Pape <pape@smarden.org>


Table of Contents

tinydyndns-0.4.2.debian1/doc/tinydyndns-data.8.html000066400000000000000000000100041103424076200221270ustar00rootroot00000000000000 tinydyndns-data(8) manual page G. Pape
tinydyndns

Name

tinydyndns-data - add or remove TYPE A record to or from data.cdb

Synopsis

tinydyndns-data add|remove fqdns

Description

fqdns consists of one or more argument, each specifying a fully qualified domain name (fqdn).

tinydyndns-data adds a TYPE A record to or removes it from data.cdb in the current directory. Other than tinydns-data(8), tinydyndns-data does not know about the source file data but changes the binary database data.cdb directly.

tinydyndns-data reads data.cdb and copies its data to data.tmp. While reading the records, tinydyndns-data checks for each fqdn in fqdns if this hostname has a TYPE A record in data.cdb, drops the record when called with the option remove, or refuses to add the record when called with the option add.

When called with the option add, tinydyndns-data then adds all new fqdns to data.tmp. The data of the newly created records can optionally be controlled through the environment, see below. Finally tinydyndns-data renames data.tmp to data.cdb.

Options

add
For each fqdn in fqdns, add a TYPE A record for fqdn to data.cdb with the default IP address (127.14.14.14).
remove
For each fqdn in fqdns, remove all TYPE A records for fqdn from data.cdb.

Environment

IP
The environment variable IP overrides the default IP address (‘‘127.14.14.14’’) for newly created records. $IP must be a valid IP address.
TTL
time-to-live. The environment variable TTL overrides the default time-to-live in seconds (0 if TTD is set, otherwise 5). $TTL must be an integer.
TTD
time-to-die. $TTD must be an integer, specifying a number of seconds. If TTD is set, the timestamp of newly created records is set to the current time plus $TTD seconds, and TTL is set to zero by default, so that tinydns(8) interpretes the timestamp as time-to-die. Note: you probably want to adjust SOA ttl, or create a wildcard record, to prevent DNS caches from caching nxdomain, when using this feature.
LOC
location. $LOC must be two characters long. If LOC is set, it specifies the client location for newly created records.

Exit Codes

tinydyndns-data exits 111 if anything goes wrong and leaves data.cdb unchanged.

tinydyndns-data exits 0 if all fqdns were processed and the new data.cdb was written.

For each fqdn in fqdns that tinydyndns-data was not able to remove or add (e.g., not there, or already there), it increases the exit code by one and exits non-zero (maximum is 100).

Files

./data.cdb
./data.tmp

See Also

tinydyndns-update(8), tinydyndns-conf(8)

http://smarden.org/tinydyndns/

Author

Gerrit Pape <pape@smarden.org>


Table of Contents

tinydyndns-0.4.2.debian1/doc/tinydyndns-update.8.html000066400000000000000000000067641103424076200225220ustar00rootroot00000000000000 tinydyndns-update(8) manual page G. Pape
tinydyndns

Name

tinydyndns-update - update TYPE A record in data.cdb

Synopsis

tinydyndns-update fqdn dynip

Description

tinydyndns-update changes the data of a TYPE A record in data.cdb in the current directory. Other than tinydns-data(8), tinydndns-update does not know about the source file data but changes the binary database data.cdb directly.

First tinydyndns-update checks if the given fqdn has a TYPE A record in data.cdb. Then it checks if the given IP address differs from the one in the TYPE A record in data.cdb, or if the record’s timestamp should be updated. Finally if data.cdb needs to change, tinydyndns-update copies data.cdb to data.tmp, changes the IP address of the TYPE A record of fqdn to dynip in data.tmp, optionally adjusts time-to-live or time-to-die, and renames data.tmp to data.cdb.

Environment

TTL
time-to-live. The environment variable TTL overrides the default time-to-live in seconds (0 if TTD is set, otherwise 5). If TTL is not set or zero, the time-to-live of the record will not change. $TTL must be an integer.
TTD
time-to-die. $TTD must be an integer, specifying a number of seconds. If TTD is set, the timestamp of the record is set to the current time plus $TTD seconds, and TTL is set to zero by default, so that tinydns(8) interpretes the timestamp as time-to-die. Note: you probably want to adjust SOA ttl, or create a wildcard record, to prevent DNS caches from caching nxdomain, when using this feature.
LOC
location. $LOC must be two characters long. If LOC is set, it specifies the client location for records to be updated.

Exit Codes

If tinydyndns-update cannot find a TYPE A record for fqdn in data.cdb, it prints a warning and exits 114.

If dynip does not differ from the IP address of the TYPE A record of fqdn in data.cdb, and the environment variable TTD is not set, tinydyndns-update prints a note and exits 0.

tinydyndns-update exits 100 if it has trouble opening data.cdb, and leaves data.cdb unchanged.

tinydyndns-update exits 111 on temporary error, and leaves data.cdb unchanged.

If data.cdb was changed successfully, tinydyndns-update exits 0.

Files

./data.cdb
./data.tmp

See Also

tinydyndns-data(8), tinydyndns-conf(8)

http://smarden.org/tinydyndns/

Author

Gerrit Pape <pape@smarden.org>


Table of Contents

tinydyndns-0.4.2.debian1/doc/upgrade.html000066400000000000000000000031161103424076200203040ustar00rootroot00000000000000 tinydyndns - upgrading from previous versions G. Pape
tinydyndns

tinydyndns - upgrading from previous versions


0.3.1 to 0.4.x

No further action from you is required.

0.3.0 to 0.3.1

The "rebuild" target in the automatically created /etc/tinydyn/root/Makefile has been fixed, it needs to be
 rebuild: clean data.cdb
	cut -d: -f1 <../pop/passwd |sed -e 's/$$/.dyn.example.com/' \
	  |xargs tinydyndns-data add
where dyn.example.com is your tinydyndns domain. Please adapt the Makefile if you provide a failover service.

0.2.1 to 0.3.0

The automatically created /etc/tinydyn/root/Makefile has changed to support "make rebuild". You should adapt your Makefile by adding the following lines to it (make sure you use TABs for indent, as Makefiles require):
 # cd /etc/tinydyn/root
 # cat >>Makefile <<EOT
 
 rebuild: clean data.cdb
 	cut -d: -f1 <../pop/passwd |xargs tinydyndns-data add
 
 clean:
 	rm -f data.cdb
 EOT
 #
Also please remove the last line "exit 0" from the /etc/tinydyn/pop/setpasswd script.

With this versions, tinydyndns documents how to provide a failover solution for the tinydyndns services, see here for details.


Gerrit Pape <pape@smarden.org>
tinydyndns-0.4.2.debian1/droproot.c000066400000000000000000000014051103424076200172350ustar00rootroot00000000000000#include #include "env.h" #include "scan.h" #include "prot.h" #include "strerr.h" void droproot(const char *fatal) { char *x; unsigned long id; x = env_get("ROOT"); if (!x) strerr_die2x(111,fatal,"$ROOT not set"); if (chdir(x) == -1) strerr_die4sys(111,fatal,"unable to chdir to ",x,": "); if (chroot(".") == -1) strerr_die4sys(111,fatal,"unable to chroot to ",x,": "); x = env_get("GID"); if (!x) strerr_die2x(111,fatal,"$GID not set"); scan_ulong(x,&id); if (prot_gid((int) id) == -1) strerr_die2sys(111,fatal,"unable to setgid: "); x = env_get("UID"); if (!x) strerr_die2x(111,fatal,"$UID not set"); scan_ulong(x,&id); if (prot_uid((int) id) == -1) strerr_die2sys(111,fatal,"unable to setuid: "); } tinydyndns-0.4.2.debian1/droproot.h000066400000000000000000000001231103424076200172360ustar00rootroot00000000000000#ifndef DROPROOT_H #define DROPROOT_H extern void droproot(const char *); #endif tinydyndns-0.4.2.debian1/env.c000066400000000000000000000004441103424076200161570ustar00rootroot00000000000000#include "str.h" #include "env.h" extern /*@null@*/char *env_get(const char *s) { int i; unsigned int len; if (!s) return 0; len = str_len(s); for (i = 0;environ[i];++i) if (str_start(environ[i],s) && (environ[i][len] == '=')) return environ[i] + len + 1; return 0; } tinydyndns-0.4.2.debian1/env.h000066400000000000000000000001531103424076200161610ustar00rootroot00000000000000#ifndef ENV_H #define ENV_H extern char **environ; extern /*@null@*/char *env_get(const char *); #endif tinydyndns-0.4.2.debian1/error.c000066400000000000000000000021751103424076200165230ustar00rootroot00000000000000#include #include "error.h" /* warning: as coverage improves here, should update error_{str,temp} */ int error_intr = #ifdef EINTR EINTR; #else -1; #endif int error_nomem = #ifdef ENOMEM ENOMEM; #else -2; #endif int error_noent = #ifdef ENOENT ENOENT; #else -3; #endif int error_txtbsy = #ifdef ETXTBSY ETXTBSY; #else -4; #endif int error_io = #ifdef EIO EIO; #else -5; #endif int error_exist = #ifdef EEXIST EEXIST; #else -6; #endif int error_timeout = #ifdef ETIMEDOUT ETIMEDOUT; #else -7; #endif int error_inprogress = #ifdef EINPROGRESS EINPROGRESS; #else -8; #endif int error_wouldblock = #ifdef EWOULDBLOCK EWOULDBLOCK; #else -9; #endif int error_again = #ifdef EAGAIN EAGAIN; #else -10; #endif int error_pipe = #ifdef EPIPE EPIPE; #else -11; #endif int error_perm = #ifdef EPERM EPERM; #else -12; #endif int error_acces = #ifdef EACCES EACCES; #else -13; #endif int error_nodevice = #ifdef ENXIO ENXIO; #else -14; #endif int error_proto = #ifdef EPROTO EPROTO; #else -15; #endif int error_isdir = #ifdef EISDIR EISDIR; #else -16; #endif int error_connrefused = #ifdef ECONNREFUSED ECONNREFUSED; #else -17; #endif tinydyndns-0.4.2.debian1/error.h000066400000000000000000000010441103424076200165220ustar00rootroot00000000000000#ifndef ERROR_H #define ERROR_H extern int errno; extern int error_intr; extern int error_nomem; extern int error_noent; extern int error_txtbsy; extern int error_io; extern int error_exist; extern int error_timeout; extern int error_inprogress; extern int error_wouldblock; extern int error_again; extern int error_pipe; extern int error_perm; extern int error_acces; extern int error_nodevice; extern int error_proto; extern int error_isdir; extern int error_connrefused; extern const char *error_str(int); extern int error_temp(int); #endif tinydyndns-0.4.2.debian1/error_str.c000066400000000000000000000125711103424076200174140ustar00rootroot00000000000000#include #include "error.h" #define X(e,s) if (i == e) return s; const char *error_str(int i) { X(0,"no error") X(error_intr,"interrupted system call") X(error_nomem,"out of memory") X(error_noent,"file does not exist") X(error_txtbsy,"text busy") X(error_io,"input/output error") X(error_exist,"file already exists") X(error_timeout,"timed out") X(error_inprogress,"operation in progress") X(error_again,"temporary failure") X(error_wouldblock,"input/output would block") X(error_pipe,"broken pipe") X(error_perm,"permission denied") X(error_acces,"access denied") X(error_nodevice,"device not configured") X(error_proto,"protocol error") X(error_isdir,"is a directory") X(error_connrefused,"connection refused") #ifdef ESRCH X(ESRCH,"no such process") #endif #ifdef E2BIG X(E2BIG,"argument list too long") #endif #ifdef ENOEXEC X(ENOEXEC,"exec format error") #endif #ifdef EBADF X(EBADF,"file descriptor not open") #endif #ifdef ECHILD X(ECHILD,"no child processes") #endif #ifdef EDEADLK X(EDEADLK,"operation would cause deadlock") #endif #ifdef EFAULT X(EFAULT,"bad address") #endif #ifdef ENOTBLK X(ENOTBLK,"not a block device") #endif #ifdef EBUSY X(EBUSY,"device busy") #endif #ifdef EXDEV X(EXDEV,"cross-device link") #endif #ifdef ENODEV X(ENODEV,"device does not support operation") #endif #ifdef ENOTDIR X(ENOTDIR,"not a directory") #endif #ifdef EINVAL X(EINVAL,"invalid argument") #endif #ifdef ENFILE X(ENFILE,"system cannot open more files") #endif #ifdef EMFILE X(EMFILE,"process cannot open more files") #endif #ifdef ENOTTY X(ENOTTY,"not a tty") #endif #ifdef EFBIG X(EFBIG,"file too big") #endif #ifdef ENOSPC X(ENOSPC,"out of disk space") #endif #ifdef ESPIPE X(ESPIPE,"unseekable descriptor") #endif #ifdef EROFS X(EROFS,"read-only file system") #endif #ifdef EMLINK X(EMLINK,"too many links") #endif #ifdef EDOM X(EDOM,"input out of range") #endif #ifdef ERANGE X(ERANGE,"output out of range") #endif #ifdef EALREADY X(EALREADY,"operation already in progress") #endif #ifdef ENOTSOCK X(ENOTSOCK,"not a socket") #endif #ifdef EDESTADDRREQ X(EDESTADDRREQ,"destination address required") #endif #ifdef EMSGSIZE X(EMSGSIZE,"message too long") #endif #ifdef EPROTOTYPE X(EPROTOTYPE,"incorrect protocol type") #endif #ifdef ENOPROTOOPT X(ENOPROTOOPT,"protocol not available") #endif #ifdef EPROTONOSUPPORT X(EPROTONOSUPPORT,"protocol not supported") #endif #ifdef ESOCKTNOSUPPORT X(ESOCKTNOSUPPORT,"socket type not supported") #endif #ifdef EOPNOTSUPP X(EOPNOTSUPP,"operation not supported") #endif #ifdef EPFNOSUPPORT X(EPFNOSUPPORT,"protocol family not supported") #endif #ifdef EAFNOSUPPORT X(EAFNOSUPPORT,"address family not supported") #endif #ifdef EADDRINUSE X(EADDRINUSE,"address already used") #endif #ifdef EADDRNOTAVAIL X(EADDRNOTAVAIL,"address not available") #endif #ifdef ENETDOWN X(ENETDOWN,"network down") #endif #ifdef ENETUNREACH X(ENETUNREACH,"network unreachable") #endif #ifdef ENETRESET X(ENETRESET,"network reset") #endif #ifdef ECONNABORTED X(ECONNABORTED,"connection aborted") #endif #ifdef ECONNRESET X(ECONNRESET,"connection reset") #endif #ifdef ENOBUFS X(ENOBUFS,"out of buffer space") #endif #ifdef EISCONN X(EISCONN,"already connected") #endif #ifdef ENOTCONN X(ENOTCONN,"not connected") #endif #ifdef ESHUTDOWN X(ESHUTDOWN,"socket shut down") #endif #ifdef ETOOMANYREFS X(ETOOMANYREFS,"too many references") #endif #ifdef ELOOP X(ELOOP,"symbolic link loop") #endif #ifdef ENAMETOOLONG X(ENAMETOOLONG,"file name too long") #endif #ifdef EHOSTDOWN X(EHOSTDOWN,"host down") #endif #ifdef EHOSTUNREACH X(EHOSTUNREACH,"host unreachable") #endif #ifdef ENOTEMPTY X(ENOTEMPTY,"directory not empty") #endif #ifdef EPROCLIM X(EPROCLIM,"too many processes") #endif #ifdef EUSERS X(EUSERS,"too many users") #endif #ifdef EDQUOT X(EDQUOT,"disk quota exceeded") #endif #ifdef ESTALE X(ESTALE,"stale NFS file handle") #endif #ifdef EREMOTE X(EREMOTE,"too many levels of remote in path") #endif #ifdef EBADRPC X(EBADRPC,"RPC structure is bad") #endif #ifdef ERPCMISMATCH X(ERPCMISMATCH,"RPC version mismatch") #endif #ifdef EPROGUNAVAIL X(EPROGUNAVAIL,"RPC program unavailable") #endif #ifdef EPROGMISMATCH X(EPROGMISMATCH,"program version mismatch") #endif #ifdef EPROCUNAVAIL X(EPROCUNAVAIL,"bad procedure for program") #endif #ifdef ENOLCK X(ENOLCK,"no locks available") #endif #ifdef ENOSYS X(ENOSYS,"system call not available") #endif #ifdef EFTYPE X(EFTYPE,"bad file type") #endif #ifdef EAUTH X(EAUTH,"authentication error") #endif #ifdef ENEEDAUTH X(ENEEDAUTH,"not authenticated") #endif #ifdef ENOSTR X(ENOSTR,"not a stream device") #endif #ifdef ETIME X(ETIME,"timer expired") #endif #ifdef ENOSR X(ENOSR,"out of stream resources") #endif #ifdef ENOMSG X(ENOMSG,"no message of desired type") #endif #ifdef EBADMSG X(EBADMSG,"bad message type") #endif #ifdef EIDRM X(EIDRM,"identifier removed") #endif #ifdef ENONET X(ENONET,"machine not on network") #endif #ifdef ERREMOTE X(ERREMOTE,"object not local") #endif #ifdef ENOLINK X(ENOLINK,"link severed") #endif #ifdef EADV X(EADV,"advertise error") #endif #ifdef ESRMNT X(ESRMNT,"srmount error") #endif #ifdef ECOMM X(ECOMM,"communication error") #endif #ifdef EMULTIHOP X(EMULTIHOP,"multihop attempted") #endif #ifdef EREMCHG X(EREMCHG,"remote address changed") #endif return "unknown error"; } tinydyndns-0.4.2.debian1/exit.h000066400000000000000000000000741103424076200163440ustar00rootroot00000000000000#ifndef EXIT_H #define EXIT_H extern void _exit(); #endif tinydyndns-0.4.2.debian1/find-systype.sh000066400000000000000000000064041103424076200202170ustar00rootroot00000000000000# oper-:arch-:syst-:chip-:kern- # oper = operating system type; e.g., sunos-4.1.4 # arch = machine language; e.g., sparc # syst = which binaries can run; e.g., sun4 # chip = chip model; e.g., micro-2-80 # kern = kernel version; e.g., sun4m # dependence: arch --- chip # \ \ # oper --- syst --- kern # so, for example, syst is interpreted in light of oper, but chip is not. # anyway, no slashes, no extra colons, no uppercase letters. # the point of the extra -'s is to ease parsing: can add hierarchies later. # e.g., *:i386-*:*:pentium-*:* would handle pentium-100 as well as pentium, # and i386-486 (486s do have more instructions, you know) as well as i386. # the idea here is to include ALL useful available information. exec 2>/dev/null sys="`uname -s | tr '/:[A-Z]' '..[a-z]'`" if [ x"$sys" != x ] then unamer="`uname -r | tr /: ..`" unamem="`uname -m | tr /: ..`" unamev="`uname -v | tr /: ..`" case "$sys" in bsd.os|freebsd|netbsd|openbsd) # in bsd 4.4, uname -v does not have useful info. # in bsd 4.4, uname -m is arch, not chip. oper="$sys-$unamer" arch="$unamem" syst="" chip="`sysctl -n hw.model`" # hopefully kern="" ;; linux) # as in bsd 4.4, uname -v does not have useful info. oper="$sys-$unamer" syst="" chip="$unamem" kern="" case "$chip" in i386|i486|i586|i686) arch="i386" ;; alpha) arch="alpha" ;; esac ;; aix) # naturally IBM has to get uname -r and uname -v backwards. dorks. oper="$sys-$unamev-$unamer" arch="`arch | tr /: ..`" syst="" chip="$unamem" kern="" ;; sunos) oper="$sys-$unamer-$unamev" arch="`(uname -p || mach) | tr /: ..`" syst="`arch | tr /: ..`" chip="$unamem" # this is wrong; is there any way to get the real info? kern="`arch -k | tr /: ..`" ;; unix_sv) oper="$sys-$unamer-$unamev" arch="`uname -m`" syst="" chip="$unamem" kern="" ;; *) oper="$sys-$unamer-$unamev" arch="`arch | tr /: ..`" syst="" chip="$unamem" kern="" ;; esac else gcc -c trycpp.c gcc -o trycpp trycpp.o case `./trycpp` in nextstep) oper="nextstep-`hostinfo | sed -n 's/^[ ]*NeXT Mach \([^:]*\):.*$/\1/p'`" arch="`hostinfo | sed -n 's/^Processor type: \(.*\) (.*)$/\1/p' | tr /: ..`" syst="" chip="`hostinfo | sed -n 's/^Processor type: .* (\(.*\))$/\1/p' | tr ' /:' '...'`" kern="" ;; *) oper="unknown" arch="" syst="" chip="" kern="" ;; esac rm -f trycpp.o trycpp fi case "$chip" in 80486) # let's try to be consistent here. (BSD/OS) chip=i486 ;; i486DX) # respect the hyphen hierarchy. (FreeBSD) chip=i486-dx ;; i486.DX2) # respect the hyphen hierarchy. (FreeBSD) chip=i486-dx2 ;; Intel.586) # no, you nitwits, there is no such chip. (NeXTStep) chip=pentium ;; i586) # no, you nitwits, there is no such chip. (Linux) chip=pentium ;; i686) # STOP SAYING THAT! (Linux) chip=ppro esac if gcc -c x86cpuid.c then if gcc -o x86cpuid x86cpuid.o then x86cpuid="`./x86cpuid | tr /: ..`" case "$x86cpuid" in ?*) chip="$x86cpuid" ;; esac fi fi rm -f x86cpuid x86cpuid.o echo "$oper-:$arch-:$syst-:$chip-:$kern-" | tr ' [A-Z]' '.[a-z]' tinydyndns-0.4.2.debian1/fmt.h000066400000000000000000000020761103424076200161650ustar00rootroot00000000000000#ifndef FMT_H #define FMT_H #define FMT_ULONG 40 /* enough space to hold 2^128 - 1 in decimal, plus \0 */ #define FMT_LEN ((char *) 0) /* convenient abbreviation */ extern unsigned int fmt_uint(char *,unsigned int); extern unsigned int fmt_uint0(char *,unsigned int,unsigned int); extern unsigned int fmt_xint(char *,unsigned int); extern unsigned int fmt_nbbint(char *,unsigned int,unsigned int,unsigned int,unsigned int); extern unsigned int fmt_ushort(char *,unsigned short); extern unsigned int fmt_xshort(char *,unsigned short); extern unsigned int fmt_nbbshort(char *,unsigned int,unsigned int,unsigned int,unsigned short); extern unsigned int fmt_ulong(char *,unsigned long); extern unsigned int fmt_xlong(char *,unsigned long); extern unsigned int fmt_nbblong(char *,unsigned int,unsigned int,unsigned int,unsigned long); extern unsigned int fmt_plusminus(char *,int); extern unsigned int fmt_minus(char *,int); extern unsigned int fmt_0x(char *,int); extern unsigned int fmt_str(char *,const char *); extern unsigned int fmt_strn(char *,const char *,unsigned int); #endif tinydyndns-0.4.2.debian1/fmt_ulong.c000066400000000000000000000004721103424076200173620ustar00rootroot00000000000000#include "fmt.h" unsigned int fmt_ulong(register char *s,register unsigned long u) { register unsigned int len; register unsigned long q; len = 1; q = u; while (q > 9) { ++len; q /= 10; } if (s) { s += len; do { *--s = '0' + (u % 10); u /= 10; } while(u); /* handles u == 0 */ } return len; } tinydyndns-0.4.2.debian1/gen_alloc.h000066400000000000000000000002551103424076200173170ustar00rootroot00000000000000#ifndef GEN_ALLOC_H #define GEN_ALLOC_H #define GEN_ALLOC_typedef(ta,type,field,len,a) \ typedef struct ta { type *field; unsigned int len; unsigned int a; } ta; #endif tinydyndns-0.4.2.debian1/gen_allocdefs.h000066400000000000000000000022461103424076200201630ustar00rootroot00000000000000#ifndef GEN_ALLOC_DEFS_H #define GEN_ALLOC_DEFS_H #define GEN_ALLOC_ready(ta,type,field,len,a,i,n,x,base,ta_ready) \ int ta_ready(register ta *x,register unsigned int n) \ { register unsigned int i; \ if (x->field) { \ i = x->a; \ if (n > i) { \ x->a = base + n + (n >> 3); \ if (alloc_re(&x->field,i * sizeof(type),x->a * sizeof(type))) return 1; \ x->a = i; return 0; } \ return 1; } \ x->len = 0; \ return !!(x->field = (type *) alloc((x->a = n) * sizeof(type))); } #define GEN_ALLOC_readyplus(ta,type,field,len,a,i,n,x,base,ta_rplus) \ int ta_rplus(register ta *x,register unsigned int n) \ { register unsigned int i; \ if (x->field) { \ i = x->a; n += x->len; \ if (n > i) { \ x->a = base + n + (n >> 3); \ if (alloc_re(&x->field,i * sizeof(type),x->a * sizeof(type))) return 1; \ x->a = i; return 0; } \ return 1; } \ x->len = 0; \ return !!(x->field = (type *) alloc((x->a = n) * sizeof(type))); } #define GEN_ALLOC_append(ta,type,field,len,a,i,n,x,base,ta_rplus,ta_append) \ int ta_append(register ta *x,register const type *i) \ { if (!ta_rplus(x,1)) return 0; x->field[x->len++] = *i; return 1; } #endif tinydyndns-0.4.2.debian1/generic-conf.c000066400000000000000000000033341103424076200177270ustar00rootroot00000000000000#include #include #include #include "strerr.h" #include "buffer.h" #include "open.h" #include "generic-conf.h" static const char *fatal; static const char *dir; static const char *fn; static int fd; static char buf[1024]; static buffer ss; void init(const char *d,const char *f) { dir = d; fatal = f; umask(022); if (mkdir(dir,0700) == -1) strerr_die4sys(111,fatal,"unable to create ",dir,": "); if (chmod(dir,03755) == -1) strerr_die4sys(111,fatal,"unable to set mode of ",dir,": "); if (chdir(dir) == -1) strerr_die4sys(111,fatal,"unable to switch to ",dir,": "); } void fail(void) { strerr_die6sys(111,fatal,"unable to create ",dir,"/",fn,": "); } void makedir(const char *s) { fn = s; if (mkdir(fn,0700) == -1) fail(); } void start(const char *s) { fn = s; fd = open_trunc(fn); if (fd == -1) fail(); buffer_init(&ss,buffer_unixwrite,fd,buf,sizeof buf); } void outs(const char *s) { if (buffer_puts(&ss,s) == -1) fail(); } void out(const char *s,unsigned int len) { if (buffer_put(&ss,s,len) == -1) fail(); } void copyfrom(buffer *b) { if (buffer_copy(&ss,b) < 0) fail(); } void finish(void) { if (buffer_flush(&ss) == -1) fail(); if (fsync(fd) == -1) fail(); close(fd); } void perm(int mode) { if (chmod(fn,mode) == -1) fail(); } void owner(int uid,int gid) { if (chown(fn,uid,gid) == -1) fail(); } void makelog(const char *user,int uid,int gid) { makedir("log"); perm(02755); makedir("log/main"); owner(uid,gid); perm(02755); start("log/status"); finish(); owner(uid,gid); perm(0644); start("log/run"); outs("#!/bin/sh\nexec"); outs(" setuidgid "); outs(user); outs(" multilog t ./main\n"); finish(); perm(0755); } tinydyndns-0.4.2.debian1/generic-conf.h000066400000000000000000000006441103424076200177350ustar00rootroot00000000000000#ifndef GENERIC_CONF_H #define GENERIC_CONF_H #include "buffer.h" extern void init(const char *,const char *); extern void makedir(const char *); extern void start(const char *); extern void outs(const char *); extern void out(const char *,unsigned int); extern void copyfrom(buffer *); extern void finish(void); extern void perm(int); extern void owner(int,int); extern void makelog(const char *,int,int); #endif tinydyndns-0.4.2.debian1/getln.c000066400000000000000000000004521103424076200164770ustar00rootroot00000000000000#include "byte.h" #include "getln.h" int getln(buffer *ss,stralloc *sa,int *match,int sep) { char *cont; unsigned int clen; if (getln2(ss,sa,&cont,&clen,sep) == -1) return -1; if (!clen) { *match = 0; return 0; } if (!stralloc_catb(sa,cont,clen)) return -1; *match = 1; return 0; } tinydyndns-0.4.2.debian1/getln.h000066400000000000000000000003101103424076200164750ustar00rootroot00000000000000#ifndef GETLN_H #define GETLN_H #include "buffer.h" #include "stralloc.h" extern int getln(buffer *,stralloc *,int *,int); extern int getln2(buffer *,stralloc *,char **,unsigned int *,int); #endif tinydyndns-0.4.2.debian1/getln2.c000066400000000000000000000010751103424076200165630ustar00rootroot00000000000000#include "byte.h" #include "getln.h" int getln2(buffer *ss,stralloc *sa,char **cont,unsigned int *clen,int sep) { register char *x; register unsigned int i; int n; if (!stralloc_ready(sa,0)) return -1; sa->len = 0; for (;;) { n = buffer_feed(ss); if (n < 0) return -1; if (n == 0) { *clen = 0; return 0; } x = buffer_PEEK(ss); i = byte_chr(x,n,sep); if (i < n) { buffer_SEEK(ss,*clen = i + 1); *cont = x; return 0; } if (!stralloc_readyplus(sa,n)) return -1; i = sa->len; sa->len = i + buffer_get(ss,sa->s + i,n); } } tinydyndns-0.4.2.debian1/hasdevtcp.h1000066400000000000000000000000261103424076200174320ustar00rootroot00000000000000/* sysdep: -devtcp */ tinydyndns-0.4.2.debian1/hasdevtcp.h2000066400000000000000000000000521103424076200174320ustar00rootroot00000000000000/* sysdep: +devtcp */ #define HASDEVTCP 1 tinydyndns-0.4.2.debian1/hasshsgr.h1000066400000000000000000000000361103424076200172740ustar00rootroot00000000000000/* sysdep: -shortsetgroups */ tinydyndns-0.4.2.debian1/hasshsgr.h2000066400000000000000000000000721103424076200172750ustar00rootroot00000000000000/* sysdep: +shortsetgroups */ #define HASSHORTSETGROUPS 1 tinydyndns-0.4.2.debian1/hier.c000066400000000000000000000026541103424076200163230ustar00rootroot00000000000000#include "auto_home.h" void hier() { c("/","etc","dnsroots.global",-1,-1,0644); h(auto_home,-1,-1,02755); d(auto_home,"bin",-1,-1,02755); c(auto_home,"bin","dnscache-conf",-1,-1,0755); c(auto_home,"bin","tinydns-conf",-1,-1,0755); c(auto_home,"bin","walldns-conf",-1,-1,0755); c(auto_home,"bin","rbldns-conf",-1,-1,0755); c(auto_home,"bin","pickdns-conf",-1,-1,0755); c(auto_home,"bin","axfrdns-conf",-1,-1,0755); c(auto_home,"bin","dnscache",-1,-1,0755); c(auto_home,"bin","tinydns",-1,-1,0755); c(auto_home,"bin","walldns",-1,-1,0755); c(auto_home,"bin","rbldns",-1,-1,0755); c(auto_home,"bin","pickdns",-1,-1,0755); c(auto_home,"bin","axfrdns",-1,-1,0755); c(auto_home,"bin","tinydns-get",-1,-1,0755); c(auto_home,"bin","tinydns-data",-1,-1,0755); c(auto_home,"bin","tinydns-edit",-1,-1,0755); c(auto_home,"bin","rbldns-data",-1,-1,0755); c(auto_home,"bin","pickdns-data",-1,-1,0755); c(auto_home,"bin","axfr-get",-1,-1,0755); c(auto_home,"bin","dnsip",-1,-1,0755); c(auto_home,"bin","dnsipq",-1,-1,0755); c(auto_home,"bin","dnsname",-1,-1,0755); c(auto_home,"bin","dnstxt",-1,-1,0755); c(auto_home,"bin","dnsmx",-1,-1,0755); c(auto_home,"bin","dnsfilter",-1,-1,0755); c(auto_home,"bin","random-ip",-1,-1,0755); c(auto_home,"bin","dnsqr",-1,-1,0755); c(auto_home,"bin","dnsq",-1,-1,0755); c(auto_home,"bin","dnstrace",-1,-1,0755); c(auto_home,"bin","dnstracesort",-1,-1,0755); } tinydyndns-0.4.2.debian1/install.c000066400000000000000000000101021103424076200170250ustar00rootroot00000000000000#include #include #include #include "buffer.h" #include "strerr.h" #include "error.h" #include "open.h" #include "exit.h" extern void hier(); #define FATAL "install: fatal: " int fdsourcedir = -1; void h(home,uid,gid,mode) char *home; int uid; int gid; int mode; { if (mkdir(home,0700) == -1) if (errno != error_exist) strerr_die4sys(111,FATAL,"unable to mkdir ",home,": "); if (chown(home,uid,gid) == -1) strerr_die4sys(111,FATAL,"unable to chown ",home,": "); if (chmod(home,mode) == -1) strerr_die4sys(111,FATAL,"unable to chmod ",home,": "); } void d(home,subdir,uid,gid,mode) char *home; char *subdir; int uid; int gid; int mode; { if (chdir(home) == -1) strerr_die4sys(111,FATAL,"unable to switch to ",home,": "); if (mkdir(subdir,0700) == -1) if (errno != error_exist) strerr_die6sys(111,FATAL,"unable to mkdir ",home,"/",subdir,": "); if (chown(subdir,uid,gid) == -1) strerr_die6sys(111,FATAL,"unable to chown ",home,"/",subdir,": "); if (chmod(subdir,mode) == -1) strerr_die6sys(111,FATAL,"unable to chmod ",home,"/",subdir,": "); } char inbuf[BUFFER_INSIZE]; char outbuf[BUFFER_OUTSIZE]; buffer ssin; buffer ssout; void c(home,subdir,file,uid,gid,mode) char *home; char *subdir; char *file; int uid; int gid; int mode; { int fdin; int fdout; if (fchdir(fdsourcedir) == -1) strerr_die2sys(111,FATAL,"unable to switch back to source directory: "); fdin = open_read(file); if (fdin == -1) strerr_die4sys(111,FATAL,"unable to read ",file,": "); buffer_init(&ssin,buffer_unixread,fdin,inbuf,sizeof inbuf); if (chdir(home) == -1) strerr_die4sys(111,FATAL,"unable to switch to ",home,": "); if (chdir(subdir) == -1) strerr_die6sys(111,FATAL,"unable to switch to ",home,"/",subdir,": "); fdout = open_trunc(file); if (fdout == -1) strerr_die6sys(111,FATAL,"unable to write .../",subdir,"/",file,": "); buffer_init(&ssout,buffer_unixwrite,fdout,outbuf,sizeof outbuf); switch(buffer_copy(&ssout,&ssin)) { case -2: strerr_die4sys(111,FATAL,"unable to read ",file,": "); case -3: strerr_die6sys(111,FATAL,"unable to write .../",subdir,"/",file,": "); } close(fdin); if (buffer_flush(&ssout) == -1) strerr_die6sys(111,FATAL,"unable to write .../",subdir,"/",file,": "); if (fsync(fdout) == -1) strerr_die6sys(111,FATAL,"unable to write .../",subdir,"/",file,": "); if (close(fdout) == -1) /* NFS silliness */ strerr_die6sys(111,FATAL,"unable to write .../",subdir,"/",file,": "); if (chown(file,uid,gid) == -1) strerr_die6sys(111,FATAL,"unable to chown .../",subdir,"/",file,": "); if (chmod(file,mode) == -1) strerr_die6sys(111,FATAL,"unable to chmod .../",subdir,"/",file,": "); } void z(home,subdir,file,len,uid,gid,mode) char *home; char *subdir; char *file; int len; int uid; int gid; int mode; { int fdout; if (chdir(home) == -1) strerr_die4sys(111,FATAL,"unable to switch to ",home,": "); if (chdir(subdir) == -1) strerr_die6sys(111,FATAL,"unable to switch to ",home,"/",subdir,": "); fdout = open_trunc(file); if (fdout == -1) strerr_die6sys(111,FATAL,"unable to write .../",subdir,"/",file,": "); buffer_init(&ssout,buffer_unixwrite,fdout,outbuf,sizeof outbuf); while (len-- > 0) if (buffer_put(&ssout,"",1) == -1) strerr_die6sys(111,FATAL,"unable to write .../",subdir,"/",file,": "); if (buffer_flush(&ssout) == -1) strerr_die6sys(111,FATAL,"unable to write .../",subdir,"/",file,": "); if (fsync(fdout) == -1) strerr_die6sys(111,FATAL,"unable to write .../",subdir,"/",file,": "); if (close(fdout) == -1) /* NFS silliness */ strerr_die6sys(111,FATAL,"unable to write .../",subdir,"/",file,": "); if (chown(file,uid,gid) == -1) strerr_die6sys(111,FATAL,"unable to chown .../",subdir,"/",file,": "); if (chmod(file,mode) == -1) strerr_die6sys(111,FATAL,"unable to chmod .../",subdir,"/",file,": "); } int main() { fdsourcedir = open_read("."); if (fdsourcedir == -1) strerr_die2sys(111,FATAL,"unable to open current directory: "); umask(077); hier(); _exit(0); } tinydyndns-0.4.2.debian1/instcheck.c000066400000000000000000000043711103424076200173450ustar00rootroot00000000000000#include #include #include #include "strerr.h" #include "error.h" #include "exit.h" extern void hier(); #define FATAL "instcheck: fatal: " #define WARNING "instcheck: warning: " void perm(prefix1,prefix2,prefix3,file,type,uid,gid,mode) char *prefix1; char *prefix2; char *prefix3; char *file; int type; int uid; int gid; int mode; { struct stat st; if (stat(file,&st) == -1) { if (errno == error_noent) strerr_warn6(WARNING,prefix1,prefix2,prefix3,file," does not exist",0); else strerr_warn4(WARNING,"unable to stat .../",file,": ",&strerr_sys); return; } if ((uid != -1) && (st.st_uid != uid)) strerr_warn6(WARNING,prefix1,prefix2,prefix3,file," has wrong owner",0); if ((gid != -1) && (st.st_gid != gid)) strerr_warn6(WARNING,prefix1,prefix2,prefix3,file," has wrong group",0); if ((st.st_mode & 07777) != mode) strerr_warn6(WARNING,prefix1,prefix2,prefix3,file," has wrong permissions",0); if ((st.st_mode & S_IFMT) != type) strerr_warn6(WARNING,prefix1,prefix2,prefix3,file," has wrong type",0); } void h(home,uid,gid,mode) char *home; int uid; int gid; int mode; { perm("","","",home,S_IFDIR,uid,gid,mode); } void d(home,subdir,uid,gid,mode) char *home; char *subdir; int uid; int gid; int mode; { if (chdir(home) == -1) strerr_die4sys(111,FATAL,"unable to switch to ",home,": "); perm("",home,"/",subdir,S_IFDIR,uid,gid,mode); } void p(home,fifo,uid,gid,mode) char *home; char *fifo; int uid; int gid; int mode; { if (chdir(home) == -1) strerr_die4sys(111,FATAL,"unable to switch to ",home,": "); perm("",home,"/",fifo,S_IFIFO,uid,gid,mode); } void c(home,subdir,file,uid,gid,mode) char *home; char *subdir; char *file; int uid; int gid; int mode; { if (chdir(home) == -1) strerr_die4sys(111,FATAL,"unable to switch to ",home,": "); if (chdir(subdir) == -1) strerr_die6sys(111,FATAL,"unable to switch to ",home,"/",subdir,": "); perm(".../",subdir,"/",file,S_IFREG,uid,gid,mode); } void z(home,file,len,uid,gid,mode) char *home; char *file; int len; int uid; int gid; int mode; { if (chdir(home) == -1) strerr_die4sys(111,FATAL,"unable to switch to ",home,": "); perm("",home,"/",file,S_IFREG,uid,gid,mode); } int main() { hier(); _exit(0); } tinydyndns-0.4.2.debian1/iopause.c000066400000000000000000000031661103424076200170400ustar00rootroot00000000000000#include "taia.h" #include "select.h" #include "iopause.h" void iopause(iopause_fd *x,unsigned int len,struct taia *deadline,struct taia *stamp) { struct taia t; int millisecs; double d; int i; if (taia_less(deadline,stamp)) millisecs = 0; else { t = *stamp; taia_sub(&t,deadline,&t); d = taia_approx(&t); if (d > 1000.0) d = 1000.0; millisecs = d * 1000.0 + 20.0; } for (i = 0;i < len;++i) x[i].revents = 0; #ifdef IOPAUSE_POLL poll(x,len,millisecs); /* XXX: some kernels apparently need x[0] even if len is 0 */ /* XXX: how to handle EAGAIN? are kernels really this dumb? */ /* XXX: how to handle EINVAL? when exactly can this happen? */ #else { struct timeval tv; fd_set rfds; fd_set wfds; int nfds; int fd; FD_ZERO(&rfds); FD_ZERO(&wfds); nfds = 1; for (i = 0;i < len;++i) { fd = x[i].fd; if (fd < 0) continue; if (fd >= 8 * sizeof(fd_set)) continue; /*XXX*/ if (fd >= nfds) nfds = fd + 1; if (x[i].events & IOPAUSE_READ) FD_SET(fd,&rfds); if (x[i].events & IOPAUSE_WRITE) FD_SET(fd,&wfds); } tv.tv_sec = millisecs / 1000; tv.tv_usec = 1000 * (millisecs % 1000); if (select(nfds,&rfds,&wfds,(fd_set *) 0,&tv) <= 0) return; /* XXX: for EBADF, could seek out and destroy the bad descriptor */ for (i = 0;i < len;++i) { fd = x[i].fd; if (fd < 0) continue; if (fd >= 8 * sizeof(fd_set)) continue; /*XXX*/ if (x[i].events & IOPAUSE_READ) if (FD_ISSET(fd,&rfds)) x[i].revents |= IOPAUSE_READ; if (x[i].events & IOPAUSE_WRITE) if (FD_ISSET(fd,&wfds)) x[i].revents |= IOPAUSE_WRITE; } } #endif } tinydyndns-0.4.2.debian1/iopause.h1000066400000000000000000000004341103424076200171210ustar00rootroot00000000000000#ifndef IOPAUSE_H #define IOPAUSE_H /* sysdep: -poll */ typedef struct { int fd; short events; short revents; } iopause_fd; #define IOPAUSE_READ 1 #define IOPAUSE_WRITE 4 #include "taia.h" extern void iopause(iopause_fd *,unsigned int,struct taia *,struct taia *); #endif tinydyndns-0.4.2.debian1/iopause.h2000066400000000000000000000004751103424076200171270ustar00rootroot00000000000000#ifndef IOPAUSE_H #define IOPAUSE_H /* sysdep: +poll */ #define IOPAUSE_POLL #include #include typedef struct pollfd iopause_fd; #define IOPAUSE_READ POLLIN #define IOPAUSE_WRITE POLLOUT #include "taia.h" extern void iopause(iopause_fd *,unsigned int,struct taia *,struct taia *); #endif tinydyndns-0.4.2.debian1/ip4.h000066400000000000000000000002361103424076200160670ustar00rootroot00000000000000#ifndef IP4_H #define IP4_H extern unsigned int ip4_scan(const char *,char *); extern unsigned int ip4_fmt(char *,const char *); #define IP4_FMT 20 #endif tinydyndns-0.4.2.debian1/ip4_fmt.c000066400000000000000000000010671103424076200167330ustar00rootroot00000000000000#include "fmt.h" #include "ip4.h" unsigned int ip4_fmt(char *s,const char ip[4]) { unsigned int len; unsigned int i; len = 0; i = fmt_ulong(s,(unsigned long) (unsigned char) ip[0]); len += i; if (s) s += i; if (s) *s++ = '.'; ++len; i = fmt_ulong(s,(unsigned long) (unsigned char) ip[1]); len += i; if (s) s += i; if (s) *s++ = '.'; ++len; i = fmt_ulong(s,(unsigned long) (unsigned char) ip[2]); len += i; if (s) s += i; if (s) *s++ = '.'; ++len; i = fmt_ulong(s,(unsigned long) (unsigned char) ip[3]); len += i; if (s) s += i; return len; } tinydyndns-0.4.2.debian1/ip4_scan.c000066400000000000000000000010751103424076200170700ustar00rootroot00000000000000#include "scan.h" #include "ip4.h" unsigned int ip4_scan(const char *s,char ip[4]) { unsigned int i; unsigned int len; unsigned long u; len = 0; i = scan_ulong(s,&u); if (!i) return 0; ip[0] = u; s += i; len += i; if (*s != '.') return 0; ++s; ++len; i = scan_ulong(s,&u); if (!i) return 0; ip[1] = u; s += i; len += i; if (*s != '.') return 0; ++s; ++len; i = scan_ulong(s,&u); if (!i) return 0; ip[2] = u; s += i; len += i; if (*s != '.') return 0; ++s; ++len; i = scan_ulong(s,&u); if (!i) return 0; ip[3] = u; s += i; len += i; return len; } tinydyndns-0.4.2.debian1/log.c000066400000000000000000000132271103424076200161530ustar00rootroot00000000000000#include "buffer.h" #include "uint32.h" #include "uint16.h" #include "error.h" #include "byte.h" #include "log.h" /* work around gcc 2.95.2 bug */ #define number(x) ( (u64 = (x)), u64_print() ) static uint64 u64; static void u64_print(void) { char buf[20]; unsigned int pos; pos = sizeof buf; do { if (!pos) break; buf[--pos] = '0' + (u64 % 10); u64 /= 10; } while(u64); buffer_put(buffer_2,buf + pos,sizeof buf - pos); } static void hex(unsigned char c) { buffer_put(buffer_2,"0123456789abcdef" + (c >> 4),1); buffer_put(buffer_2,"0123456789abcdef" + (c & 15),1); } static void string(const char *s) { buffer_puts(buffer_2,s); } static void line(void) { string("\n"); buffer_flush(buffer_2); } static void space(void) { string(" "); } static void ip(const char i[4]) { hex(i[0]); hex(i[1]); hex(i[2]); hex(i[3]); } static void logid(const char id[2]) { hex(id[0]); hex(id[1]); } static void logtype(const char type[2]) { uint16 u; uint16_unpack_big(type,&u); number(u); } static void name(const char *q) { char ch; int state; if (!*q) { string("."); return; } while (state = *q++) { while (state) { ch = *q++; --state; if ((ch <= 32) || (ch > 126)) ch = '?'; if ((ch >= 'A') && (ch <= 'Z')) ch += 32; buffer_put(buffer_2,&ch,1); } string("."); } } void log_startup(void) { string("starting"); line(); } void log_query(uint64 *qnum,const char client[4],unsigned int port,const char id[2],const char *q,const char qtype[2]) { string("query "); number(*qnum); space(); ip(client); string(":"); hex(port >> 8); hex(port & 255); string(":"); logid(id); space(); logtype(qtype); space(); name(q); line(); } void log_querydone(uint64 *qnum,unsigned int len) { string("sent "); number(*qnum); space(); number(len); line(); } void log_querydrop(uint64 *qnum) { const char *x = error_str(errno); string("drop "); number(*qnum); space(); string(x); line(); } void log_tcpopen(const char client[4],unsigned int port) { string("tcpopen "); ip(client); string(":"); hex(port >> 8); hex(port & 255); line(); } void log_tcpclose(const char client[4],unsigned int port) { const char *x = error_str(errno); string("tcpclose "); ip(client); string(":"); hex(port >> 8); hex(port & 255); space(); string(x); line(); } void log_tx(const char *q,const char qtype[2],const char *control,const char servers[64],unsigned int gluelessness) { int i; string("tx "); number(gluelessness); space(); logtype(qtype); space(); name(q); space(); name(control); for (i = 0;i < 64;i += 4) if (byte_diff(servers + i,4,"\0\0\0\0")) { space(); ip(servers + i); } line(); } void log_cachedanswer(const char *q,const char type[2]) { string("cached "); logtype(type); space(); name(q); line(); } void log_cachedcname(const char *dn,const char *dn2) { string("cached cname "); name(dn); space(); name(dn2); line(); } void log_cachedns(const char *control,const char *ns) { string("cached ns "); name(control); space(); name(ns); line(); } void log_cachednxdomain(const char *dn) { string("cached nxdomain "); name(dn); line(); } void log_nxdomain(const char server[4],const char *q,unsigned int ttl) { string("nxdomain "); ip(server); space(); number(ttl); space(); name(q); line(); } void log_nodata(const char server[4],const char *q,const char qtype[2],unsigned int ttl) { string("nodata "); ip(server); space(); number(ttl); space(); logtype(qtype); space(); name(q); line(); } void log_lame(const char server[4],const char *control,const char *referral) { string("lame "); ip(server); space(); name(control); space(); name(referral); line(); } void log_servfail(const char *dn) { const char *x = error_str(errno); string("servfail "); name(dn); space(); string(x); line(); } void log_rr(const char server[4],const char *q,const char type[2],const char *buf,unsigned int len,unsigned int ttl) { int i; string("rr "); ip(server); space(); number(ttl); space(); logtype(type); space(); name(q); space(); for (i = 0;i < len;++i) { hex(buf[i]); if (i > 30) { string("..."); break; } } line(); } void log_rrns(const char server[4],const char *q,const char *data,unsigned int ttl) { string("rr "); ip(server); space(); number(ttl); string(" ns "); name(q); space(); name(data); line(); } void log_rrcname(const char server[4],const char *q,const char *data,unsigned int ttl) { string("rr "); ip(server); space(); number(ttl); string(" cname "); name(q); space(); name(data); line(); } void log_rrptr(const char server[4],const char *q,const char *data,unsigned int ttl) { string("rr "); ip(server); space(); number(ttl); string(" ptr "); name(q); space(); name(data); line(); } void log_rrmx(const char server[4],const char *q,const char *mx,const char pref[2],unsigned int ttl) { uint16 u; string("rr "); ip(server); space(); number(ttl); string(" mx "); name(q); space(); uint16_unpack_big(pref,&u); number(u); space(); name(mx); line(); } void log_rrsoa(const char server[4],const char *q,const char *n1,const char *n2,const char misc[20],unsigned int ttl) { uint32 u; int i; string("rr "); ip(server); space(); number(ttl); string(" soa "); name(q); space(); name(n1); space(); name(n2); for (i = 0;i < 20;i += 4) { uint32_unpack_big(misc + i,&u); space(); number(u); } line(); } void log_stats(void) { extern uint64 numqueries; extern uint64 cache_motion; extern int uactive; extern int tactive; string("stats "); number(numqueries); space(); number(cache_motion); space(); number(uactive); space(); number(tactive); line(); } tinydyndns-0.4.2.debian1/log.h000066400000000000000000000027041103424076200161560ustar00rootroot00000000000000#ifndef LOG_H #define LOG_H #include "uint64.h" extern void log_startup(void); extern void log_query(uint64 *,const char *,unsigned int,const char *,const char *,const char *); extern void log_querydrop(uint64 *); extern void log_querydone(uint64 *,unsigned int); extern void log_tcpopen(const char *,unsigned int); extern void log_tcpclose(const char *,unsigned int); extern void log_cachedanswer(const char *,const char *); extern void log_cachedcname(const char *,const char *); extern void log_cachednxdomain(const char *); extern void log_cachedns(const char *,const char *); extern void log_tx(const char *,const char *,const char *,const char *,unsigned int); extern void log_nxdomain(const char *,const char *,unsigned int); extern void log_nodata(const char *,const char *,const char *,unsigned int); extern void log_servfail(const char *); extern void log_lame(const char *,const char *,const char *); extern void log_rr(const char *,const char *,const char *,const char *,unsigned int,unsigned int); extern void log_rrns(const char *,const char *,const char *,unsigned int); extern void log_rrcname(const char *,const char *,const char *,unsigned int); extern void log_rrptr(const char *,const char *,const char *,unsigned int); extern void log_rrmx(const char *,const char *,const char *,const char *,unsigned int); extern void log_rrsoa(const char *,const char *,const char *,const char *,const char *,unsigned int); extern void log_stats(void); #endif tinydyndns-0.4.2.debian1/ndelay.h000066400000000000000000000001421103424076200166430ustar00rootroot00000000000000#ifndef NDELAY_H #define NDELAY_H extern int ndelay_on(int); extern int ndelay_off(int); #endif tinydyndns-0.4.2.debian1/ndelay_off.c000066400000000000000000000003171103424076200174740ustar00rootroot00000000000000#include #include #include "ndelay.h" #ifndef O_NONBLOCK #define O_NONBLOCK O_NDELAY #endif int ndelay_off(int fd) { return fcntl(fd,F_SETFL,fcntl(fd,F_GETFL,0) & ~O_NONBLOCK); } tinydyndns-0.4.2.debian1/ndelay_on.c000066400000000000000000000003151103424076200173340ustar00rootroot00000000000000#include #include #include "ndelay.h" #ifndef O_NONBLOCK #define O_NONBLOCK O_NDELAY #endif int ndelay_on(int fd) { return fcntl(fd,F_SETFL,fcntl(fd,F_GETFL,0) | O_NONBLOCK); } tinydyndns-0.4.2.debian1/okclient.c000066400000000000000000000006631103424076200172020ustar00rootroot00000000000000#include #include #include "str.h" #include "ip4.h" #include "okclient.h" static char fn[3 + IP4_FMT]; int okclient(char ip[4]) { struct stat st; int i; fn[0] = 'i'; fn[1] = 'p'; fn[2] = '/'; fn[3 + ip4_fmt(fn + 3,ip)] = 0; for (;;) { if (stat(fn,&st) == 0) return 1; /* treat temporary error as rejection */ i = str_rchr(fn,'.'); if (!fn[i]) return 0; fn[i] = 0; } } tinydyndns-0.4.2.debian1/okclient.h000066400000000000000000000001141103424076200171760ustar00rootroot00000000000000#ifndef OKCLIENT_H #define OKCLIENT_H extern int okclient(char *); #endif tinydyndns-0.4.2.debian1/open.h000066400000000000000000000003371103424076200163360ustar00rootroot00000000000000#ifndef OPEN_H #define OPEN_H extern int open_read(const char *); extern int open_excl(const char *); extern int open_append(const char *); extern int open_trunc(const char *); extern int open_write(const char *); #endif tinydyndns-0.4.2.debian1/open_read.c000066400000000000000000000002041103424076200173150ustar00rootroot00000000000000#include #include #include "open.h" int open_read(const char *fn) { return open(fn,O_RDONLY | O_NDELAY); } tinydyndns-0.4.2.debian1/open_trunc.c000066400000000000000000000002361103424076200175420ustar00rootroot00000000000000#include #include #include "open.h" int open_trunc(const char *fn) { return open(fn,O_WRONLY | O_NDELAY | O_TRUNC | O_CREAT,0644); } tinydyndns-0.4.2.debian1/openreadclose.c000066400000000000000000000005121103424076200202060ustar00rootroot00000000000000#include "error.h" #include "open.h" #include "readclose.h" #include "openreadclose.h" int openreadclose(const char *fn,stralloc *sa,unsigned int bufsize) { int fd; fd = open_read(fn); if (fd == -1) { if (errno == error_noent) return 0; return -1; } if (readclose(fd,sa,bufsize) == -1) return -1; return 1; } tinydyndns-0.4.2.debian1/openreadclose.h000066400000000000000000000002201103424076200202070ustar00rootroot00000000000000#ifndef OPENREADCLOSE_H #define OPENREADCLOSE_H #include "stralloc.h" extern int openreadclose(const char *,stralloc *,unsigned int); #endif tinydyndns-0.4.2.debian1/package/000077500000000000000000000000001103424076200166145ustar00rootroot00000000000000tinydyndns-0.4.2.debian1/package/CHANGES000066400000000000000000000032521103424076200176110ustar00rootroot00000000000000tinydyndns 0.4.2 Tue, 14 Mar 2006 23:16:38 +0000 * move project to http://smarden.org/tinydyndns/. * doc/configuration.html: remove broken link to http://cr.yp.to/djbdns/parents.html (thx Bill Shupp). tinydyndns 0.4.0 Sun, 29 Feb 2004 15:04:24 +0000 * doc/fake-pop3d.html: fix sample to work with current version (thx Patrik Nilsson). * doc/fake-pop3d.sh: minor. * doc/install.html: note on newer glibc. * tinydyndns-data.c: support setting ip, ttl, ttd, location through environment when adding records. * tinydyndns-update.c: support setting ttl, ttd additionally to ip; support setting location for records; skips non-type-a records instead of barfing. * man/tinydyndns-data.8, man/tinydyndns-update.8, Makefile.tinydyndns: adapt. tinydyndns 0.3.1 Mon, 03 Nov 2003 10:39:52 +0000 * man/tinydyndns-data.8: typo. * src/tinydyndns-conf: fix target rebuild (used for failover) in generated Makefile. tinydyndns 0.3.0 Wed, 16 Jul 2003 11:06:07 +0200 * doc/failover.html: new; how to provide failover. * doc/upgrade.html: new; upgrading from previous versions. * doc/fake-pop3.html, doc/fake-pop3.sh: new; minimal tinydyndns client for Unix. * doc/index.html: adapt. * tinydyndns-conf: create Makefile with rebuild target; remove last line ``exit 0'' from setpasswd. tinydyndns 0.2.1 Thu, 01 May 2003 15:36:19 +0200 * package/REAMDE, package/COPYING: new; include three-clause BSD-license information. * doc/index.html: typo; change title. tinydyndns 0.2.0 Mon, 25 Nov 2002 15:43:12 +0100 * tinydyndns-update.c, tinydyndns-data.c: new; manipulate data.cdb. tinydyndns 0.1.0 Fri, 3 May 2002 09:41:36 +0200 * initial version. tinydyndns-0.4.2.debian1/package/COPYING000066400000000000000000000026121103424076200176500ustar00rootroot00000000000000Copyright (c) 2002-2006, Gerrit Pape 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. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. tinydyndns-0.4.2.debian1/package/README000066400000000000000000000000731103424076200174740ustar00rootroot00000000000000Copyright 2002-2006 G. Pape http://smarden.org/tinydyndns/ tinydyndns-0.4.2.debian1/parsetype.c000066400000000000000000000021541103424076200174030ustar00rootroot00000000000000#include "scan.h" #include "byte.h" #include "case.h" #include "dns.h" #include "uint16.h" #include "parsetype.h" int parsetype(char *s,char type[2]) { unsigned long u; if (!s[scan_ulong(s,&u)]) uint16_pack_big(type,u); else if (case_equals(s,"any")) byte_copy(type,2,DNS_T_ANY); else if (case_equals(s,"a")) byte_copy(type,2,DNS_T_A); else if (case_equals(s,"ns")) byte_copy(type,2,DNS_T_NS); else if (case_equals(s,"mx")) byte_copy(type,2,DNS_T_MX); else if (case_equals(s,"ptr")) byte_copy(type,2,DNS_T_PTR); else if (case_equals(s,"txt")) byte_copy(type,2,DNS_T_TXT); else if (case_equals(s,"cname")) byte_copy(type,2,DNS_T_CNAME); else if (case_equals(s,"soa")) byte_copy(type,2,DNS_T_SOA); else if (case_equals(s,"hinfo")) byte_copy(type,2,DNS_T_HINFO); else if (case_equals(s,"rp")) byte_copy(type,2,DNS_T_RP); else if (case_equals(s,"sig")) byte_copy(type,2,DNS_T_SIG); else if (case_equals(s,"key")) byte_copy(type,2,DNS_T_KEY); else if (case_equals(s,"aaaa")) byte_copy(type,2,DNS_T_AAAA); else if (case_equals(s,"axfr")) byte_copy(type,2,DNS_T_AXFR); else return 0; return 1; } tinydyndns-0.4.2.debian1/parsetype.h000066400000000000000000000001261103424076200174050ustar00rootroot00000000000000#ifndef PARSETYPE_H #define PARSETYPE_H extern int parsetype(char *,char *); #endif tinydyndns-0.4.2.debian1/pickdns-conf.c000066400000000000000000000024571103424076200177530ustar00rootroot00000000000000#include #include #include "strerr.h" #include "exit.h" #include "auto_home.h" #include "generic-conf.h" #define FATAL "pickdns-conf: fatal: " void usage(void) { strerr_die1x(100,"pickdns-conf: usage: pickdns-conf acct logacct /pickdns myip"); } char *dir; char *user; char *loguser; struct passwd *pw; char *myip; int main(int argc,char **argv) { user = argv[1]; if (!user) usage(); loguser = argv[2]; if (!loguser) usage(); dir = argv[3]; if (!dir) usage(); if (dir[0] != '/') usage(); myip = argv[4]; if (!myip) usage(); pw = getpwnam(loguser); if (!pw) strerr_die3x(111,FATAL,"unknown account ",loguser); init(dir,FATAL); makelog(loguser,pw->pw_uid,pw->pw_gid); makedir("env"); perm(02755); start("env/ROOT"); outs(dir); outs("/root\n"); finish(); perm(0644); start("env/IP"); outs(myip); outs("\n"); finish(); perm(0644); start("run"); outs("#!/bin/sh\nexec 2>&1\nexec envuidgid "); outs(user); outs(" envdir ./env softlimit -d250000 "); outs(auto_home); outs("/bin/pickdns\n"); finish(); perm(0755); makedir("root"); perm(02755); start("root/data"); finish(); perm(0644); start("root/Makefile"); outs("data.cdb: data\n"); outs("\t"); outs(auto_home); outs("/bin/pickdns-data\n"); finish(); perm(0644); _exit(0); } tinydyndns-0.4.2.debian1/pickdns-data.c000066400000000000000000000121261103424076200177310ustar00rootroot00000000000000#include #include #include #include #include "buffer.h" #include "exit.h" #include "cdb_make.h" #include "open.h" #include "alloc.h" #include "gen_allocdefs.h" #include "stralloc.h" #include "getln.h" #include "case.h" #include "strerr.h" #include "str.h" #include "byte.h" #include "scan.h" #include "fmt.h" #include "ip4.h" #include "dns.h" #define FATAL "pickdns-data: fatal: " void nomem(void) { strerr_die2x(111,FATAL,"out of memory"); } void ipprefix_cat(stralloc *out,char *s) { unsigned long u; char ch; unsigned int j; for (;;) if (*s == '.') ++s; else { j = scan_ulong(s,&u); if (!j) return; s += j; ch = u; if (!stralloc_catb(out,&ch,1)) nomem(); } } struct address { char *name; unsigned int namelen; char ip[4]; char location[2]; } ; int address_diff(struct address *p,struct address *q) { int r; r = byte_diff(p->location,2,q->location); if (r < 0) return -1; if (r > 0) return 1; if (p->namelen < q->namelen) return -1; if (p->namelen > q->namelen) return 1; return case_diffb(p->name,p->namelen,q->name); } void address_sort(struct address *z,unsigned int n) { unsigned int i; unsigned int j; unsigned int p; unsigned int q; struct address t; i = j = n; --z; while (j > 1) { if (i > 1) { --i; t = z[i]; } else { t = z[j]; z[j] = z[i]; --j; } q = i; while ((p = q * 2) < j) { if (address_diff(&z[p + 1],&z[p]) >= 0) ++p; z[q] = z[p]; q = p; } if (p == j) { z[q] = z[p]; q = p; } while ((q > i) && (address_diff(&t,&z[p = q/2]) > 0)) { z[q] = z[p]; q = p; } z[q] = t; } } GEN_ALLOC_typedef(address_alloc,struct address,s,len,a) GEN_ALLOC_readyplus(address_alloc,struct address,s,len,a,i,n,x,30,address_alloc_readyplus) GEN_ALLOC_append(address_alloc,struct address,s,len,a,i,n,x,30,address_alloc_readyplus,address_alloc_append) static address_alloc x; int fd; buffer b; char bspace[1024]; int fdcdb; struct cdb_make cdb; static stralloc key; static stralloc result; static stralloc line; int match = 1; unsigned long linenum = 0; #define NUMFIELDS 3 static stralloc f[NUMFIELDS]; char strnum[FMT_ULONG]; void syntaxerror(const char *why) { strnum[fmt_ulong(strnum,linenum)] = 0; strerr_die4x(111,FATAL,"unable to parse data line ",strnum,why); } void die_datatmp(void) { strerr_die2sys(111,FATAL,"unable to create data.tmp: "); } int main() { struct address t; int i; int j; int k; char ch; umask(022); if (!address_alloc_readyplus(&x,0)) nomem(); fd = open_read("data"); if (fd == -1) strerr_die2sys(111,FATAL,"unable to open data: "); buffer_init(&b,buffer_unixread,fd,bspace,sizeof bspace); fdcdb = open_trunc("data.tmp"); if (fdcdb == -1) die_datatmp(); if (cdb_make_start(&cdb,fdcdb) == -1) die_datatmp(); while (match) { ++linenum; if (getln(&b,&line,&match,'\n') == -1) strerr_die2sys(111,FATAL,"unable to read line: "); while (line.len) { ch = line.s[line.len - 1]; if ((ch != ' ') && (ch != '\t') && (ch != '\n')) break; --line.len; } if (!line.len) continue; j = 1; for (i = 0;i < NUMFIELDS;++i) { if (j >= line.len) { if (!stralloc_copys(&f[i],"")) nomem(); } else { k = byte_chr(line.s + j,line.len - j,':'); if (!stralloc_copyb(&f[i],line.s + j,k)) nomem(); j += k + 1; } } switch(line.s[0]) { default: syntaxerror(": unrecognized leading character"); case '#': break; case '-': break; case '+': byte_zero(&t,sizeof t); if (!dns_domain_fromdot(&t.name,f[0].s,f[0].len)) nomem(); t.namelen = dns_domain_length(t.name); case_lowerb(t.name,t.namelen); if (!stralloc_0(&f[1])) nomem(); if (!ip4_scan(f[1].s,t.ip)) syntaxerror(": malformed IP address"); if (!stralloc_0(&f[2])) nomem(); if (!stralloc_0(&f[2])) nomem(); byte_copy(t.location,2,f[2].s); if (!address_alloc_append(&x,&t)) nomem(); break; case '%': if (!stralloc_0(&f[0])) nomem(); if (!stralloc_0(&f[0])) nomem(); if (!stralloc_copyb(&result,f[0].s,2)) nomem(); if (!stralloc_0(&f[1])) nomem(); if (!stralloc_copys(&key,"%")) nomem(); ipprefix_cat(&key,f[1].s); if (cdb_make_add(&cdb,key.s,key.len,result.s,result.len) == -1) die_datatmp(); break; } } close(fd); address_sort(x.s,x.len); i = 0; while (i < x.len) { for (j = i + 1;j < x.len;++j) if (address_diff(x.s + i,x.s + j)) break; if (!stralloc_copys(&key,"+")) nomem(); if (!stralloc_catb(&key,x.s[i].location,2)) nomem(); if (!stralloc_catb(&key,x.s[i].name,x.s[i].namelen)) nomem(); if (!stralloc_copys(&result,"")) nomem(); while (i < j) if (!stralloc_catb(&result,x.s[i++].ip,4)) nomem(); if (cdb_make_add(&cdb,key.s,key.len,result.s,result.len) == -1) die_datatmp(); } if (cdb_make_finish(&cdb) == -1) die_datatmp(); if (fsync(fdcdb) == -1) die_datatmp(); if (close(fdcdb) == -1) die_datatmp(); /* NFS stupidity */ if (rename("data.tmp","data.cdb") == -1) strerr_die2sys(111,FATAL,"unable to move data.tmp to data.cdb: "); _exit(0); } tinydyndns-0.4.2.debian1/pickdns.c000066400000000000000000000037371103424076200170320ustar00rootroot00000000000000#include #include "byte.h" #include "case.h" #include "dns.h" #include "open.h" #include "cdb.h" #include "response.h" const char *fatal = "pickdns: fatal: "; const char *starting = "starting pickdns\n"; static char seed[128]; void initialize(void) { dns_random_init(seed); } static struct cdb c; static char key[258]; static char data[512]; static int doit(char *q,char qtype[2],char ip[4]) { int r; uint32 dlen; unsigned int qlen; int flaga; int flagmx; qlen = dns_domain_length(q); if (qlen > 255) return 0; /* impossible */ flaga = byte_equal(qtype,2,DNS_T_A); flagmx = byte_equal(qtype,2,DNS_T_MX); if (byte_equal(qtype,2,DNS_T_ANY)) flaga = flagmx = 1; if (!flaga && !flagmx) goto REFUSE; key[0] = '%'; byte_copy(key + 1,4,ip); r = cdb_find(&c,key,5); if (!r) r = cdb_find(&c,key,4); if (!r) r = cdb_find(&c,key,3); if (!r) r = cdb_find(&c,key,2); if (r == -1) return 0; key[0] = '+'; byte_zero(key + 1,2); if (r && (cdb_datalen(&c) == 2)) if (cdb_read(&c,key + 1,2,cdb_datapos(&c)) == -1) return 0; byte_copy(key + 3,qlen,q); case_lowerb(key + 3,qlen + 3); r = cdb_find(&c,key,qlen + 3); if (!r) { byte_zero(key + 1,2); r = cdb_find(&c,key,qlen + 3); } if (!r) goto REFUSE; if (r == -1) return 0; dlen = cdb_datalen(&c); if (dlen > 512) dlen = 512; if (cdb_read(&c,data,dlen,cdb_datapos(&c)) == -1) return 0; if (flaga) { dns_sortip(data,dlen); if (dlen > 12) dlen = 12; while (dlen >= 4) { dlen -= 4; if (!response_rstart(q,DNS_T_A,5)) return 0; if (!response_addbytes(data + dlen,4)) return 0; response_rfinish(RESPONSE_ANSWER); } } return 1; REFUSE: response[2] &= ~4; response[3] &= ~15; response[3] |= 5; return 1; } int respond(char *q,char qtype[2],char ip[4]) { int fd; int result; fd = open_read("data.cdb"); if (fd == -1) return 0; cdb_init(&c,fd); result = doit(q,qtype,ip); cdb_free(&c); close(fd); return result; } tinydyndns-0.4.2.debian1/printpacket.c000066400000000000000000000040541103424076200177140ustar00rootroot00000000000000#include "uint16.h" #include "uint32.h" #include "error.h" #include "byte.h" #include "dns.h" #include "printrecord.h" #include "printpacket.h" static char *d; #define X(s) if (!stralloc_cats(out,s)) return 0; #define NUM(u) if (!stralloc_catulong0(out,u,0)) return 0; unsigned int printpacket_cat(stralloc *out,char *buf,unsigned int len) { uint16 numqueries; uint16 numanswers; uint16 numauthority; uint16 numglue; unsigned int pos; char data[12]; uint16 type; pos = dns_packet_copy(buf,len,0,data,12); if (!pos) return 0; uint16_unpack_big(data + 4,&numqueries); uint16_unpack_big(data + 6,&numanswers); uint16_unpack_big(data + 8,&numauthority); uint16_unpack_big(data + 10,&numglue); NUM(len) X(" bytes, ") NUM(numqueries) X("+") NUM(numanswers) X("+") NUM(numauthority) X("+") NUM(numglue) X(" records") if (data[2] & 128) X(", response") if (data[2] & 120) X(", weird op") if (data[2] & 4) X(", authoritative") if (data[2] & 2) X(", truncated") if (data[2] & 1) X(", weird rd") if (data[3] & 128) X(", weird ra") switch(data[3] & 15) { case 0: X(", noerror"); break; case 3: X(", nxdomain"); break; case 4: X(", notimp"); break; case 5: X(", refused"); break; default: X(", weird rcode"); } if (data[3] & 112) X(", weird z") X("\n") while (numqueries) { --numqueries; X("query: ") pos = dns_packet_getname(buf,len,pos,&d); if (!pos) return 0; pos = dns_packet_copy(buf,len,pos,data,4); if (!pos) return 0; if (byte_diff(data + 2,2,DNS_C_IN)) { X("weird class") } else { uint16_unpack_big(data,&type); NUM(type) X(" ") if (!dns_domain_todot_cat(out,d)) return 0; } X("\n") } for (;;) { if (numanswers) { --numanswers; X("answer: ") } else if (numauthority) { --numauthority; X("authority: ") } else if (numglue) { --numglue; X("additional: ") } else break; pos = printrecord_cat(out,buf,len,pos,0,0); if (!pos) return 0; } if (pos != len) { errno = error_proto; return 0; } return 1; } tinydyndns-0.4.2.debian1/printpacket.h000066400000000000000000000002211103424076200177110ustar00rootroot00000000000000#ifndef PRINTPACKET_H #define PRINTPACKET_H #include "stralloc.h" extern unsigned int printpacket_cat(stralloc *,char *,unsigned int); #endif tinydyndns-0.4.2.debian1/printrecord.c000066400000000000000000000072331103424076200177250ustar00rootroot00000000000000#include "uint16.h" #include "uint32.h" #include "error.h" #include "byte.h" #include "dns.h" #include "printrecord.h" static char *d; unsigned int printrecord_cat(stralloc *out,const char *buf,unsigned int len,unsigned int pos,const char *q,const char qtype[2]) { const char *x; char misc[20]; uint16 datalen; uint16 u16; uint32 u32; unsigned int newpos; int i; unsigned char ch; pos = dns_packet_getname(buf,len,pos,&d); if (!pos) return 0; pos = dns_packet_copy(buf,len,pos,misc,10); if (!pos) return 0; uint16_unpack_big(misc + 8,&datalen); newpos = pos + datalen; if (q) { if (!dns_domain_equal(d,q)) return newpos; if (byte_diff(qtype,2,misc) && byte_diff(qtype,2,DNS_T_ANY)) return newpos; } if (!dns_domain_todot_cat(out,d)) return 0; if (!stralloc_cats(out," ")) return 0; uint32_unpack_big(misc + 4,&u32); if (!stralloc_catulong0(out,u32,0)) return 0; if (byte_diff(misc + 2,2,DNS_C_IN)) { if (!stralloc_cats(out," weird class\n")) return 0; return newpos; } x = 0; if (byte_equal(misc,2,DNS_T_NS)) x = " NS "; if (byte_equal(misc,2,DNS_T_PTR)) x = " PTR "; if (byte_equal(misc,2,DNS_T_CNAME)) x = " CNAME "; if (x) { pos = dns_packet_getname(buf,len,pos,&d); if (!pos) return 0; if (!stralloc_cats(out,x)) return 0; if (!dns_domain_todot_cat(out,d)) return 0; } else if (byte_equal(misc,2,DNS_T_MX)) { if (!stralloc_cats(out," MX ")) return 0; pos = dns_packet_copy(buf,len,pos,misc,2); if (!pos) return 0; pos = dns_packet_getname(buf,len,pos,&d); if (!pos) return 0; uint16_unpack_big(misc,&u16); if (!stralloc_catulong0(out,u16,0)) return 0; if (!stralloc_cats(out," ")) return 0; if (!dns_domain_todot_cat(out,d)) return 0; } else if (byte_equal(misc,2,DNS_T_SOA)) { if (!stralloc_cats(out," SOA ")) return 0; pos = dns_packet_getname(buf,len,pos,&d); if (!pos) return 0; if (!dns_domain_todot_cat(out,d)) return 0; if (!stralloc_cats(out," ")) return 0; pos = dns_packet_getname(buf,len,pos,&d); if (!pos) return 0; if (!dns_domain_todot_cat(out,d)) return 0; pos = dns_packet_copy(buf,len,pos,misc,20); if (!pos) return 0; for (i = 0;i < 5;++i) { if (!stralloc_cats(out," ")) return 0; uint32_unpack_big(misc + 4 * i,&u32); if (!stralloc_catulong0(out,u32,0)) return 0; } } else if (byte_equal(misc,2,DNS_T_A)) { if (datalen != 4) { errno = error_proto; return 0; } if (!stralloc_cats(out," A ")) return 0; pos = dns_packet_copy(buf,len,pos,misc,4); if (!pos) return 0; for (i = 0;i < 4;++i) { ch = misc[i]; if (i) if (!stralloc_cats(out,".")) return 0; if (!stralloc_catulong0(out,ch,0)) return 0; } } else { if (!stralloc_cats(out," ")) return 0; uint16_unpack_big(misc,&u16); if (!stralloc_catulong0(out,u16,0)) return 0; if (!stralloc_cats(out," ")) return 0; while (datalen--) { pos = dns_packet_copy(buf,len,pos,misc,1); if (!pos) return 0; if ((misc[0] >= 33) && (misc[0] <= 126) && (misc[0] != '\\')) { if (!stralloc_catb(out,misc,1)) return 0; } else { ch = misc[0]; misc[3] = '0' + (7 & ch); ch >>= 3; misc[2] = '0' + (7 & ch); ch >>= 3; misc[1] = '0' + (7 & ch); misc[0] = '\\'; if (!stralloc_catb(out,misc,4)) return 0; } } } if (!stralloc_cats(out,"\n")) return 0; if (pos != newpos) { errno = error_proto; return 0; } return newpos; } unsigned int printrecord(stralloc *out,const char *buf,unsigned int len,unsigned int pos,const char *q,const char qtype[2]) { if (!stralloc_copys(out,"")) return 0; return printrecord_cat(out,buf,len,pos,q,qtype); } tinydyndns-0.4.2.debian1/printrecord.h000066400000000000000000000004541103424076200177300ustar00rootroot00000000000000#ifndef PRINTRECORD_H #define PRINTRECORD_H #include "stralloc.h" extern unsigned int printrecord_cat(stralloc *,const char *,unsigned int,unsigned int,const char *,const char *); extern unsigned int printrecord(stralloc *,const char *,unsigned int,unsigned int,const char *,const char *); #endif tinydyndns-0.4.2.debian1/prot.c000066400000000000000000000005651103424076200163570ustar00rootroot00000000000000#include "hasshsgr.h" #include "prot.h" int prot_gid(int gid) { #ifdef HASSHORTSETGROUPS short x[2]; x[0] = gid; x[1] = 73; /* catch errors */ if (setgroups(1,x) == -1) return -1; #else if (setgroups(1,&gid) == -1) return -1; #endif return setgid(gid); /* _should_ be redundant, but on some systems it isn't */ } int prot_uid(int uid) { return setuid(uid); } tinydyndns-0.4.2.debian1/prot.h000066400000000000000000000001331103424076200163530ustar00rootroot00000000000000#ifndef PROT_H #define PROT_H extern int prot_gid(int); extern int prot_uid(int); #endif tinydyndns-0.4.2.debian1/qlog.c000066400000000000000000000021271103424076200163310ustar00rootroot00000000000000#include "buffer.h" #include "qlog.h" static void put(char c) { buffer_put(buffer_2,&c,1); } static void hex(unsigned char c) { put("0123456789abcdef"[(c >> 4) & 15]); put("0123456789abcdef"[c & 15]); } static void octal(unsigned char c) { put('\\'); put('0' + ((c >> 6) & 7)); put('0' + ((c >> 3) & 7)); put('0' + (c & 7)); } void qlog(const char ip[4],uint16 port,const char id[2],const char *q,const char qtype[2],const char *result) { char ch; char ch2; hex(ip[0]); hex(ip[1]); hex(ip[2]); hex(ip[3]); put(':'); hex(port >> 8); hex(port & 255); put(':'); hex(id[0]); hex(id[1]); buffer_puts(buffer_2,result); hex(qtype[0]); hex(qtype[1]); put(' '); if (!*q) put('.'); else for (;;) { ch = *q++; while (ch--) { ch2 = *q++; if ((ch2 >= 'A') && (ch2 <= 'Z')) ch2 += 32; if (((ch2 >= 'a') && (ch2 <= 'z')) || ((ch2 >= '0') && (ch2 <= '9')) || (ch2 == '-') || (ch2 == '_')) put(ch2); else octal(ch2); } if (!*q) break; put('.'); } put('\n'); buffer_flush(buffer_2); } tinydyndns-0.4.2.debian1/qlog.h000066400000000000000000000002271103424076200163350ustar00rootroot00000000000000#ifndef QLOG_H #define QLOG_H #include "uint16.h" extern void qlog(const char *,uint16,const char *,const char *,const char *,const char *); #endif tinydyndns-0.4.2.debian1/query.c000066400000000000000000000560701103424076200165420ustar00rootroot00000000000000#include "error.h" #include "roots.h" #include "log.h" #include "case.h" #include "cache.h" #include "byte.h" #include "dns.h" #include "uint64.h" #include "uint32.h" #include "uint16.h" #include "dd.h" #include "alloc.h" #include "response.h" #include "query.h" static int flagforwardonly = 0; void query_forwardonly(void) { flagforwardonly = 1; } static void cachegeneric(const char type[2],const char *d,const char *data,unsigned int datalen,uint32 ttl) { unsigned int len; char key[257]; len = dns_domain_length(d); if (len > 255) return; byte_copy(key,2,type); byte_copy(key + 2,len,d); case_lowerb(key + 2,len); cache_set(key,len + 2,data,datalen,ttl); } static char save_buf[8192]; static unsigned int save_len; static unsigned int save_ok; static void save_start(void) { save_len = 0; save_ok = 1; } static void save_data(const char *buf,unsigned int len) { if (!save_ok) return; if (len > (sizeof save_buf) - save_len) { save_ok = 0; return; } byte_copy(save_buf + save_len,len,buf); save_len += len; } static void save_finish(const char type[2],const char *d,uint32 ttl) { if (!save_ok) return; cachegeneric(type,d,save_buf,save_len,ttl); } static int typematch(const char rtype[2],const char qtype[2]) { return byte_equal(qtype,2,rtype) || byte_equal(qtype,2,DNS_T_ANY); } static uint32 ttlget(char buf[4]) { uint32 ttl; uint32_unpack_big(buf,&ttl); if (ttl > 1000000000) return 0; if (ttl > 604800) return 604800; return ttl; } static void cleanup(struct query *z) { int j; int k; dns_transmit_free(&z->dt); for (j = 0;j < QUERY_MAXALIAS;++j) dns_domain_free(&z->alias[j]); for (j = 0;j < QUERY_MAXLEVEL;++j) { dns_domain_free(&z->name[j]); for (k = 0;k < QUERY_MAXNS;++k) dns_domain_free(&z->ns[j][k]); } } static int rqa(struct query *z) { int i; for (i = QUERY_MAXALIAS - 1;i >= 0;--i) if (z->alias[i]) { if (!response_query(z->alias[i],z->type,z->class)) return 0; while (i > 0) { if (!response_cname(z->alias[i],z->alias[i - 1],z->aliasttl[i])) return 0; --i; } if (!response_cname(z->alias[0],z->name[0],z->aliasttl[0])) return 0; return 1; } if (!response_query(z->name[0],z->type,z->class)) return 0; return 1; } static int globalip(char *d,char ip[4]) { if (dns_domain_equal(d,"\011localhost\0")) { byte_copy(ip,4,"\177\0\0\1"); return 1; } if (dd(d,"",ip) == 4) return 1; return 0; } static char *t1 = 0; static char *t2 = 0; static char *t3 = 0; static char *cname = 0; static char *referral = 0; static unsigned int *records = 0; static int smaller(char *buf,unsigned int len,unsigned int pos1,unsigned int pos2) { char header1[12]; char header2[12]; int r; unsigned int len1; unsigned int len2; pos1 = dns_packet_getname(buf,len,pos1,&t1); dns_packet_copy(buf,len,pos1,header1,10); pos2 = dns_packet_getname(buf,len,pos2,&t2); dns_packet_copy(buf,len,pos2,header2,10); r = byte_diff(header1,4,header2); if (r < 0) return 1; if (r > 0) return 0; len1 = dns_domain_length(t1); len2 = dns_domain_length(t2); if (len1 < len2) return 1; if (len1 > len2) return 0; r = case_diffb(t1,len1,t2); if (r < 0) return 1; if (r > 0) return 0; if (pos1 < pos2) return 1; return 0; } static int doit(struct query *z,int state) { char key[257]; char *cached; unsigned int cachedlen; char *buf; unsigned int len; const char *whichserver; char header[12]; char misc[20]; unsigned int rcode; unsigned int posanswers; uint16 numanswers; unsigned int posauthority; uint16 numauthority; unsigned int posglue; uint16 numglue; unsigned int pos; unsigned int pos2; uint16 datalen; char *control; char *d; const char *dtype; unsigned int dlen; int flagout; int flagcname; int flagreferral; int flagsoa; uint32 ttl; uint32 soattl; uint32 cnamettl; int i; int j; int k; int p; int q; errno = error_io; if (state == 1) goto HAVEPACKET; if (state == -1) { log_servfail(z->name[z->level]); goto SERVFAIL; } NEWNAME: if (++z->loop == 100) goto DIE; d = z->name[z->level]; dtype = z->level ? DNS_T_A : z->type; dlen = dns_domain_length(d); if (globalip(d,misc)) { if (z->level) { for (k = 0;k < 64;k += 4) if (byte_equal(z->servers[z->level - 1] + k,4,"\0\0\0\0")) { byte_copy(z->servers[z->level - 1] + k,4,misc); break; } goto LOWERLEVEL; } if (!rqa(z)) goto DIE; if (typematch(DNS_T_A,dtype)) { if (!response_rstart(d,DNS_T_A,655360)) goto DIE; if (!response_addbytes(misc,4)) goto DIE; response_rfinish(RESPONSE_ANSWER); } cleanup(z); return 1; } if (dns_domain_equal(d,"\0011\0010\0010\003127\7in-addr\4arpa\0")) { if (z->level) goto LOWERLEVEL; if (!rqa(z)) goto DIE; if (typematch(DNS_T_PTR,dtype)) { if (!response_rstart(d,DNS_T_PTR,655360)) goto DIE; if (!response_addname("\011localhost\0")) goto DIE; response_rfinish(RESPONSE_ANSWER); } cleanup(z); log_stats(); return 1; } if (dlen <= 255) { byte_copy(key,2,DNS_T_ANY); byte_copy(key + 2,dlen,d); case_lowerb(key + 2,dlen); cached = cache_get(key,dlen + 2,&cachedlen,&ttl); if (cached) { log_cachednxdomain(d); goto NXDOMAIN; } byte_copy(key,2,DNS_T_CNAME); cached = cache_get(key,dlen + 2,&cachedlen,&ttl); if (cached) { if (typematch(DNS_T_CNAME,dtype)) { log_cachedanswer(d,DNS_T_CNAME); if (!rqa(z)) goto DIE; if (!response_cname(z->name[0],cached,ttl)) goto DIE; cleanup(z); return 1; } log_cachedcname(d,cached); if (!dns_domain_copy(&cname,cached)) goto DIE; goto CNAME; } if (typematch(DNS_T_NS,dtype)) { byte_copy(key,2,DNS_T_NS); cached = cache_get(key,dlen + 2,&cachedlen,&ttl); if (cached && (cachedlen || byte_diff(dtype,2,DNS_T_ANY))) { log_cachedanswer(d,DNS_T_NS); if (!rqa(z)) goto DIE; pos = 0; while (pos = dns_packet_getname(cached,cachedlen,pos,&t2)) { if (!response_rstart(d,DNS_T_NS,ttl)) goto DIE; if (!response_addname(t2)) goto DIE; response_rfinish(RESPONSE_ANSWER); } cleanup(z); return 1; } } if (typematch(DNS_T_PTR,dtype)) { byte_copy(key,2,DNS_T_PTR); cached = cache_get(key,dlen + 2,&cachedlen,&ttl); if (cached && (cachedlen || byte_diff(dtype,2,DNS_T_ANY))) { log_cachedanswer(d,DNS_T_PTR); if (!rqa(z)) goto DIE; pos = 0; while (pos = dns_packet_getname(cached,cachedlen,pos,&t2)) { if (!response_rstart(d,DNS_T_PTR,ttl)) goto DIE; if (!response_addname(t2)) goto DIE; response_rfinish(RESPONSE_ANSWER); } cleanup(z); return 1; } } if (typematch(DNS_T_MX,dtype)) { byte_copy(key,2,DNS_T_MX); cached = cache_get(key,dlen + 2,&cachedlen,&ttl); if (cached && (cachedlen || byte_diff(dtype,2,DNS_T_ANY))) { log_cachedanswer(d,DNS_T_MX); if (!rqa(z)) goto DIE; pos = 0; while (pos = dns_packet_copy(cached,cachedlen,pos,misc,2)) { pos = dns_packet_getname(cached,cachedlen,pos,&t2); if (!pos) break; if (!response_rstart(d,DNS_T_MX,ttl)) goto DIE; if (!response_addbytes(misc,2)) goto DIE; if (!response_addname(t2)) goto DIE; response_rfinish(RESPONSE_ANSWER); } cleanup(z); return 1; } } if (typematch(DNS_T_A,dtype)) { byte_copy(key,2,DNS_T_A); cached = cache_get(key,dlen + 2,&cachedlen,&ttl); if (cached && (cachedlen || byte_diff(dtype,2,DNS_T_ANY))) { if (z->level) { log_cachedanswer(d,DNS_T_A); while (cachedlen >= 4) { for (k = 0;k < 64;k += 4) if (byte_equal(z->servers[z->level - 1] + k,4,"\0\0\0\0")) { byte_copy(z->servers[z->level - 1] + k,4,cached); break; } cached += 4; cachedlen -= 4; } goto LOWERLEVEL; } log_cachedanswer(d,DNS_T_A); if (!rqa(z)) goto DIE; while (cachedlen >= 4) { if (!response_rstart(d,DNS_T_A,ttl)) goto DIE; if (!response_addbytes(cached,4)) goto DIE; response_rfinish(RESPONSE_ANSWER); cached += 4; cachedlen -= 4; } cleanup(z); return 1; } } if (!typematch(DNS_T_ANY,dtype) && !typematch(DNS_T_AXFR,dtype) && !typematch(DNS_T_CNAME,dtype) && !typematch(DNS_T_NS,dtype) && !typematch(DNS_T_PTR,dtype) && !typematch(DNS_T_A,dtype) && !typematch(DNS_T_MX,dtype)) { byte_copy(key,2,dtype); cached = cache_get(key,dlen + 2,&cachedlen,&ttl); if (cached && (cachedlen || byte_diff(dtype,2,DNS_T_ANY))) { log_cachedanswer(d,dtype); if (!rqa(z)) goto DIE; while (cachedlen >= 2) { uint16_unpack_big(cached,&datalen); cached += 2; cachedlen -= 2; if (datalen > cachedlen) goto DIE; if (!response_rstart(d,dtype,ttl)) goto DIE; if (!response_addbytes(cached,datalen)) goto DIE; response_rfinish(RESPONSE_ANSWER); cached += datalen; cachedlen -= datalen; } cleanup(z); return 1; } } } for (;;) { if (roots(z->servers[z->level],d)) { for (j = 0;j < QUERY_MAXNS;++j) dns_domain_free(&z->ns[z->level][j]); z->control[z->level] = d; break; } if (!flagforwardonly && (z->level < 2)) if (dlen < 255) { byte_copy(key,2,DNS_T_NS); byte_copy(key + 2,dlen,d); case_lowerb(key + 2,dlen); cached = cache_get(key,dlen + 2,&cachedlen,&ttl); if (cached && cachedlen) { z->control[z->level] = d; byte_zero(z->servers[z->level],64); for (j = 0;j < QUERY_MAXNS;++j) dns_domain_free(&z->ns[z->level][j]); pos = 0; j = 0; while (pos = dns_packet_getname(cached,cachedlen,pos,&t1)) { log_cachedns(d,t1); if (j < QUERY_MAXNS) if (!dns_domain_copy(&z->ns[z->level][j++],t1)) goto DIE; } break; } } if (!*d) goto DIE; j = 1 + (unsigned int) (unsigned char) *d; dlen -= j; d += j; } HAVENS: for (j = 0;j < QUERY_MAXNS;++j) if (z->ns[z->level][j]) { if (z->level + 1 < QUERY_MAXLEVEL) { if (!dns_domain_copy(&z->name[z->level + 1],z->ns[z->level][j])) goto DIE; dns_domain_free(&z->ns[z->level][j]); ++z->level; goto NEWNAME; } dns_domain_free(&z->ns[z->level][j]); } for (j = 0;j < 64;j += 4) if (byte_diff(z->servers[z->level] + j,4,"\0\0\0\0")) break; if (j == 64) goto SERVFAIL; dns_sortip(z->servers[z->level],64); if (z->level) { log_tx(z->name[z->level],DNS_T_A,z->control[z->level],z->servers[z->level],z->level); if (dns_transmit_start(&z->dt,z->servers[z->level],flagforwardonly,z->name[z->level],DNS_T_A,z->localip) == -1) goto DIE; } else { log_tx(z->name[0],z->type,z->control[0],z->servers[0],0); if (dns_transmit_start(&z->dt,z->servers[0],flagforwardonly,z->name[0],z->type,z->localip) == -1) goto DIE; } return 0; LOWERLEVEL: dns_domain_free(&z->name[z->level]); for (j = 0;j < QUERY_MAXNS;++j) dns_domain_free(&z->ns[z->level][j]); --z->level; goto HAVENS; HAVEPACKET: if (++z->loop == 100) goto DIE; buf = z->dt.packet; len = z->dt.packetlen; whichserver = z->dt.servers + 4 * z->dt.curserver; control = z->control[z->level]; d = z->name[z->level]; dtype = z->level ? DNS_T_A : z->type; pos = dns_packet_copy(buf,len,0,header,12); if (!pos) goto DIE; pos = dns_packet_skipname(buf,len,pos); if (!pos) goto DIE; pos += 4; posanswers = pos; uint16_unpack_big(header + 6,&numanswers); uint16_unpack_big(header + 8,&numauthority); uint16_unpack_big(header + 10,&numglue); rcode = header[3] & 15; if (rcode && (rcode != 3)) goto DIE; /* impossible; see irrelevant() */ flagout = 0; flagcname = 0; flagreferral = 0; flagsoa = 0; soattl = 0; cnamettl = 0; for (j = 0;j < numanswers;++j) { pos = dns_packet_getname(buf,len,pos,&t1); if (!pos) goto DIE; pos = dns_packet_copy(buf,len,pos,header,10); if (!pos) goto DIE; if (dns_domain_equal(t1,d)) if (byte_equal(header + 2,2,DNS_C_IN)) { /* should always be true */ if (typematch(header,dtype)) flagout = 1; else if (typematch(header,DNS_T_CNAME)) { if (!dns_packet_getname(buf,len,pos,&cname)) goto DIE; flagcname = 1; cnamettl = ttlget(header + 4); } } uint16_unpack_big(header + 8,&datalen); pos += datalen; } posauthority = pos; for (j = 0;j < numauthority;++j) { pos = dns_packet_getname(buf,len,pos,&t1); if (!pos) goto DIE; pos = dns_packet_copy(buf,len,pos,header,10); if (!pos) goto DIE; if (typematch(header,DNS_T_SOA)) { flagsoa = 1; soattl = ttlget(header + 4); if (soattl > 3600) soattl = 3600; } else if (typematch(header,DNS_T_NS)) { flagreferral = 1; if (!dns_domain_copy(&referral,t1)) goto DIE; } uint16_unpack_big(header + 8,&datalen); pos += datalen; } posglue = pos; if (!flagcname && !rcode && !flagout && flagreferral && !flagsoa) if (dns_domain_equal(referral,control) || !dns_domain_suffix(referral,control)) { log_lame(whichserver,control,referral); byte_zero(whichserver,4); goto HAVENS; } if (records) { alloc_free(records); records = 0; } k = numanswers + numauthority + numglue; records = (unsigned int *) alloc(k * sizeof(unsigned int)); if (!records) goto DIE; pos = posanswers; for (j = 0;j < k;++j) { records[j] = pos; pos = dns_packet_getname(buf,len,pos,&t1); if (!pos) goto DIE; pos = dns_packet_copy(buf,len,pos,header,10); if (!pos) goto DIE; uint16_unpack_big(header + 8,&datalen); pos += datalen; } i = j = k; while (j > 1) { if (i > 1) { --i; pos = records[i - 1]; } else { pos = records[j - 1]; records[j - 1] = records[i - 1]; --j; } q = i; while ((p = q * 2) < j) { if (!smaller(buf,len,records[p],records[p - 1])) ++p; records[q - 1] = records[p - 1]; q = p; } if (p == j) { records[q - 1] = records[p - 1]; q = p; } while ((q > i) && smaller(buf,len,records[(p = q/2) - 1],pos)) { records[q - 1] = records[p - 1]; q = p; } records[q - 1] = pos; } i = 0; while (i < k) { char type[2]; pos = dns_packet_getname(buf,len,records[i],&t1); if (!pos) goto DIE; pos = dns_packet_copy(buf,len,pos,header,10); if (!pos) goto DIE; ttl = ttlget(header + 4); byte_copy(type,2,header); if (byte_diff(header + 2,2,DNS_C_IN)) { ++i; continue; } for (j = i + 1;j < k;++j) { pos = dns_packet_getname(buf,len,records[j],&t2); if (!pos) goto DIE; pos = dns_packet_copy(buf,len,pos,header,10); if (!pos) goto DIE; if (!dns_domain_equal(t1,t2)) break; if (byte_diff(header,2,type)) break; if (byte_diff(header + 2,2,DNS_C_IN)) break; } if (!dns_domain_suffix(t1,control)) { i = j; continue; } if (!roots_same(t1,control)) { i = j; continue; } if (byte_equal(type,2,DNS_T_ANY)) ; else if (byte_equal(type,2,DNS_T_AXFR)) ; else if (byte_equal(type,2,DNS_T_SOA)) { while (i < j) { pos = dns_packet_skipname(buf,len,records[i]); if (!pos) goto DIE; pos = dns_packet_getname(buf,len,pos + 10,&t2); if (!pos) goto DIE; pos = dns_packet_getname(buf,len,pos,&t3); if (!pos) goto DIE; pos = dns_packet_copy(buf,len,pos,misc,20); if (!pos) goto DIE; if (records[i] < posauthority) log_rrsoa(whichserver,t1,t2,t3,misc,ttl); ++i; } } else if (byte_equal(type,2,DNS_T_CNAME)) { pos = dns_packet_skipname(buf,len,records[j - 1]); if (!pos) goto DIE; pos = dns_packet_getname(buf,len,pos + 10,&t2); if (!pos) goto DIE; log_rrcname(whichserver,t1,t2,ttl); cachegeneric(DNS_T_CNAME,t1,t2,dns_domain_length(t2),ttl); } else if (byte_equal(type,2,DNS_T_PTR)) { save_start(); while (i < j) { pos = dns_packet_skipname(buf,len,records[i]); if (!pos) goto DIE; pos = dns_packet_getname(buf,len,pos + 10,&t2); if (!pos) goto DIE; log_rrptr(whichserver,t1,t2,ttl); save_data(t2,dns_domain_length(t2)); ++i; } save_finish(DNS_T_PTR,t1,ttl); } else if (byte_equal(type,2,DNS_T_NS)) { save_start(); while (i < j) { pos = dns_packet_skipname(buf,len,records[i]); if (!pos) goto DIE; pos = dns_packet_getname(buf,len,pos + 10,&t2); if (!pos) goto DIE; log_rrns(whichserver,t1,t2,ttl); save_data(t2,dns_domain_length(t2)); ++i; } save_finish(DNS_T_NS,t1,ttl); } else if (byte_equal(type,2,DNS_T_MX)) { save_start(); while (i < j) { pos = dns_packet_skipname(buf,len,records[i]); if (!pos) goto DIE; pos = dns_packet_copy(buf,len,pos + 10,misc,2); if (!pos) goto DIE; pos = dns_packet_getname(buf,len,pos,&t2); if (!pos) goto DIE; log_rrmx(whichserver,t1,t2,misc,ttl); save_data(misc,2); save_data(t2,dns_domain_length(t2)); ++i; } save_finish(DNS_T_MX,t1,ttl); } else if (byte_equal(type,2,DNS_T_A)) { save_start(); while (i < j) { pos = dns_packet_skipname(buf,len,records[i]); if (!pos) goto DIE; pos = dns_packet_copy(buf,len,pos,header,10); if (!pos) goto DIE; if (byte_equal(header + 8,2,"\0\4")) { pos = dns_packet_copy(buf,len,pos,header,4); if (!pos) goto DIE; save_data(header,4); log_rr(whichserver,t1,DNS_T_A,header,4,ttl); } ++i; } save_finish(DNS_T_A,t1,ttl); } else { save_start(); while (i < j) { pos = dns_packet_skipname(buf,len,records[i]); if (!pos) goto DIE; pos = dns_packet_copy(buf,len,pos,header,10); if (!pos) goto DIE; uint16_unpack_big(header + 8,&datalen); if (datalen > len - pos) goto DIE; save_data(header + 8,2); save_data(buf + pos,datalen); log_rr(whichserver,t1,type,buf + pos,datalen,ttl); ++i; } save_finish(type,t1,ttl); } i = j; } alloc_free(records); records = 0; if (flagcname) { ttl = cnamettl; CNAME: if (!z->level) { if (z->alias[QUERY_MAXALIAS - 1]) goto DIE; for (j = QUERY_MAXALIAS - 1;j > 0;--j) z->alias[j] = z->alias[j - 1]; for (j = QUERY_MAXALIAS - 1;j > 0;--j) z->aliasttl[j] = z->aliasttl[j - 1]; z->alias[0] = z->name[0]; z->aliasttl[0] = ttl; z->name[0] = 0; } if (!dns_domain_copy(&z->name[z->level],cname)) goto DIE; goto NEWNAME; } if (rcode == 3) { log_nxdomain(whichserver,d,soattl); cachegeneric(DNS_T_ANY,d,"",0,soattl); NXDOMAIN: if (z->level) goto LOWERLEVEL; if (!rqa(z)) goto DIE; response_nxdomain(); cleanup(z); return 1; } if (!flagout && flagsoa) if (byte_diff(DNS_T_ANY,2,dtype)) if (byte_diff(DNS_T_AXFR,2,dtype)) if (byte_diff(DNS_T_CNAME,2,dtype)) { save_start(); save_finish(dtype,d,soattl); log_nodata(whichserver,d,dtype,soattl); } log_stats(); if (flagout || flagsoa || !flagreferral) { if (z->level) { pos = posanswers; for (j = 0;j < numanswers;++j) { pos = dns_packet_getname(buf,len,pos,&t1); if (!pos) goto DIE; pos = dns_packet_copy(buf,len,pos,header,10); if (!pos) goto DIE; uint16_unpack_big(header + 8,&datalen); if (dns_domain_equal(t1,d)) if (typematch(header,DNS_T_A)) if (byte_equal(header + 2,2,DNS_C_IN)) /* should always be true */ if (datalen == 4) for (k = 0;k < 64;k += 4) if (byte_equal(z->servers[z->level - 1] + k,4,"\0\0\0\0")) { if (!dns_packet_copy(buf,len,pos,z->servers[z->level - 1] + k,4)) goto DIE; break; } pos += datalen; } goto LOWERLEVEL; } if (!rqa(z)) goto DIE; pos = posanswers; for (j = 0;j < numanswers;++j) { pos = dns_packet_getname(buf,len,pos,&t1); if (!pos) goto DIE; pos = dns_packet_copy(buf,len,pos,header,10); if (!pos) goto DIE; ttl = ttlget(header + 4); uint16_unpack_big(header + 8,&datalen); if (dns_domain_equal(t1,d)) if (byte_equal(header + 2,2,DNS_C_IN)) /* should always be true */ if (typematch(header,dtype)) { if (!response_rstart(t1,header,ttl)) goto DIE; if (typematch(header,DNS_T_NS) || typematch(header,DNS_T_CNAME) || typematch(header,DNS_T_PTR)) { if (!dns_packet_getname(buf,len,pos,&t2)) goto DIE; if (!response_addname(t2)) goto DIE; } else if (typematch(header,DNS_T_MX)) { pos2 = dns_packet_copy(buf,len,pos,misc,2); if (!pos2) goto DIE; if (!response_addbytes(misc,2)) goto DIE; if (!dns_packet_getname(buf,len,pos2,&t2)) goto DIE; if (!response_addname(t2)) goto DIE; } else if (typematch(header,DNS_T_SOA)) { pos2 = dns_packet_getname(buf,len,pos,&t2); if (!pos2) goto DIE; if (!response_addname(t2)) goto DIE; pos2 = dns_packet_getname(buf,len,pos2,&t3); if (!pos2) goto DIE; if (!response_addname(t3)) goto DIE; pos2 = dns_packet_copy(buf,len,pos2,misc,20); if (!pos2) goto DIE; if (!response_addbytes(misc,20)) goto DIE; } else { if (pos + datalen > len) goto DIE; if (!response_addbytes(buf + pos,datalen)) goto DIE; } response_rfinish(RESPONSE_ANSWER); } pos += datalen; } cleanup(z); return 1; } if (!dns_domain_suffix(d,referral)) goto DIE; control = d + dns_domain_suffixpos(d,referral); z->control[z->level] = control; byte_zero(z->servers[z->level],64); for (j = 0;j < QUERY_MAXNS;++j) dns_domain_free(&z->ns[z->level][j]); k = 0; pos = posauthority; for (j = 0;j < numauthority;++j) { pos = dns_packet_getname(buf,len,pos,&t1); if (!pos) goto DIE; pos = dns_packet_copy(buf,len,pos,header,10); if (!pos) goto DIE; uint16_unpack_big(header + 8,&datalen); if (dns_domain_equal(referral,t1)) /* should always be true */ if (typematch(header,DNS_T_NS)) /* should always be true */ if (byte_equal(header + 2,2,DNS_C_IN)) /* should always be true */ if (k < QUERY_MAXNS) if (!dns_packet_getname(buf,len,pos,&z->ns[z->level][k++])) goto DIE; pos += datalen; } goto HAVENS; SERVFAIL: if (z->level) goto LOWERLEVEL; if (!rqa(z)) goto DIE; response_servfail(); cleanup(z); return 1; DIE: cleanup(z); if (records) { alloc_free(records); records = 0; } return -1; } int query_start(struct query *z,char *dn,char type[2],char class[2],char localip[4]) { if (byte_equal(type,2,DNS_T_AXFR)) { errno = error_perm; return -1; } cleanup(z); z->level = 0; z->loop = 0; if (!dns_domain_copy(&z->name[0],dn)) return -1; byte_copy(z->type,2,type); byte_copy(z->class,2,class); byte_copy(z->localip,4,localip); return doit(z,0); } int query_get(struct query *z,iopause_fd *x,struct taia *stamp) { switch(dns_transmit_get(&z->dt,x,stamp)) { case 1: return doit(z,1); case -1: return doit(z,-1); } return 0; } void query_io(struct query *z,iopause_fd *x,struct taia *deadline) { dns_transmit_io(&z->dt,x,deadline); } tinydyndns-0.4.2.debian1/query.h000066400000000000000000000013741103424076200165440ustar00rootroot00000000000000#ifndef QUERY_H #define QUERY_H #include "dns.h" #include "uint32.h" #define QUERY_MAXLEVEL 5 #define QUERY_MAXALIAS 16 #define QUERY_MAXNS 16 struct query { unsigned int loop; unsigned int level; char *name[QUERY_MAXLEVEL]; char *control[QUERY_MAXLEVEL]; /* pointing inside name */ char *ns[QUERY_MAXLEVEL][QUERY_MAXNS]; char servers[QUERY_MAXLEVEL][64]; char *alias[QUERY_MAXALIAS]; uint32 aliasttl[QUERY_MAXALIAS]; char localip[4]; char type[2]; char class[2]; struct dns_transmit dt; } ; extern int query_start(struct query *,char *,char *,char *,char *); extern void query_io(struct query *,iopause_fd *,struct taia *); extern int query_get(struct query *,iopause_fd *,struct taia *); extern void query_forwardonly(void); #endif tinydyndns-0.4.2.debian1/random-ip.c000066400000000000000000000036011103424076200172530ustar00rootroot00000000000000#include "buffer.h" #include "exit.h" #include "fmt.h" #include "scan.h" #include "dns.h" char ip[4]; int ipfixed = 0; unsigned long loops = 10000; unsigned char tab[256]; char strnum[FMT_ULONG]; char seed[128]; int main(int argc,char **argv) { unsigned long u; int i; int j; unsigned char c; dns_random_init(seed); for (i = 0;i < 256;++i) tab[i] = i; for (j = 256;j > 0;--j) { i = dns_random(j); c = tab[j - 1]; tab[j - 1] = tab[i]; tab[i] = c; } if (*argv) ++argv; if (*argv) scan_ulong(*argv++,&loops); if (*argv) { scan_ulong(*argv++,&u); ip[0] = u; ipfixed = 1; } if (*argv) { scan_ulong(*argv++,&u); ip[1] = u; ipfixed = 2; } if (*argv) { scan_ulong(*argv++,&u); ip[2] = u; ipfixed = 3; } if (*argv) { scan_ulong(*argv++,&u); ip[3] = u; ipfixed = 4; } if (ipfixed >= 1) if (loops > 16777216) loops = 16777216; if (ipfixed >= 2) if (loops > 65536) loops = 65536; if (ipfixed >= 3) if (loops > 256) loops = 256; if (ipfixed >= 4) if (loops > 1) loops = 1; while (loops) { --loops; u = loops; for (i = ipfixed;i < 4;++i) { ip[i] = u & 255; u >>= 8; } if (ipfixed == 3) { c = ip[3]; ip[3] = tab[c]; } else if (ipfixed < 3) { c = 0; for (j = 0;j < 100;++j) { for (i = ipfixed;i < 4;++i) { c ^= (unsigned char) ip[i]; c = tab[c]; ip[i] = c; } } } u = (unsigned char) ip[0]; buffer_put(buffer_1,strnum,fmt_ulong(strnum,u)); buffer_puts(buffer_1,"."); u = (unsigned char) ip[1]; buffer_put(buffer_1,strnum,fmt_ulong(strnum,u)); buffer_puts(buffer_1,"."); u = (unsigned char) ip[2]; buffer_put(buffer_1,strnum,fmt_ulong(strnum,u)); buffer_puts(buffer_1,"."); u = (unsigned char) ip[3]; buffer_put(buffer_1,strnum,fmt_ulong(strnum,u)); buffer_puts(buffer_1,"\n"); } buffer_flush(buffer_1); _exit(0); } tinydyndns-0.4.2.debian1/rbldns-conf.c000066400000000000000000000026471103424076200176050ustar00rootroot00000000000000#include #include #include "strerr.h" #include "exit.h" #include "auto_home.h" #include "generic-conf.h" #define FATAL "rbldns-conf: fatal: " void usage(void) { strerr_die1x(100,"rbldns-conf: usage: rbldns-conf acct logacct /rbldns myip base"); } char *dir; char *user; char *loguser; struct passwd *pw; char *myip; char *base; int main(int argc,char **argv) { user = argv[1]; if (!user) usage(); loguser = argv[2]; if (!loguser) usage(); dir = argv[3]; if (!dir) usage(); if (dir[0] != '/') usage(); myip = argv[4]; if (!myip) usage(); base = argv[5]; if (!base) usage(); pw = getpwnam(loguser); if (!pw) strerr_die3x(111,FATAL,"unknown account ",loguser); init(dir,FATAL); makelog(loguser,pw->pw_uid,pw->pw_gid); makedir("env"); perm(02755); start("env/ROOT"); outs(dir); outs("/root\n"); finish(); perm(0644); start("env/IP"); outs(myip); outs("\n"); finish(); perm(0644); start("env/BASE"); outs(base); outs("\n"); finish(); perm(0644); start("run"); outs("#!/bin/sh\nexec 2>&1\nexec envuidgid "); outs(user); outs(" envdir ./env softlimit -d250000 "); outs(auto_home); outs("/bin/rbldns\n"); finish(); perm(0755); makedir("root"); perm(02755); start("root/data"); finish(); perm(0644); start("root/Makefile"); outs("data.cdb: data\n"); outs("\t"); outs(auto_home); outs("/bin/rbldns-data\n"); finish(); perm(0644); _exit(0); } tinydyndns-0.4.2.debian1/rbldns-data.c000066400000000000000000000056341103424076200175700ustar00rootroot00000000000000#include #include #include #include #include "buffer.h" #include "exit.h" #include "cdb_make.h" #include "open.h" #include "stralloc.h" #include "getln.h" #include "strerr.h" #include "byte.h" #include "scan.h" #include "fmt.h" #include "ip4.h" #define FATAL "rbldns-data: fatal: " void nomem(void) { strerr_die2x(111,FATAL,"out of memory"); } int fd; buffer b; char bspace[1024]; int fdcdb; struct cdb_make cdb; static stralloc tmp; static stralloc line; int match = 1; unsigned long linenum = 0; char strnum[FMT_ULONG]; void syntaxerror(const char *why) { strnum[fmt_ulong(strnum,linenum)] = 0; strerr_die4x(111,FATAL,"unable to parse data line ",strnum,why); } void die_datatmp(void) { strerr_die2sys(111,FATAL,"unable to create data.tmp: "); } int main() { char ip[4]; unsigned long u; unsigned int j; unsigned int k; char ch; umask(022); fd = open_read("data"); if (fd == -1) strerr_die2sys(111,FATAL,"unable to open data: "); buffer_init(&b,buffer_unixread,fd,bspace,sizeof bspace); fdcdb = open_trunc("data.tmp"); if (fdcdb == -1) die_datatmp(); if (cdb_make_start(&cdb,fdcdb) == -1) die_datatmp(); while (match) { ++linenum; if (getln(&b,&line,&match,'\n') == -1) strerr_die2sys(111,FATAL,"unable to read line: "); while (line.len) { ch = line.s[line.len - 1]; if ((ch != ' ') && (ch != '\t') && (ch != '\n')) break; --line.len; } if (!line.len) continue; switch(line.s[0]) { default: syntaxerror(": unrecognized leading character"); case '#': break; case ':': j = byte_chr(line.s + 1,line.len - 1,':'); if (j >= line.len - 1) syntaxerror(": missing colon"); if (ip4_scan(line.s + 1,ip) != j) syntaxerror(": malformed IP address"); if (!stralloc_copyb(&tmp,ip,4)) nomem(); if (!stralloc_catb(&tmp,line.s + j + 2,line.len - j - 2)) nomem(); if (cdb_make_add(&cdb,"",0,tmp.s,tmp.len) == -1) die_datatmp(); break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if (!stralloc_0(&line)) nomem(); j = 0; if (!stralloc_copys(&tmp,"")) nomem(); for (;;) { k = scan_ulong(line.s + j,&u); if (!k) break; ch = u; if (!stralloc_catb(&tmp,&ch,1)) nomem(); j += k; if (line.s[j] != '.') break; ++j; } if (!stralloc_catb(&tmp,"\0\0\0\0",4)) nomem(); tmp.len = 4; if (line.s[j] == '/') scan_ulong(line.s + j + 1,&u); else u = 32; if (u > 32) u = 32; ch = u; if (!stralloc_catb(&tmp,&ch,1)) nomem(); if (cdb_make_add(&cdb,tmp.s,tmp.len,"",0) == -1) die_datatmp(); break; } } if (cdb_make_finish(&cdb) == -1) die_datatmp(); if (fsync(fdcdb) == -1) die_datatmp(); if (close(fdcdb) == -1) die_datatmp(); /* NFS stupidity */ if (rename("data.tmp","data.cdb") == -1) strerr_die2sys(111,FATAL,"unable to move data.tmp to data.cdb: "); _exit(0); } tinydyndns-0.4.2.debian1/rbldns.c000066400000000000000000000045141103424076200166550ustar00rootroot00000000000000#include #include "str.h" #include "byte.h" #include "ip4.h" #include "open.h" #include "env.h" #include "cdb.h" #include "dns.h" #include "dd.h" #include "strerr.h" #include "response.h" static char *base; static struct cdb c; static char key[5]; static char data[100 + IP4_FMT]; static int doit(char *q,char qtype[2]) { int flaga; int flagtxt; char ch; char reverseip[4]; char ip[4]; uint32 ipnum; int r; uint32 dlen; int i; flaga = byte_equal(qtype,2,DNS_T_A); flagtxt = byte_equal(qtype,2,DNS_T_TXT); if (byte_equal(qtype,2,DNS_T_ANY)) flaga = flagtxt = 1; if (!flaga && !flagtxt) goto REFUSE; if (dd(q,base,reverseip) != 4) goto REFUSE; uint32_unpack(reverseip,&ipnum); uint32_pack_big(ip,ipnum); for (i = 0;i <= 24;++i) { ipnum >>= i; ipnum <<= i; uint32_pack_big(key,ipnum); key[4] = 32 - i; r = cdb_find(&c,key,5); if (r == -1) return 0; if (r) break; } if (!r) { response_nxdomain(); return 1; } r = cdb_find(&c,"",0); if (r == -1) return 0; if (r && ((dlen = cdb_datalen(&c)) >= 4)) { if (dlen > 100) dlen = 100; if (cdb_read(&c,data,dlen,cdb_datapos(&c)) == -1) return 0; } else { dlen = 12; byte_copy(data,dlen,"\177\0\0\2Listed $"); } if ((dlen >= 5) && (data[dlen - 1] == '$')) { --dlen; dlen += ip4_fmt(data + dlen,ip); } if (flaga) { if (!response_rstart(q,DNS_T_A,2048)) return 0; if (!response_addbytes(data,4)) return 0; response_rfinish(RESPONSE_ANSWER); } if (flagtxt) { if (!response_rstart(q,DNS_T_TXT,2048)) return 0; ch = dlen - 4; if (!response_addbytes(&ch,1)) return 0; if (!response_addbytes(data + 4,dlen - 4)) return 0; response_rfinish(RESPONSE_ANSWER); } return 1; REFUSE: response[2] &= ~4; response[3] &= ~15; response[3] |= 5; return 1; } int respond(char *q,char qtype[2],char ip[4]) { int fd; int result; fd = open_read("data.cdb"); if (fd == -1) return 0; cdb_init(&c,fd); result = doit(q,qtype); cdb_free(&c); close(fd); return result; } const char *fatal = "rbldns: fatal: "; const char *starting = "starting rbldns\n"; void initialize(void) { char *x; x = env_get("BASE"); if (!x) strerr_die2x(111,fatal,"$BASE not set"); if (!dns_domain_fromdot(&base,x,str_len(x))) strerr_die2x(111,fatal,"unable to parse $BASE"); } tinydyndns-0.4.2.debian1/readclose.c000066400000000000000000000010271103424076200173260ustar00rootroot00000000000000#include #include "error.h" #include "readclose.h" int readclose_append(int fd,stralloc *sa,unsigned int bufsize) { int r; for (;;) { if (!stralloc_readyplus(sa,bufsize)) { close(fd); return -1; } r = read(fd,sa->s + sa->len,bufsize); if (r == -1) if (errno == error_intr) continue; if (r <= 0) { close(fd); return r; } sa->len += r; } } int readclose(int fd,stralloc *sa,unsigned int bufsize) { if (!stralloc_copys(sa,"")) { close(fd); return -1; } return readclose_append(fd,sa,bufsize); } tinydyndns-0.4.2.debian1/readclose.h000066400000000000000000000002651103424076200173360ustar00rootroot00000000000000#ifndef READCLOSE_H #define READCLOSE_H #include "stralloc.h" extern int readclose_append(int,stralloc *,unsigned int); extern int readclose(int,stralloc *,unsigned int); #endif tinydyndns-0.4.2.debian1/response.c000066400000000000000000000050211103424076200172210ustar00rootroot00000000000000#include "dns.h" #include "byte.h" #include "uint16.h" #include "response.h" char response[65535]; unsigned int response_len = 0; /* <= 65535 */ static unsigned int tctarget; #define NAMES 100 static char name[NAMES][128]; static unsigned int name_ptr[NAMES]; /* each < 16384 */ static unsigned int name_num; int response_addbytes(const char *buf,unsigned int len) { if (len > 65535 - response_len) return 0; byte_copy(response + response_len,len,buf); response_len += len; return 1; } int response_addname(const char *d) { unsigned int dlen; unsigned int i; char buf[2]; dlen = dns_domain_length(d); while (*d) { for (i = 0;i < name_num;++i) if (dns_domain_equal(d,name[i])) { uint16_pack_big(buf,49152 + name_ptr[i]); return response_addbytes(buf,2); } if (dlen <= 128) if (name_num < NAMES) { byte_copy(name[name_num],dlen,d); name_ptr[name_num] = response_len; ++name_num; } i = (unsigned char) *d; ++i; if (!response_addbytes(d,i)) return 0; d += i; dlen -= i; } return response_addbytes(d,1); } int response_query(const char *q,const char qtype[2],const char qclass[2]) { response_len = 0; name_num = 0; if (!response_addbytes("\0\0\201\200\0\1\0\0\0\0\0\0",12)) return 0; if (!response_addname(q)) return 0; if (!response_addbytes(qtype,2)) return 0; if (!response_addbytes(qclass,2)) return 0; tctarget = response_len; return 1; } static unsigned int dpos; static int flaghidettl = 0; void response_hidettl(void) { flaghidettl = 1; } int response_rstart(const char *d,const char type[2],uint32 ttl) { char ttlstr[4]; if (!response_addname(d)) return 0; if (!response_addbytes(type,2)) return 0; if (!response_addbytes(DNS_C_IN,2)) return 0; if (flaghidettl) ttl = 0; uint32_pack_big(ttlstr,ttl); if (!response_addbytes(ttlstr,4)) return 0; if (!response_addbytes("\0\0",2)) return 0; dpos = response_len; return 1; } void response_rfinish(int x) { uint16_pack_big(response + dpos - 2,response_len - dpos); if (!++response[x + 1]) ++response[x]; } int response_cname(const char *c,const char *d,uint32 ttl) { if (!response_rstart(c,DNS_T_CNAME,ttl)) return 0; if (!response_addname(d)) return 0; response_rfinish(RESPONSE_ANSWER); return 1; } void response_nxdomain(void) { response[3] |= 3; response[2] |= 4; } void response_servfail(void) { response[3] |= 2; } void response_id(const char id[2]) { byte_copy(response,2,id); } void response_tc(void) { response[2] |= 2; response_len = tctarget; } tinydyndns-0.4.2.debian1/response.h000066400000000000000000000013211103424076200172250ustar00rootroot00000000000000#ifndef RESPONSE_H #define RESPONSE_H #include "uint32.h" extern char response[]; extern unsigned int response_len; extern int response_query(const char *,const char *,const char *); extern void response_nxdomain(void); extern void response_servfail(void); extern void response_id(const char *); extern void response_tc(void); extern int response_addbytes(const char *,unsigned int); extern int response_addname(const char *); extern void response_hidettl(void); extern int response_rstart(const char *,const char *,uint32); extern void response_rfinish(int); #define RESPONSE_ANSWER 6 #define RESPONSE_AUTHORITY 8 #define RESPONSE_ADDITIONAL 10 extern int response_cname(const char *,const char *,uint32); #endif tinydyndns-0.4.2.debian1/roots.c000066400000000000000000000042771103424076200165450ustar00rootroot00000000000000#include #include "open.h" #include "error.h" #include "str.h" #include "byte.h" #include "error.h" #include "direntry.h" #include "ip4.h" #include "dns.h" #include "openreadclose.h" #include "roots.h" static stralloc data; static int roots_find(char *q) { int i; int j; i = 0; while (i < data.len) { j = dns_domain_length(data.s + i); if (dns_domain_equal(data.s + i,q)) return i + j; i += j; i += 64; } return -1; } static int roots_search(char *q) { int r; for (;;) { r = roots_find(q); if (r >= 0) return r; if (!*q) return -1; /* user misconfiguration */ q += *q; q += 1; } } int roots(char servers[64],char *q) { int r; r = roots_find(q); if (r == -1) return 0; byte_copy(servers,64,data.s + r); return 1; } int roots_same(char *q,char *q2) { return roots_search(q) == roots_search(q2); } static int init2(DIR *dir) { direntry *d; const char *fqdn; static char *q; static stralloc text; char servers[64]; int serverslen; int i; int j; for (;;) { errno = 0; d = readdir(dir); if (!d) { if (errno) return 0; return 1; } if (d->d_name[0] != '.') { if (openreadclose(d->d_name,&text,32) != 1) return 0; if (!stralloc_append(&text,"\n")) return 0; fqdn = d->d_name; if (str_equal(fqdn,"@")) fqdn = "."; if (!dns_domain_fromdot(&q,fqdn,str_len(fqdn))) return 0; serverslen = 0; j = 0; for (i = 0;i < text.len;++i) if (text.s[i] == '\n') { if (serverslen <= 60) if (ip4_scan(text.s + j,servers + serverslen)) serverslen += 4; j = i + 1; } byte_zero(servers + serverslen,64 - serverslen); if (!stralloc_catb(&data,q,dns_domain_length(q))) return 0; if (!stralloc_catb(&data,servers,64)) return 0; } } } static int init1(void) { DIR *dir; int r; if (chdir("servers") == -1) return 0; dir = opendir("."); if (!dir) return 0; r = init2(dir); closedir(dir); return r; } int roots_init(void) { int fddir; int r; if (!stralloc_copys(&data,"")) return 0; fddir = open_read("."); if (fddir == -1) return 0; r = init1(); if (fchdir(fddir) == -1) r = 0; close(fddir); return r; } tinydyndns-0.4.2.debian1/roots.h000066400000000000000000000002151103424076200165360ustar00rootroot00000000000000#ifndef ROOTS_H #define ROOTS_H extern int roots(char *,char *); extern int roots_same(char *,char *); extern int roots_init(void); #endif tinydyndns-0.4.2.debian1/rts.exp000066400000000000000000001137451103424076200165620ustar00rootroot00000000000000--- dnscache-conf works --- tinydns-conf works --- pickdns-conf works --- walldns-conf works --- rbldns-conf works --- axfrdns-conf works --- cache handles simple example un un deux un deux trois un deux trois quatre un deux trois quatre cinq een deux trois quatre cinq een twee trois quatre cinq een twee drie quatre cinq een twee drie vier cinq een twee drie vier vijf 0 --- cache handles overwriting un een een deux een twee een twee trois een twee drie twee drie quatre twee drie vier drie vier cinq drie vier vijf 0 --- cache handles long chains 1 2 3 4 5 6 7 8 9 0 --- dnsip finds IP address of network-surveys.cr.yp.to 131.193.178.100 0 --- dnsip does not find nonexistent.cr.yp.to 0 --- dnsip rejects overly long domain names dnsip: fatal: unable to find IP address for x.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789: protocol error 111 --- dnsip handles IP address on input 1.2.3.4 127.0.0.1 10.43.166.133 10.43.166.133 0 --- dnsip allows 0 to be omitted 127.0.0.1 0 --- dnsip handles multiple IP addresses on input 1.2.3.4 5.6.7.8 9.10.11.12 13.14.15.16 0 --- dnsipq handles simple examples 1.2.3.4 1.2.3.4 localhost 127.0.0.1 localhost 127.0.0.1 5.6.7.8 5.6.7.8 network-surveys.cr.yp.to 131.193.178.100 nonexistent.whatever.cr.yp.to 0 --- dnsmx finds MX record for network-surveys.cr.yp.to 0 a.mx.network-surveys.cr.yp.to 0 --- dnsmx manufactures MX record for nonexistent.cr.yp.to 0 nonexistent.cr.yp.to 0 --- dnsmx rejects overly long domain names dnsmx: fatal: unable to find MX records for 0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789: protocol error 111 --- dnstxt finds TXT record for leap.yp.to 8222222206660602022066620620. 0 --- dnstxt does not find nonexistent.cr.yp.to 0 --- dnstxt rejects overly long domain names dnstxt: fatal: unable to find TXT records for 0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789: protocol error 111 --- dnsname finds host name of 131.193.178.100 network-surveys.cr.yp.to 0 --- dnsname does not find 127.5.6.7 0 --- dnsname rejects misformatted IP addresses dnsname: fatal: unable to parse IP address 1.2.3 111 --- dnsfilter finds some host names 131.193.178.100+one=network-surveys.cr.yp.to two three 127.5.6.7+one two three 10+one two three 0 --- tinydns-data complains about unrecognized initial characters tinydns-data: fatal: unable to parse data line 3: unrecognized leading character 111 --- tinydns-data complains if it cannot create data.tmp tinydns-data: fatal: unable to create data.tmp: symbolic link loop 111 --- tinydns-data handles simple example 0 --- tinydns-data produces A records 1 wormhole.movie.edu: 117 bytes, 1+2+2+1 records, response, authoritative, noerror additional: a.ns.movie.edu 259200 A 192.249.249.3 answer: wormhole.movie.edu 86400 A 192.249.249.1 answer: wormhole.movie.edu 86400 A 192.253.253.1 authority: movie.edu 259200 NS a.ns.movie.edu authority: movie.edu 259200 NS wormhole.movie.edu query: 1 wormhole.movie.edu 0 --- tinydns-data produces NS records 2 movie.edu: 117 bytes, 1+2+0+3 records, response, authoritative, noerror query: 2 movie.edu answer: movie.edu 259200 NS a.ns.movie.edu answer: movie.edu 259200 NS wormhole.movie.edu additional: a.ns.movie.edu 259200 A 192.249.249.3 additional: wormhole.movie.edu 86400 A 192.249.249.1 additional: wormhole.movie.edu 86400 A 192.253.253.1 0 --- tinydns-data produces SOA records 6 movie.edu: 164 bytes, 1+1+2+3 records, response, authoritative, noerror query: 6 movie.edu answer: movie.edu 2560 SOA a.ns.movie.edu hostmaster.movie.edu 987654321 16384 2048 1048576 2560 authority: movie.edu 259200 NS a.ns.movie.edu authority: movie.edu 259200 NS wormhole.movie.edu additional: a.ns.movie.edu 259200 A 192.249.249.3 additional: wormhole.movie.edu 86400 A 192.249.249.1 additional: wormhole.movie.edu 86400 A 192.253.253.1 0 --- tinydns-data produces PTR records 12 1.253.253.192.in-addr.arpa: 175 bytes, 1+1+3+3 records, response, authoritative, noerror query: 12 1.253.253.192.in-addr.arpa answer: 1.253.253.192.in-addr.arpa 86400 PTR wormhole.movie.edu authority: 253.253.192.in-addr.arpa 259200 NS a.ns.253.253.192.in-addr.arpa authority: 253.253.192.in-addr.arpa 259200 NS b.ns.253.253.192.in-addr.arpa authority: 253.253.192.in-addr.arpa 259200 NS c.ns.253.253.192.in-addr.arpa additional: a.ns.253.253.192.in-addr.arpa 259200 A 192.249.249.3 additional: b.ns.253.253.192.in-addr.arpa 259200 A 192.249.249.1 additional: c.ns.253.253.192.in-addr.arpa 259200 A 192.253.253.1 0 --- tinydns-data produces MX records 15 movie.edu: 154 bytes, 1+1+2+4 records, response, authoritative, noerror query: 15 movie.edu answer: movie.edu 86400 MX 0 a.mx.movie.edu authority: movie.edu 259200 NS a.ns.movie.edu authority: movie.edu 259200 NS wormhole.movie.edu additional: a.mx.movie.edu 86400 A 192.249.249.1 additional: a.ns.movie.edu 259200 A 192.249.249.3 additional: wormhole.movie.edu 86400 A 192.249.249.1 additional: wormhole.movie.edu 86400 A 192.253.253.1 0 --- tinydns-data produces TXT records 16 movie.edu: 146 bytes, 1+1+2+3 records, response, authoritative, noerror query: 16 movie.edu answer: movie.edu 86400 16 \020Movie\040University authority: movie.edu 259200 NS a.ns.movie.edu authority: movie.edu 259200 NS wormhole.movie.edu additional: a.ns.movie.edu 259200 A 192.249.249.3 additional: wormhole.movie.edu 86400 A 192.249.249.1 additional: wormhole.movie.edu 86400 A 192.253.253.1 0 --- tinydns-data produces AXFR responses 252 movie.edu: 27 bytes, 1+0+0+0 records, response, authoritative, notimp query: 252 movie.edu 0 --- tinydns-data produces ANY responses 255 movie.edu: 293 bytes, 1+9+0+4 records, response, authoritative, noerror query: 255 movie.edu answer: movie.edu 2560 SOA a.ns.movie.edu hostmaster.movie.edu 987654321 16384 2048 1048576 2560 answer: movie.edu 259200 NS a.ns.movie.edu answer: movie.edu 259200 NS wormhole.movie.edu answer: movie.edu 86400 MX 0 a.mx.movie.edu answer: movie.edu 86400 16 \020Movie\040University answer: movie.edu 86400 12345 One answer: movie.edu 86400 12345 Two answer: movie.edu 86400 12346 Three answer: movie.edu 86400 12346 Four additional: a.ns.movie.edu 259200 A 192.249.249.3 additional: wormhole.movie.edu 86400 A 192.249.249.1 additional: wormhole.movie.edu 86400 A 192.253.253.1 additional: a.mx.movie.edu 86400 A 192.249.249.1 0 --- tinydns-data produces records of any type 12345 movie.edu: 147 bytes, 1+2+2+3 records, response, authoritative, noerror query: 12345 movie.edu answer: movie.edu 86400 12345 One answer: movie.edu 86400 12345 Two authority: movie.edu 259200 NS a.ns.movie.edu authority: movie.edu 259200 NS wormhole.movie.edu additional: a.ns.movie.edu 259200 A 192.249.249.3 additional: wormhole.movie.edu 86400 A 192.249.249.1 additional: wormhole.movie.edu 86400 A 192.253.253.1 0 12346 movie.edu: 150 bytes, 1+2+2+3 records, response, authoritative, noerror query: 12346 movie.edu answer: movie.edu 86400 12346 Three answer: movie.edu 86400 12346 Four authority: movie.edu 259200 NS a.ns.movie.edu authority: movie.edu 259200 NS wormhole.movie.edu additional: a.ns.movie.edu 259200 A 192.249.249.3 additional: wormhole.movie.edu 86400 A 192.249.249.1 additional: wormhole.movie.edu 86400 A 192.253.253.1 0 --- tinydns-data produces NODATA responses 54321 movie.edu: 79 bytes, 1+0+1+0 records, response, authoritative, noerror query: 54321 movie.edu authority: movie.edu 2560 SOA a.ns.movie.edu hostmaster.movie.edu 987654321 16384 2048 1048576 2560 0 --- tinydns-data produces NXDOMAIN responses 1 this.does.not.exist.movie.edu: 99 bytes, 1+0+1+0 records, response, authoritative, nxdomain query: 1 this.does.not.exist.movie.edu authority: movie.edu 2560 SOA a.ns.movie.edu hostmaster.movie.edu 987654321 16384 2048 1048576 2560 0 --- tinydns-data produces NXDOMAIN responses for suffixes 1 ns.movie.edu: 79 bytes, 1+0+1+0 records, response, authoritative, nxdomain query: 1 ns.movie.edu authority: movie.edu 2560 SOA a.ns.movie.edu hostmaster.movie.edu 987654321 16384 2048 1048576 2560 0 --- tinydns-data produces NXDOMAIN ANY responses for suffixes 255 ns.movie.edu: 79 bytes, 1+0+1+0 records, response, authoritative, nxdomain query: 255 ns.movie.edu authority: movie.edu 2560 SOA a.ns.movie.edu hostmaster.movie.edu 987654321 16384 2048 1048576 2560 0 --- tinydns-data does not produce responses outside its bailiwick 1 edu: 0 --- tinydns-data does not include TXT in additional sections 1 blah.movie.edu: 62 bytes, 1+1+1+0 records, response, authoritative, noerror query: 1 blah.movie.edu answer: blah.movie.edu 259200 A 1.2.3.4 authority: blah.movie.edu 259200 NS blah.movie.edu 0 --- tinydns-data handles another example 0 --- tinydns-data uses serial 1 for mtime 0 255 test: 152 bytes, 1+3+0+3 records, response, authoritative, noerror query: 255 test answer: test 2560 SOA a.ns.test hostmaster.test 1 16384 2048 1048576 2560 answer: test 259200 NS a.ns.test answer: test 259200 NS b.ns.test additional: a.ns.test 259200 A 10.2.3.4 additional: b.ns.test 259200 A 10.2.3.6 additional: b.ns.test 259200 A 10.2.3.5 0 --- tinydns-data does not split size-127 TXT records 16 127.test: 249 bytes, 1+1+2+3 records, response, authoritative, noerror query: 16 127.test answer: 127.test 86400 16 \1770123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456 authority: test 259200 NS a.ns.test authority: test 259200 NS b.ns.test additional: a.ns.test 259200 A 10.2.3.4 additional: b.ns.test 259200 A 10.2.3.6 additional: b.ns.test 259200 A 10.2.3.5 0 --- tinydns-data splits size-128 TXT records 16 128.test: 251 bytes, 1+1+2+3 records, response, authoritative, noerror query: 16 128.test answer: 128.test 86400 16 \1770123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456\0017 authority: test 259200 NS a.ns.test authority: test 259200 NS b.ns.test additional: a.ns.test 259200 A 10.2.3.4 additional: b.ns.test 259200 A 10.2.3.6 additional: b.ns.test 259200 A 10.2.3.5 0 --- tinydns-data splits size-254 TXT records 16 254.test: 377 bytes, 1+1+2+3 records, response, authoritative, noerror query: 16 254.test answer: 254.test 86400 16 \1770123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456\1777890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123 authority: test 259200 NS a.ns.test authority: test 259200 NS b.ns.test additional: a.ns.test 259200 A 10.2.3.4 additional: b.ns.test 259200 A 10.2.3.6 additional: b.ns.test 259200 A 10.2.3.5 0 --- tinydns-data doubly splits size-255 TXT records 16 255.test: 379 bytes, 1+1+2+3 records, response, authoritative, noerror query: 16 255.test answer: 255.test 86400 16 \1770123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456\1777890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123\0014 authority: test 259200 NS a.ns.test authority: test 259200 NS b.ns.test additional: a.ns.test 259200 A 10.2.3.4 additional: b.ns.test 259200 A 10.2.3.6 additional: b.ns.test 259200 A 10.2.3.5 0 --- tinydns-data excludes the additional section if necessary 16 387.test: 512 bytes, 1+1+2+3 records, response, authoritative, noerror query: 16 387.test answer: 387.test 86400 16 \1770123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456\1777890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123\1774567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\006123456 authority: test 259200 NS a.ns.test authority: test 259200 NS b.ns.test additional: a.ns.test 259200 A 10.2.3.4 additional: b.ns.test 259200 A 10.2.3.6 additional: b.ns.test 259200 A 10.2.3.5 0 16 388.test: 465 bytes, 1+1+2+0 records, response, authoritative, noerror query: 16 388.test answer: 388.test 86400 16 \1770123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456\1777890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123\1774567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\0071234567 authority: test 259200 NS a.ns.test authority: test 259200 NS b.ns.test 0 --- tinydns-data excludes the authority section if necessary 16 435.test: 512 bytes, 1+1+2+0 records, response, authoritative, noerror query: 16 435.test answer: 435.test 86400 16 \1770123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456\1777890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123\17745678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678906123456789012345678901234567890123456789012345678901234 authority: test 259200 NS a.ns.test authority: test 259200 NS b.ns.test 0 16 436.test: 478 bytes, 1+1+0+0 records, response, authoritative, noerror query: 16 436.test answer: 436.test 86400 16 \1770123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456\1777890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123\177456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789071234567890123456789012345678901234567890123456789012345 0 --- tinydns-data handles size-1000 TXT records 16 1000.test: 1047 bytes, 1+1+0+0 records, response, authoritative, noerror query: 16 1000.test answer: 1000.test 86400 16 \1770123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456\1777890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123\1774567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\1771234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567\1778901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234\1775678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901\1772345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678o901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 0 --- tinydns-data handles unusual characters in owner names 1 \000\001\177\200\277\056\056\056.test: 130 bytes, 1+1+2+3 records, response, authoritative, noerror query: 1 \000\001\177\200\277\056\056\056.test answer: \000\001\177\200\277\056\056\056.test 86400 A 10.5.6.7 authority: test 259200 NS a.ns.test authority: test 259200 NS b.ns.test additional: a.ns.test 259200 A 10.2.3.4 additional: b.ns.test 259200 A 10.2.3.6 additional: b.ns.test 259200 A 10.2.3.5 0 --- tinydns-data handles unusual characters in PTR results 12 7.6.5.10.in-addr.arpa: 99 bytes, 1+1+1+1 records, response, authoritative, noerror query: 12 7.6.5.10.in-addr.arpa answer: 7.6.5.10.in-addr.arpa 86400 PTR \000\001\177\200\277\056\056\056.test authority: 7.6.5.10.in-addr.arpa 259200 NS ns.7.6.5.10.in-addr.arpa additional: ns.7.6.5.10.in-addr.arpa 259200 A 10.5.6.7 0 --- tinydns-data handles delegations 1 x.\000\001\177\200\277\056\056\056.test: 66 bytes, 1+0+1+1 records, response, noerror query: 1 x.\000\001\177\200\277\056\056\056.test authority: x.\000\001\177\200\277\056\056\056.test 259200 NS ns.x.\000\001\177\200\277\056\056\056.test additional: ns.x.\000\001\177\200\277\056\056\056.test 259200 A 10.8.9.10 0 1 ns.x.\000\001\177\200\277\056\056\056.test: 66 bytes, 1+0+1+1 records, response, noerror query: 1 ns.x.\000\001\177\200\277\056\056\056.test authority: x.\000\001\177\200\277\056\056\056.test 259200 NS ns.x.\000\001\177\200\277\056\056\056.test additional: ns.x.\000\001\177\200\277\056\056\056.test 259200 A 10.8.9.10 0 1 z.y.x.\000\001\177\200\277\056\056\056.test: 70 bytes, 1+0+1+1 records, response, noerror query: 1 z.y.x.\000\001\177\200\277\056\056\056.test authority: x.\000\001\177\200\277\056\056\056.test 259200 NS ns.x.\000\001\177\200\277\056\056\056.test additional: ns.x.\000\001\177\200\277\056\056\056.test 259200 A 10.8.9.10 0 --- tinydns-data handles another example 0 --- tinydns-data handles TTLs 255 test: 202 bytes, 1+6+0+2 records, response, authoritative, noerror query: 255 test answer: test 98765 SOA primary.server host.master 1234567 2345678 3456789 4567890 5678901 answer: test 37 NS ns.test answer: test 41 MX 0 mx.test answer: test 42 16 \004Text answer: test 43 12345 Binary answer: test 39 A 1.2.3.4 additional: ns.test 37 A 1.2.3.4 additional: mx.test 41 A 1.2.3.4 0 255 www.test: 75 bytes, 1+1+1+1 records, response, authoritative, noerror query: 255 www.test answer: www.test 40 A 1.2.3.4 authority: test 37 NS ns.test additional: ns.test 37 A 1.2.3.4 0 255 child.test: 61 bytes, 1+0+1+1 records, response, noerror query: 255 child.test authority: child.test 38 NS ns.child.test additional: ns.child.test 38 A 1.2.3.5 0 --- tinydns-data handles CNAMEs 255 mail.test: 78 bytes, 1+1+1+1 records, response, authoritative, noerror query: 255 mail.test answer: mail.test 44 CNAME www.test authority: test 37 NS ns.test additional: ns.test 37 A 1.2.3.4 0 5 mail.test: 78 bytes, 1+1+1+1 records, response, authoritative, noerror query: 5 mail.test answer: mail.test 44 CNAME www.test authority: test 37 NS ns.test additional: ns.test 37 A 1.2.3.4 0 1 mail.test: 78 bytes, 1+1+1+1 records, response, authoritative, noerror query: 1 mail.test answer: mail.test 44 CNAME www.test authority: test 37 NS ns.test additional: ns.test 37 A 1.2.3.4 0 255 foo.mail.test: 92 bytes, 1+0+1+0 records, response, authoritative, nxdomain query: 255 foo.mail.test authority: test 98765 SOA primary.server host.master 1234567 2345678 3456789 4567890 5678901 0 --- tinydns-data does not apply wildcard A to base name 1 wild.test: 88 bytes, 1+0+1+0 records, response, authoritative, nxdomain query: 1 wild.test authority: test 98765 SOA primary.server host.master 1234567 2345678 3456789 4567890 5678901 0 --- tinydns-data handles wildcard A records 1 x.wild.test: 78 bytes, 1+1+1+1 records, response, authoritative, noerror query: 1 x.wild.test answer: x.wild.test 45 A 1.2.3.6 authority: test 37 NS ns.test additional: ns.test 37 A 1.2.3.4 0 1 xy.wild.test: 79 bytes, 1+1+1+1 records, response, authoritative, noerror query: 1 xy.wild.test answer: xy.wild.test 45 A 1.2.3.6 authority: test 37 NS ns.test additional: ns.test 37 A 1.2.3.4 0 1 x.z.wild.test: 80 bytes, 1+1+1+1 records, response, authoritative, noerror query: 1 x.z.wild.test answer: x.z.wild.test 45 A 1.2.3.6 authority: test 37 NS ns.test additional: ns.test 37 A 1.2.3.4 0 --- tinydns-data handles wildcard MX records 255 wild.test: 88 bytes, 1+0+1+0 records, response, authoritative, nxdomain query: 255 wild.test authority: test 98765 SOA primary.server host.master 1234567 2345678 3456789 4567890 5678901 0 --- tinydns-data does not apply wildcard MX to base name 255 x.wild.test: 115 bytes, 1+2+1+2 records, response, authoritative, noerror query: 255 x.wild.test answer: x.wild.test 46 MX 54321 mail.wild.test answer: x.wild.test 45 A 1.2.3.6 authority: test 37 NS ns.test additional: mail.wild.test 46 A 1.2.3.7 additional: ns.test 37 A 1.2.3.4 0 255 xy.wild.test: 116 bytes, 1+2+1+2 records, response, authoritative, noerror query: 255 xy.wild.test answer: xy.wild.test 46 MX 54321 mail.wild.test answer: xy.wild.test 45 A 1.2.3.6 authority: test 37 NS ns.test additional: mail.wild.test 46 A 1.2.3.7 additional: ns.test 37 A 1.2.3.4 0 15 x.z.wild.test: 101 bytes, 1+1+1+2 records, response, authoritative, noerror query: 15 x.z.wild.test answer: x.z.wild.test 46 MX 54321 mail.wild.test authority: test 37 NS ns.test additional: mail.wild.test 46 A 1.2.3.7 additional: ns.test 37 A 1.2.3.4 0 255 x.z.wild.test: 117 bytes, 1+2+1+2 records, response, authoritative, noerror query: 255 x.z.wild.test answer: x.z.wild.test 46 MX 54321 mail.wild.test answer: x.z.wild.test 45 A 1.2.3.6 authority: test 37 NS ns.test additional: mail.wild.test 46 A 1.2.3.7 additional: ns.test 37 A 1.2.3.4 0 255 \052.wild.test: 115 bytes, 1+2+1+2 records, response, authoritative, noerror query: 255 \052.wild.test answer: \052.wild.test 46 MX 54321 mail.wild.test answer: \052.wild.test 45 A 1.2.3.6 authority: test 37 NS ns.test additional: mail.wild.test 46 A 1.2.3.7 additional: ns.test 37 A 1.2.3.4 0 --- tinydns-data uses wildcard under base of sub-wildcard 255 alias.wild.test: 119 bytes, 1+2+1+2 records, response, authoritative, noerror query: 255 alias.wild.test answer: alias.wild.test 46 MX 54321 mail.wild.test answer: alias.wild.test 45 A 1.2.3.6 authority: test 37 NS ns.test additional: mail.wild.test 46 A 1.2.3.7 additional: ns.test 37 A 1.2.3.4 0 --- tinydns-data handles wildcard CNAME records 255 xyz.alias.wild.test: 84 bytes, 1+1+1+1 records, response, authoritative, noerror query: 255 xyz.alias.wild.test answer: xyz.alias.wild.test 50 CNAME wild.test authority: test 37 NS ns.test additional: ns.test 37 A 1.2.3.4 0 255 \052.alias.wild.test: 82 bytes, 1+1+1+1 records, response, authoritative, noerror query: 255 \052.alias.wild.test answer: \052.alias.wild.test 50 CNAME wild.test authority: test 37 NS ns.test additional: ns.test 37 A 1.2.3.4 0 --- tinydns-data lets explicit record override wildcard 255 override.wild.test: 85 bytes, 1+1+1+1 records, response, authoritative, noerror query: 255 override.wild.test answer: override.wild.test 47 A 1.2.3.8 authority: test 37 NS ns.test additional: ns.test 37 A 1.2.3.4 0 --- tinydns-data handles overrides sanely 255 x.override.wild.test: 124 bytes, 1+2+1+2 records, response, authoritative, noerror query: 255 x.override.wild.test answer: x.override.wild.test 46 MX 54321 mail.wild.test answer: x.override.wild.test 45 A 1.2.3.6 authority: test 37 NS ns.test additional: mail.wild.test 46 A 1.2.3.7 additional: ns.test 37 A 1.2.3.4 0 --- tinydns-data overrides wildcard with subdomain wildcard 255 x.wild.wild.test: 83 bytes, 1+1+1+1 records, response, authoritative, noerror query: 255 x.wild.wild.test answer: x.wild.wild.test 48 A 1.2.3.9 authority: test 37 NS ns.test additional: ns.test 37 A 1.2.3.4 0 --- tinydns-data overrides wildcard with delegation 255 child.wild.test: 69 bytes, 1+0+1+1 records, response, noerror query: 255 child.wild.test authority: child.wild.test 259200 NS 49.ns.child.wild.test additional: 49.ns.child.wild.test 259200 A 1.2.3.10 0 255 x.child.wild.test: 71 bytes, 1+0+1+1 records, response, noerror query: 255 x.child.wild.test authority: child.wild.test 259200 NS 49.ns.child.wild.test additional: 49.ns.child.wild.test 259200 A 1.2.3.10 0 --- tinydns-data handles another example 0 --- tinydns-data handles ending time 255 www.four: 0 255 www.six: 74 bytes, 1+1+1+1 records, response, authoritative, noerror query: 255 www.six answer: www.six 3600 A 1.2.3.6 authority: six 3600 NS ns.six additional: ns.six 3600 A 1.2.3.6 0 --- tinydns-data handles starting time 255 www.five: 75 bytes, 1+1+1+1 records, response, authoritative, noerror query: 255 www.five answer: www.five 86400 A 1.2.3.5 authority: five 259200 NS ns.five additional: ns.five 259200 A 1.2.3.5 0 255 www.seven: 0 --- tinydns-edit handles simple examples 0 0 0 0 0 0 0 0 0 0 .heaven.af.mil:1.2.3.5:a:259200 .heaven.af.mil:1.2.3.6:b:259200 &sub.heaven.af.mil:1.2.10.11:a:259200 &sub.heaven.af.mil:1.2.10.12:b:259200 =lion.heaven.af.mil:1.2.3.4:86400 =tiger.heaven.af.mil:1.2.3.5:86400 =bear.heaven.af.mil:1.2.3.6:86400 +www.heaven.af.mil:1.2.3.4:86400 @heaven.af.mil:1.2.3.4:a::86400 @heaven.af.mil:1.2.3.7:b::86400 --- tinydns-edit rejects hosts with old names or IP addresses tinydns-edit: fatal: IP address already used 100 tinydns-edit: fatal: host name already used 100 .heaven.af.mil:1.2.3.5:a:259200 .heaven.af.mil:1.2.3.6:b:259200 &sub.heaven.af.mil:1.2.10.11:a:259200 &sub.heaven.af.mil:1.2.10.12:b:259200 =lion.heaven.af.mil:1.2.3.4:86400 =tiger.heaven.af.mil:1.2.3.5:86400 =bear.heaven.af.mil:1.2.3.6:86400 +www.heaven.af.mil:1.2.3.4:86400 @heaven.af.mil:1.2.3.4:a::86400 @heaven.af.mil:1.2.3.7:b::86400 --- tinydns-edit recognizes alternate forms of host names tinydns-edit: fatal: host name already used 100 .heaven.af.mil:1.2.3.5:a:259200 .heaven.af.mil:1.2.3.6:b:259200 &sub.heaven.af.mil:1.2.10.11:a:259200 &sub.heaven.af.mil:1.2.10.12:b:259200 =lion.heaven.af.mil:1.2.3.4:86400 =tiger.heaven.af.mil:1.2.3.5:86400 =bear.heaven.af.mil:1.2.3.6:86400 +www.heaven.af.mil:1.2.3.4:86400 @heaven.af.mil:1.2.3.4:a::86400 @heaven.af.mil:1.2.3.7:b::86400 --- tinydns-edit copies TTLs from previous NS records 0 .test:1.2.3.4:a:3600 .test:1.2.3.5:b:3600 --- dnscache handles dotted-decimal names 255 127.43.123.234: 48 bytes, 1+1+0+0 records, response, noerror query: 255 127.43.123.234 answer: 127.43.123.234 655360 A 127.43.123.234 0 --- tinydns works 127.43.0.100 127.43.0.101 0 1234 a.mx.test 45678 b.mx.test 0 255 www.test: 91 bytes, 1+2+1+1 records, response, authoritative, noerror additional: ns.test 259200 A 127.43.0.2 answer: www.test 86400 A 127.43.0.100 answer: www.test 86400 A 127.43.0.101 authority: test 259200 NS ns.test query: 255 www.test 0 255 test: 173 bytes, 1+4+0+3 records, response, authoritative, noerror query: 255 test answer: test 2560 SOA ns.test hostmaster.test 987654321 16384 2048 1048576 2560 answer: test 259200 NS ns.test answer: test 86400 MX 1234 a.mx.test answer: test 86400 MX 45678 b.mx.test additional: ns.test 259200 A 127.43.0.2 additional: a.mx.test 86400 A 127.43.0.100 additional: b.mx.test 86400 A 127.43.0.101 0 --- dnscache handles large TXT records 0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 --- walldns handles in-addr.arpa names 7.6.43.127.in-addr.arpa 0 234.123.43.127.in-addr.arpa 0 127.43.123.234 0 255 234.123.43.127.in-addr.arpa: 75 bytes, 1+2+0+0 records, response, authoritative, noerror query: 255 234.123.43.127.in-addr.arpa answer: 234.123.43.127.in-addr.arpa 655360 A 127.43.123.234 answer: 234.123.43.127.in-addr.arpa 655360 PTR 234.123.43.127.in-addr.arpa 0 --- walldns handles dotted-decimal names 255 127.43.123.234: 48 bytes, 1+1+0+0 records, response, authoritative, noerror query: 255 127.43.123.234 answer: 127.43.123.234 655360 A 127.43.123.234 0 --- walldns rejects other names 255 blah.test: temporary failure 0 --- rbldns works 127.0.0.3 0 See http://www.rbl.test/5.4.3.2 0 255 2.3.4.5.rbl.test: 94 bytes, 1+2+0+0 records, response, authoritative, noerror query: 255 2.3.4.5.rbl.test answer: 2.3.4.5.rbl.test 2048 A 127.0.0.3 answer: 2.3.4.5.rbl.test 2048 16 \037See\040http://www.rbl.test/5.4.3.2 0 127.0.0.3 0 See http://www.rbl.test/4.1.255.200 0 255 200.255.1.4.rbl.test: 102 bytes, 1+2+0+0 records, response, authoritative, noerror query: 255 200.255.1.4.rbl.test answer: 200.255.1.4.rbl.test 2048 A 127.0.0.3 answer: 200.255.1.4.rbl.test 2048 16 #See\040http://www.rbl.test/4.1.255.200 0 127.0.0.3 0 See http://www.rbl.test/4.0.255.200 0 255 200.255.0.4.rbl.test: 102 bytes, 1+2+0+0 records, response, authoritative, noerror query: 255 200.255.0.4.rbl.test answer: 200.255.0.4.rbl.test 2048 A 127.0.0.3 answer: 200.255.0.4.rbl.test 2048 16 #See\040http://www.rbl.test/4.0.255.200 0 127.0.0.3 0 See http://www.rbl.test/4.0.0.1 0 255 1.0.0.4.rbl.test: 94 bytes, 1+2+0+0 records, response, authoritative, noerror query: 255 1.0.0.4.rbl.test answer: 1.0.0.4.rbl.test 2048 A 127.0.0.3 answer: 1.0.0.4.rbl.test 2048 16 \037See\040http://www.rbl.test/4.0.0.1 0 0 0 255 0.0.0.4.rbl.test: 34 bytes, 1+0+0+0 records, response, authoritative, nxdomain query: 255 0.0.0.4.rbl.test 0 --- tinydns handles differentiation 0 127.43.0.102 0 127.43.0.100 127.43.0.102 0 127.43.0.100 127.43.0.102 0 255 pick.test5: 81 bytes, 1+0+1+0 records, response, authoritative, nxdomain query: 255 pick.test5 authority: test5 2560 SOA me.ns.test5 hostmaster.test5 987654321 16384 2048 1048576 2560 0 255 pick2.test5: 81 bytes, 1+1+1+1 records, response, authoritative, noerror query: 255 pick2.test5 answer: pick2.test5 86400 A 127.43.0.102 authority: test5 259200 NS me.ns.test5 additional: me.ns.test5 259200 A 127.43.0.2 0 255 pick3.test5: 97 bytes, 1+2+1+1 records, response, authoritative, noerror additional: me.ns.test5 259200 A 127.43.0.2 answer: pick3.test5 86400 A 127.43.0.100 answer: pick3.test5 86400 A 127.43.0.102 authority: test5 259200 NS me.ns.test5 query: 255 pick3.test5 0 103 bytes, 1+2+1+1 records, response, authoritative, noerror 255 really.wild.test5: additional: me.ns.test5 259200 A 127.43.0.2 answer: really.wild.test5 86400 A 127.43.0.100 answer: really.wild.test5 86400 A 127.43.0.102 authority: test5 259200 NS me.ns.test5 query: 255 really.wild.test5 0 --- tinydns-get handles differentiation 255 pick.test5: 80 bytes, 1+1+1+1 records, response, authoritative, noerror query: 255 pick.test5 answer: pick.test5 86400 A 127.43.0.101 authority: test5 259200 NS ex.ns.test5 additional: ex.ns.test5 259200 A 127.43.0.2 0 255 pick2.test5: 82 bytes, 1+0+1+0 records, response, authoritative, nxdomain query: 255 pick2.test5 authority: test5 2560 SOA ex.ns.test5 hostmaster.test5 987654321 16384 2048 1048576 2560 0 255 pick3.test5: 97 bytes, 1+2+1+1 records, response, authoritative, noerror additional: ex.ns.test5 259200 A 127.43.0.2 answer: pick3.test5 86400 A 127.43.0.100 answer: pick3.test5 86400 A 127.43.0.101 authority: test5 259200 NS ex.ns.test5 query: 255 pick3.test5 0 103 bytes, 1+2+1+1 records, response, authoritative, noerror 255 really.wild.test5: additional: ex.ns.test5 259200 A 127.43.0.2 answer: really.wild.test5 86400 A 127.43.0.100 answer: really.wild.test5 86400 A 127.43.0.101 authority: test5 259200 NS ex.ns.test5 query: 255 really.wild.test5 0 255 pick.test5: 81 bytes, 1+0+1+0 records, response, authoritative, nxdomain query: 255 pick.test5 authority: test5 2560 SOA i4.ns.test5 hostmaster.test5 987654321 16384 2048 1048576 2560 0 255 pick2.test5: 82 bytes, 1+0+1+0 records, response, authoritative, nxdomain query: 255 pick2.test5 authority: test5 2560 SOA i4.ns.test5 hostmaster.test5 987654321 16384 2048 1048576 2560 0 255 pick3.test5: 97 bytes, 1+2+1+1 records, response, authoritative, noerror additional: i4.ns.test5 259200 A 127.43.0.2 answer: pick3.test5 86400 A 127.43.0.100 answer: pick3.test5 86400 A 127.43.0.104 authority: test5 259200 NS i4.ns.test5 query: 255 pick3.test5 0 103 bytes, 1+2+1+1 records, response, authoritative, noerror 255 really.wild.test5: additional: i4.ns.test5 259200 A 127.43.0.2 answer: really.wild.test5 86400 A 127.43.0.100 answer: really.wild.test5 86400 A 127.43.0.104 authority: test5 259200 NS i4.ns.test5 query: 255 really.wild.test5 0 --- pickdns works 127.43.0.101 0 127.43.0.102 0 255 pick.test: 43 bytes, 1+1+0+0 records, response, authoritative, noerror query: 255 pick.test answer: pick.test 5 A 127.43.0.101 0 --- pickdns answers MX 0 pick.test 0 --- pickdns rejects queries for unknown information 255 pick11.test: temporary failure 0 16 pick2.test: temporary failure 0 --- axfrdns rejects unauthorized transfer attempts axfr-get: fatal: unable to parse AXFR results: protocol error 111 axfr-get: fatal: unable to parse AXFR results: protocol error 111 --- axfrdns works 0 #987654321 auto axfr-get Ztest:ns.test.:hostmaster.test.:987654321:16384:2048:1048576:2560:2560 &test::ns.test.:259200 +ns.test:127.43.0.2:259200 +www.test:127.43.0.100:86400 +www.test:127.43.0.101:86400 @test::a.mx.test.:1234:86400 +a.mx.test:127.43.0.100:86400 @test::b.mx.test.:45678:86400 +b.mx.test:127.43.0.101:86400 &pick.test::ns.pick.test.:259200 +ns.pick.test:127.43.0.3:259200 &pick2.test::ns.pick2.test.:259200 +ns.pick2.test:127.43.0.3:259200 &rbl.test::ns.rbl.test.:259200 +ns.rbl.test:127.43.0.5:259200 :big.test:16:\1770123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456\1777890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123\1774567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\1771234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567\1778901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234\1775678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901\1772345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678o901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789:86400 --- axfrdns handles differentiation 0 #987654321 auto axfr-get Ztest5:me.ns.test5.:hostmaster.test5.:987654321:16384:2048:1048576:2560:2560 &test5::me.ns.test5.:259200 +me.ns.test5:127.43.0.2:259200 +pick2.test5:127.43.0.102:86400 +pick3.test5:127.43.0.100:86400 +pick3.test5:127.43.0.102:86400 +\052.wild.test5:127.43.0.100:86400 +\052.wild.test5:127.43.0.102:86400 0 #987654321 auto axfr-get Ztest5:i3.ns.test5.:hostmaster.test5.:987654321:16384:2048:1048576:2560:2560 &test5::i3.ns.test5.:259200 +i3.ns.test5:127.43.0.2:259200 +pick3.test5:127.43.0.100:86400 +pick3.test5:127.43.0.103:86400 +\052.wild.test5:127.43.0.100:86400 +\052.wild.test5:127.43.0.103:86400 0 #987654321 auto axfr-get Ztest5:i4.ns.test5.:hostmaster.test5.:987654321:16384:2048:1048576:2560:2560 &test5::i4.ns.test5.:259200 +i4.ns.test5:127.43.0.2:259200 +pick3.test5:127.43.0.100:86400 +pick3.test5:127.43.0.104:86400 +\052.wild.test5:127.43.0.100:86400 +\052.wild.test5:127.43.0.104:86400 0 #987654321 auto axfr-get Ztest5:i5.ns.test5.:hostmaster.test5.:987654321:16384:2048:1048576:2560:2560 &test5::i5.ns.test5.:259200 +i5.ns.test5:127.43.0.2:259200 +pick3.test5:127.43.0.100:86400 +pick3.test5:127.43.0.105:86400 +\052.wild.test5:127.43.0.100:86400 +\052.wild.test5:127.43.0.105:86400 --- axfrdns gives authoritative answers 255 test4: 727 bytes, 1+12+0+0 records, response, authoritative, noerror query: 255 test4 answer: test4 2560 SOA ns.test4 hostmaster.test4 987654321 16384 2048 1048576 2560 answer: test4 259200 NS ns.test4 answer: test4 86400 16 3001234567890123456789012345678901234567890123456789 answer: test4 86400 16 3101234567890123456789012345678901234567890123456789 answer: test4 86400 16 3201234567890123456789012345678901234567890123456789 answer: test4 86400 16 3301234567890123456789012345678901234567890123456789 answer: test4 86400 16 3401234567890123456789012345678901234567890123456789 answer: test4 86400 16 3501234567890123456789012345678901234567890123456789 answer: test4 86400 16 3601234567890123456789012345678901234567890123456789 answer: test4 86400 16 3701234567890123456789012345678901234567890123456789 answer: test4 86400 16 3801234567890123456789012345678901234567890123456789 answer: test4 86400 16 3901234567890123456789012345678901234567890123456789 0 --- axfrdns handles size-1000 TXT records 255 big.test: 1046 bytes, 1+1+0+0 records, response, authoritative, noerror query: 255 big.test answer: big.test 86400 16 \1770123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456\1777890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123\1774567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\1771234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567\1778901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234\1775678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901\1772345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678o901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 0 --- axfr-get handles zones with wildcards 0 #987654321 auto axfr-get Ztest2:ns.test2.:hostmaster.test2.:987654321:16384:2048:1048576:2560:2560 &test2::ns.test2.:259200 +ns.test2:127.43.0.2:259200 +\052.test2:127.43.0.102:86400 C\052.www.test2:www.test2.:5000 +one.test2:127.43.0.103:86400 +two.test2:127.43.0.104:2 tinydyndns-0.4.2.debian1/rts.sh000066400000000000000000000000641103424076200163650ustar00rootroot00000000000000env - PATH="`pwd`:$PATH" sh rts.tests 2>&1 | cat -v tinydyndns-0.4.2.debian1/rts.tests000066400000000000000000000673201103424076200171250ustar00rootroot00000000000000# Requirements: # You are running as root. # You have dns{cache,log}, {tiny,pick,wall,axfr,rbl}dns accounts. # You have local IP addresses 127.43.0.{1,2,3,4,5}. # You are connected to the Internet. # # Some features not tested here: # dns_random works. # random-ip works. # dnstrace works. # dnstracesort works. # dns_resolvconfrewrite rereads after 10 minutes or 10000 uses. # dns_resolvconfip rereads after 10 minutes or 10000 uses. # /etc/resolv.conf is parsed properly. # dns_transmit handles timeouts properly. # dns_transmit falls back to TCP properly. # dns_transmit handles various strange situations: e.g., NOTIMP. umask 022 rm -rf rts-tmp service=`pwd`/rts-tmp/service mkdir rts-tmp mkdir $service echo ' *.b:.2.3.4 =localhost:localhost. -.localhost:localhost. ?:+.yp.to+.cr.yp.to+.whatever.cr.yp.to *.: ' > rts-tmp/rewrite DNSREWRITEFILE=rts-tmp/rewrite; export DNSREWRITEFILE DNSCACHEIP=127.555.0.1; export DNSCACHEIP echo '--- dnscache-conf works' dnscache-conf dnscache dnslog $service/dnscache 127.555.0.1 echo 127.555.0.2 > $service/dnscache/root/servers/tEST echo 127.555.0.2 > $service/dnscache/root/servers/tEST5 echo 127.555.0.4 > $service/dnscache/root/servers/43.127.iN-aDDR.aRPA touch $service/dnscache/root/ip/127.43.0.1 supervise $service/dnscache | supervise $service/dnscache/log & echo '--- tinydns-conf works' tinydns-conf tinydns dnslog $service/tinydns 127.555.0.2 supervise $service/tinydns | supervise $service/tinydns/log & echo '--- pickdns-conf works' pickdns-conf pickdns dnslog $service/pickdns 127.555.0.3 supervise $service/pickdns | supervise $service/pickdns/log & echo '--- walldns-conf works' walldns-conf walldns dnslog $service/walldns 127.555.0.4 supervise $service/walldns | supervise $service/walldns/log & echo '--- rbldns-conf works' rbldns-conf rbldns dnslog $service/rbldns 127.555.0.5 RbL.TeSt supervise $service/rbldns | supervise $service/rbldns/log & echo '--- axfrdns-conf works' axfrdns-conf axfrdns dnslog $service/axfrdns $service/tinydns 127.555.0.2 supervise $service/axfrdns | supervise $service/axfrdns/log & sleep 1 echo '--- cache handles simple example' cachetest \ one two three four five \ one:un one two three four five \ two:deux one two three four five \ three:trois one two three four five \ four:quatre one two three four five \ five:cinq one two three four five \ one:een one two three four five \ two:twee one two three four five \ three:drie one two three four five \ four:vier one two three four five \ five:vijf one two three four five echo $? echo '--- cache handles overwriting' cachetest \ one two three four five \ one:un one two three four five \ one:een one two three four five \ two:deux one two three four five \ two:twee one two three four five \ three:trois one two three four five \ three:drie one two three four five \ four:quatre one two three four five \ four:vier one two three four five \ five:cinq one two three four five \ five:vijf one two three four five echo $? echo '--- cache handles long chains' cachetest \ a:1 a \ a:2 a \ a:3 a \ a:4 a \ a:5 a \ a:6 a \ a:7 a \ a:8 a \ a:9 a echo $? echo '--- dnsip finds IP address of network-surveys.cr.yp.to' dnsip network-surveys.cr.yp.to echo $? echo '--- dnsip does not find nonexistent.cr.yp.to' dnsip nonexistent.cr.yp.to echo $? echo '--- dnsip rejects overly long domain names' dnsip x.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789 echo $? echo '--- dnsip handles IP address on input' dnsip 1.2.3.4 127.0.0.1 10.555.678.901 '[010.0555.0678.0901]' echo $? echo '--- dnsip allows 0 to be omitted' dnsip 127...1 echo $? echo '--- dnsip handles multiple IP addresses on input' dnsip 1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16 echo $? echo '--- dnsipq handles simple examples' dnsipq 1.b localhost anything.localhost 5.6.7.8 network-surveys nonexistent echo $? echo '--- dnsmx finds MX record for network-surveys.cr.yp.to' dnsmx network-surveys.cr.yp.to echo $? echo '--- dnsmx manufactures MX record for nonexistent.cr.yp.to' dnsmx NONexistent.cr.yp.to echo $? echo '--- dnsmx rejects overly long domain names' dnsmx 0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789 echo $? echo '--- dnstxt finds TXT record for leap.yp.to' dnstxt leap.yp.to echo $? echo '--- dnstxt does not find nonexistent.cr.yp.to' dnstxt nonexistent.cr.yp.to echo $? echo '--- dnstxt rejects overly long domain names' dnstxt 0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789.0123456789 echo $? echo '--- dnsname finds host name of 131.193.178.100' dnsname 131.193.178.100 echo $? echo '--- dnsname does not find 127.5.6.7' dnsname 127.5.6.7 echo $? echo '--- dnsname rejects misformatted IP addresses' dnsname 1.2.3 echo $? echo '--- dnsfilter finds some host names' echo '131.193.178.100+one two three 127.5.6.7+one two three 10+one two three' | dnsfilter echo $? echo ' =movie.edu:1.2.3.4 *star ' > rts-tmp/data echo '--- tinydns-data complains about unrecognized initial characters' ( cd rts-tmp; tinydns-data; echo $? ) echo ' .movie.edu:192.249.249.3:a .movie.edu::wormhole.movie.edu &fx.movie.edu:192.253.254.2:a &fx.movie.edu:192.253.254.3:b .249.249.192.in-addr.arpa:192.249.249.3:a .249.249.192.in-addr.arpa::wormhole.movie.edu .253.253.192.in-addr.arpa:192.249.249.3:a .253.253.192.in-addr.arpa:192.249.249.1:b .253.253.192.in-addr.arpa:192.253.253.1:c .254.253.192.in-addr.arpa:192.253.254.2:a .254.253.192.in-addr.arpa:192.253.254.3:b +localhost.movie.edu:127.0.0.1 @movie.edu:192.249.249.1:a '\''movie.edu:Movie University :movie.edu:12345:One :movie.edu:12345:Two :movie.edu:12346:Three :movie.edu:12346:Four =wormhole.movie.edu:192.249.249.1 +wh249.movie.edu:192.249.249.1 =robocop.movie.edu:192.249.249.2 =terminator.movie.edu:192.249.249.3 +bigt.movie.edu:192.249.249.3 =diehard.movie.edu:192.249.294.4 +dh.movie.edu:192.249.294.4 =wormhole.movie.edu:192.253.253.1 +wh253.movie.edu:192.253.253.1 +wh.movie.edu:192.253.253.1 +wh.movie.edu:192.253.253.1 =misery.movie.edu:192.253.253.2 =shining.movie.edu:192.253.253.3 =carrie.movie.edu:192.253.253.4 .blah.movie.edu:1.2.3.4:blah.movie.edu '\''blah.movie.edu:Text ' > rts-tmp/data utime rts-tmp/data 987654321 echo '--- tinydns-data complains if it cannot create data.tmp' rm -f rts-tmp/data.tmp ln -s data.tmp rts-tmp/data.tmp ( cd rts-tmp; tinydns-data; echo $? ) rm -f rts-tmp/data.tmp echo '--- tinydns-data handles simple example' ( cd rts-tmp; tinydns-data; echo $? ) echo '--- tinydns-data produces A records' ( cd rts-tmp; tinydns-get 1 wormhole.movie.edu | sort; echo $? ) echo '--- tinydns-data produces NS records' ( cd rts-tmp; tinydns-get 2 movie.edu; echo $? ) echo '--- tinydns-data produces SOA records' ( cd rts-tmp; tinydns-get 6 movie.edu; echo $? ) echo '--- tinydns-data produces PTR records' ( cd rts-tmp; tinydns-get 12 1.253.253.192.in-addr.arpa; echo $? ) echo '--- tinydns-data produces MX records' ( cd rts-tmp; tinydns-get 15 movie.edu; echo $? ) echo '--- tinydns-data produces TXT records' ( cd rts-tmp; tinydns-get 16 movie.edu; echo $? ) echo '--- tinydns-data produces AXFR responses' ( cd rts-tmp; tinydns-get 252 movie.edu; echo $? ) echo '--- tinydns-data produces ANY responses' ( cd rts-tmp; tinydns-get 255 movie.edu; echo $? ) echo '--- tinydns-data produces records of any type' ( cd rts-tmp; tinydns-get 12345 movie.edu; echo $? ) ( cd rts-tmp; tinydns-get 12346 movie.edu; echo $? ) echo '--- tinydns-data produces NODATA responses' ( cd rts-tmp; tinydns-get 54321 movie.edu; echo $? ) echo '--- tinydns-data produces NXDOMAIN responses' ( cd rts-tmp; tinydns-get 1 this.does.not.exist.movie.edu; echo $? ) echo '--- tinydns-data produces NXDOMAIN responses for suffixes' ( cd rts-tmp; tinydns-get 1 ns.movie.edu; echo $? ) echo '--- tinydns-data produces NXDOMAIN ANY responses for suffixes' ( cd rts-tmp; tinydns-get 255 ns.movie.edu; echo $? ) echo '--- tinydns-data does not produce responses outside its bailiwick' ( cd rts-tmp; tinydns-get 1 edu; echo $? ) echo '--- tinydns-data does not include TXT in additional sections' ( cd rts-tmp; tinydns-get 1 blah.movie.edu; echo $? ) echo ' .test:10.2.3.4:a +b.ns.test:10.2.3.6:259200 .test:10.2.3.5:b '\''127.test:0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456 '\''128.test:01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567 '\''254.test:01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123 '\''255.test:012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234 '\''387.test:012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456 '\''388.test:0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567 '\''400.test:0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 '\''410.test:01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 '\''420.test:012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 '\''430.test:0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 '\''435.test:012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234 '\''436.test:0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345 '\''1000.test:0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 =\000\001\177\200\277\.\.\..test:10.5.6.7 .7.6.5.10.in-addr.arpa:10.5.6.7 &x.\0\1\177\200\277\.\.\..test:10.8.9.10 ' > rts-tmp/data utime rts-tmp/data 0 echo '--- tinydns-data handles another example' ( cd rts-tmp; tinydns-data; echo $? ) echo '--- tinydns-data uses serial 1 for mtime 0' ( cd rts-tmp; tinydns-get Any test; echo $? ) echo '--- tinydns-data does not split size-127 TXT records' ( cd rts-tmp; tinydns-get Txt 127.test; echo $? ) echo '--- tinydns-data splits size-128 TXT records' ( cd rts-tmp; tinydns-get 16 128.test; echo $? ) echo '--- tinydns-data splits size-254 TXT records' ( cd rts-tmp; tinydns-get 16 254.test; echo $? ) echo '--- tinydns-data doubly splits size-255 TXT records' ( cd rts-tmp; tinydns-get 16 255.test; echo $? ) echo '--- tinydns-data excludes the additional section if necessary' ( cd rts-tmp; tinydns-get 16 387.test; echo $? ) ( cd rts-tmp; tinydns-get 16 388.test; echo $? ) echo '--- tinydns-data excludes the authority section if necessary' ( cd rts-tmp; tinydns-get 16 435.test; echo $? ) ( cd rts-tmp; tinydns-get 16 436.test; echo $? ) echo '--- tinydns-data handles size-1000 TXT records' ( cd rts-tmp; tinydns-get 16 1000.test; echo $? ) echo '--- tinydns-data handles unusual characters in owner names' ( cd rts-tmp; tinydns-get A '\0\1\177\200\277\56\56\56.test'; echo $? ) echo '--- tinydns-data handles unusual characters in PTR results' ( cd rts-tmp; tinydns-get Ptr 7.6.5.10.in-addr.arpa; echo $? ) echo '--- tinydns-data handles delegations' ( cd rts-tmp; tinydns-get 1 'x.\0\1\177\200\277\56\56\56.test'; echo $? ) ( cd rts-tmp; tinydns-get 1 'ns.x.\0\1\177\200\277\56\56\56.test'; echo $? ) ( cd rts-tmp; tinydns-get 1 'z.y.x.\0\1\177\200\277\56\56\56.test'; echo $? ) echo ' Ztest:Primary.Server:Host.Master:1234567:2345678:3456789:4567890:5678901:98765 &test:1.2.3.4::37 @*.wild.test:1.2.3.7:mail.wild.test:54321:46 &child.test:1.2.3.5::38 @test:1.2.3.4:::41 =test:1.2.3.4:39 +www.test:1.2.3.4:40 '\''test:Text:42 :test:12345:Binary:43 Cmail.test:www.test:44 +*.wild.test:1.2.3.6:45 =override.wild.test:1.2.3.8:47 +*.wild.wild.test:1.2.3.9:48 &child.wild.test:1.2.3.10:49 C*.alias.wild.test:wild.test:50 ' > rts-tmp/data utime rts-tmp/data 0 echo '--- tinydns-data handles another example' ( cd rts-tmp; tinydns-data; echo $? ) echo '--- tinydns-data handles TTLs' ( cd rts-tmp; tinydns-get 255 test; echo $? ) ( cd rts-tmp; tinydns-get 255 www.test; echo $? ) ( cd rts-tmp; tinydns-get 255 child.test; echo $? ) echo '--- tinydns-data handles CNAMEs' ( cd rts-tmp; tinydns-get 255 mail.test; echo $? ) ( cd rts-tmp; tinydns-get 5 mail.test; echo $? ) ( cd rts-tmp; tinydns-get 1 mail.test; echo $? ) ( cd rts-tmp; tinydns-get 255 foo.mail.test; echo $? ) echo '--- tinydns-data does not apply wildcard A to base name' ( cd rts-tmp; tinydns-get 1 wild.test; echo $? ) echo '--- tinydns-data handles wildcard A records' ( cd rts-tmp; tinydns-get 1 x.wild.test; echo $? ) ( cd rts-tmp; tinydns-get 1 xy.wild.test; echo $? ) ( cd rts-tmp; tinydns-get 1 x.z.wild.test; echo $? ) echo '--- tinydns-data handles wildcard MX records' ( cd rts-tmp; tinydns-get 255 wild.test; echo $? ) echo '--- tinydns-data does not apply wildcard MX to base name' ( cd rts-tmp; tinydns-get 255 x.wild.test; echo $? ) ( cd rts-tmp; tinydns-get 255 xy.wild.test; echo $? ) ( cd rts-tmp; tinydns-get 15 x.z.wild.test; echo $? ) ( cd rts-tmp; tinydns-get 255 x.z.wild.test; echo $? ) ( cd rts-tmp; tinydns-get 255 '*'.wild.test; echo $? ) echo '--- tinydns-data uses wildcard under base of sub-wildcard' ( cd rts-tmp; tinydns-get 255 alias.wild.test; echo $? ) echo '--- tinydns-data handles wildcard CNAME records' ( cd rts-tmp; tinydns-get 255 xyz.alias.wild.test; echo $? ) ( cd rts-tmp; tinydns-get 255 '*'.alias.wild.test; echo $? ) echo '--- tinydns-data lets explicit record override wildcard' ( cd rts-tmp; tinydns-get 255 override.wild.test; echo $? ) echo '--- tinydns-data handles overrides sanely' ( cd rts-tmp; tinydns-get 255 x.override.wild.test; echo $? ) echo '--- tinydns-data overrides wildcard with subdomain wildcard' ( cd rts-tmp; tinydns-get 255 x.wild.wild.test; echo $? ) echo '--- tinydns-data overrides wildcard with delegation' ( cd rts-tmp; tinydns-get 255 child.wild.test; echo $? ) ( cd rts-tmp; tinydns-get 255 x.child.wild.test; echo $? ) echo ' .four:1.2.3.4::0:30000000fedcba98 +www.four:1.2.3.4:0:30000000fedcba98 .five:1.2.3.5:::30000000fedcba98 +www.five:1.2.3.5::30000000fedcba98 .six:1.2.3.6::0:50000000fedcba98 +www.six:1.2.3.6:0:50000000fedcba98 .seven:1.2.3.7:::50000000fedcba98 +www.seven:1.2.3.7::50000000fedcba98 ' > rts-tmp/data utime rts-tmp/data 7654321 echo '--- tinydns-data handles another example' ( cd rts-tmp; tinydns-data; echo $? ) echo '--- tinydns-data handles ending time' ( cd rts-tmp; tinydns-get 255 www.four; echo $? ) ( cd rts-tmp; tinydns-get 255 www.six; echo $? ) echo '--- tinydns-data handles starting time' ( cd rts-tmp; tinydns-get 255 www.five; echo $? ) ( cd rts-tmp; tinydns-get 255 www.seven; echo $? ) echo '--- tinydns-edit handles simple examples' echo '' > rts-tmp/data ( cd rts-tmp; tinydns-edit data data.new add ns heaven.af.mil 1.2.3.5; echo $? ) ( cd rts-tmp; tinydns-edit data data.new add ns heaven.af.mil 1.2.3.6; echo $? ) ( cd rts-tmp; tinydns-edit data data.new add childns sub.heaven.af.mil 1.2.10.11; echo $? ) ( cd rts-tmp; tinydns-edit data data.new add childns sub.heaven.af.mil 1.2.10.12; echo $? ) ( cd rts-tmp; tinydns-edit data data.new add host lion.heaven.af.mil 1.2.3.4; echo $? ) ( cd rts-tmp; tinydns-edit data data.new add host tiger.heaven.af.mil 1.2.3.5; echo $? ) ( cd rts-tmp; tinydns-edit data data.new add host bear.heaven.af.mil 1.2.3.6; echo $? ) ( cd rts-tmp; tinydns-edit data data.new add alias www.heaven.af.mil 1.2.3.4; echo $? ) ( cd rts-tmp; tinydns-edit data data.new add mx heaven.af.mil 1.2.3.4; echo $? ) ( cd rts-tmp; tinydns-edit data data.new add mx heaven.af.mil 1.2.3.7; echo $? ) cat rts-tmp/data echo '--- tinydns-edit rejects hosts with old names or IP addresses' ( cd rts-tmp; tinydns-edit data data.new add host panda.heaven.af.mil 1.2.3.6; echo $? ) ( cd rts-tmp; tinydns-edit data data.new add host bear.heaven.af.mil 1.2.3.8; echo $? ) cat rts-tmp/data echo '--- tinydns-edit recognizes alternate forms of host names' ( cd rts-tmp; tinydns-edit data data.new add host 'BE\101r.Heaven.AF..Mil.' 1.2.3.8; echo $? ) cat rts-tmp/data echo '--- tinydns-edit copies TTLs from previous NS records' echo '.test:1.2.3.4:a:3600' > rts-tmp/data ( cd rts-tmp; tinydns-edit data data.new add ns test 1.2.3.5; echo $? ) cat rts-tmp/data echo ' .Test:127.555.0.2 =Www.Test:127.555.0.100 =Www.Test:127.555.0.101 @Test:127.555.0.100:a:1234 @Test:127.555.0.101:b:45678 &Pick.Test:127.555.0.3 &Pick2.Test:127.555.0.3 &Rbl.Test:127.555.0.5 .Test2:127.555.0.2 +*.Test2:127.555.0.102 C*.Www.Test2:Www.Test2:5000 =one.Test2:127.555.0.103::300000003456789a =two.Test2:127.555.0.104:0:500000003456789a .Test3:127.555.0.2 =Www.Test3:127.0.0.106 .Test4:127.555.0.2 '\''Test4:001234567890123456789012345678901234567890123456789 '\''Test4:101234567890123456789012345678901234567890123456789 '\''Test4:201234567890123456789012345678901234567890123456789 '\''Test4:301234567890123456789012345678901234567890123456789 '\''Test4:401234567890123456789012345678901234567890123456789 '\''Test4:501234567890123456789012345678901234567890123456789 '\''Test4:601234567890123456789012345678901234567890123456789 '\''Test4:701234567890123456789012345678901234567890123456789 '\''Test4:801234567890123456789012345678901234567890123456789 '\''Test4:901234567890123456789012345678901234567890123456789 '\''Big.Test:0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 %i3:127.555.0.3 %i4:127.555.0.4 %i5:127.555.0.5 %ME:127 %EX .Test5:127.555.0.2:ex:::EX .Test5:127.555.0.2:me:::ME .Test5:127.555.0.2:i3:::i3 .Test5:127.555.0.2:i4:::i4 .Test5:127.555.0.2:i5:::i5 -Pick.Test5:127.555.0.100:::EX +Pick.Test5:127.555.0.101:::EX -Pick2.Test5:127.555.0.102:::ME +Pick2.Test5:127.555.0.102:::ME +Pick3.Test5:127.555.0.100 +Pick3.Test5:127.555.0.101:::EX +Pick3.Test5:127.555.0.102:::ME +Pick3.Test5:127.555.0.103:::i3 +Pick3.Test5:127.555.0.104:::i4 +Pick3.Test5:127.555.0.105:::i5 +*.Wild.Test5:127.555.0.100 +*.Wild.Test5:127.555.0.101:::EX +*.Wild.Test5:127.555.0.102:::ME +*.Wild.Test5:127.555.0.103:::i3 +*.Wild.Test5:127.555.0.104:::i4 +*.Wild.Test5:127.555.0.105:::i5 ' > $service/tinydns/root/data utime $service/tinydns/root/data 987654321 ( cd $service/tinydns/root; tinydns-data ) echo ' -Pick.Test:127.555.0.100 +Pick.Test:127.555.0.101 -Pick2.Test:127.555.0.102:ME +Pick2.Test:127.555.0.102:ME %ME:127 ' > $service/pickdns/root/data ( cd $service/pickdns/root; pickdns-data ) echo ' 4.0.0.1 4.0.0.2/31 4.0.0.4/30 4.0.0.8/29 4.0.0.16/28 4.0.0.32/27 4.0.0.64/26 4.0.0.128/25 4.0.1.0/24 4.0.2.0/23 4.0.4.0/22 4.0.8.0/21 4.0.16.0/20 4.0.32.0/19 4.0.64.0/18 4.0.128.0/17 4.1.0.0/16 4.2.0.0/15 4.4.0.0/14 4.8.0.0/13 4.16.0.0/12 4.32.0.0/11 4.64.0.0/10 4.128.0.0/9 5.0.0.0/8 :127.0.0.3:See http://www.rbl.test/$ ' > $service/rbldns/root/data ( cd $service/rbldns/root; rbldns-data ) echo ' 127.:allow,AXFR="tEsT/TeSt2/TEst5" :deny ' > $service/axfrdns/tcp ( cd $service/axfrdns; tcprules tcp.cdb tcp.tmp < tcp ) echo '--- dnscache handles dotted-decimal names' dnsqr 255 127.43.123.234 echo $? echo '--- tinydns works' dnsip WWW.TEST | tr ' ' '\012' | sort echo $? dnsmx TEST echo $? dnsq 255 WWW.TEST 127.555.0.2 | sort echo $? dnsq Any TEST 127.555.0.2 echo $? echo '--- dnscache handles large TXT records' dnstxt BIG.Test echo '--- walldns handles in-addr.arpa names' dnsname 127.555.6.7 echo $? dnsname 127.555.123.234 echo $? dnsip 234.123.43.127.IN-ADDR.ARPA echo $? dnsq 255 234.123.43.127.IN-ADDR.ARPA 127.555.0.4 echo $? echo '--- walldns handles dotted-decimal names' dnsq 255 127.43.123.234 127.555.0.4 echo $? echo '--- walldns rejects other names' dnsq 255 BLAH.TEST 127.555.0.4 echo $? echo '--- rbldns works' dnsip 2.3.4.5.rbl.test echo $? dnstxt 2.3.4.5.rbl.test echo $? dnsq 255 2.3.4.5.rbl.test 127.555.0.5 echo $? dnsip 200.255.1.4.rbl.test echo $? dnstxt 200.255.1.4.rbl.test echo $? dnsq 255 200.255.1.4.rbl.test 127.555.0.5 echo $? dnsip 200.255.0.4.rbl.test echo $? dnstxt 200.255.0.4.rbl.test echo $? dnsq 255 200.255.0.4.rbl.test 127.555.0.5 echo $? dnsip 1.0.0.4.rbl.test echo $? dnstxt 1.0.0.4.rbl.test echo $? dnsq 255 1.0.0.4.rbl.test 127.555.0.5 echo $? dnsip 0.0.0.4.rbl.test echo $? dnstxt 0.0.0.4.rbl.test echo $? dnsq 255 0.0.0.4.rbl.test 127.555.0.5 echo $? echo '--- tinydns handles differentiation' dnsip PICK.TEST5 echo $? dnsip PICK2.TEST5 echo $? dnsip PICK3.TEST5 | tr ' ' '\012' | sort echo $? dnsip REALLY.WILD.TEST5 | tr ' ' '\012' | sort echo $? dnsq 255 PICK.TEST5 127.555.0.2 echo $? dnsq 255 PICK2.TEST5 127.555.0.2 echo $? dnsq 255 PICK3.TEST5 127.555.0.2 | sort echo $? dnsq 255 REALLY.WILD.TEST5 127.555.0.2 | sort echo $? echo '--- tinydns-get handles differentiation' ( cd rts-tmp/service/tinydns/root tinydns-get 255 PICK.TEST5 1.2.3.4; echo $? tinydns-get 255 PICK2.TEST5 1.2.3.4; echo $? tinydns-get 255 PICK3.TEST5 1.2.3.4 | sort; echo $? tinydns-get 255 REALLY.WILD.TEST5 1.2.3.4 | sort; echo $? tinydns-get 255 PICK.TEST5 127.555.0.4; echo $? tinydns-get 255 PICK2.TEST5 127.555.0.4; echo $? tinydns-get 255 PICK3.TEST5 127.555.0.4 | sort; echo $? tinydns-get 255 REALLY.WILD.TEST5 127.555.0.4 | sort; echo $? ) echo '--- pickdns works' dnsip PICK.TEST echo $? dnsip PICK2.TEST echo $? dnsq 255 PICK.TEST 127.555.0.3 echo $? echo '--- pickdns answers MX' dnsmx PICK.TEST echo $? echo '--- pickdns rejects queries for unknown information' dnsq 255 PICK11.TEST 127.555.0.3 echo $? dnsq Txt PICK2.TEST 127.555.0.3 echo $? echo '--- axfrdns rejects unauthorized transfer attempts' tcpclient -RHl0 127.43.0.2 53 axfr-get TEST3 rts-tmp/zone rts-tmp/zone.tmp echo $? tcpclient -RHl0 127.43.0.2 53 axfr-get TEST4 rts-tmp/zone2 rts-tmp/zone2.tmp echo $? echo '--- axfrdns works' tcpclient -RHl0 127.43.0.2 53 axfr-get TEST rts-tmp/zone rts-tmp/zone.tmp echo $? cat rts-tmp/zone echo '--- axfrdns handles differentiation' tcpclient -RHl0 -i 127.43.0.2 127.43.0.2 53 axfr-get TEST5 rts-tmp/zone5 rts-tmp/zone5.tmp echo $? cat rts-tmp/zone5 rm rts-tmp/zone5 tcpclient -RHl0 -i 127.43.0.3 127.43.0.2 53 axfr-get TEST5 rts-tmp/zone5 rts-tmp/zone5.tmp echo $? cat rts-tmp/zone5 rm rts-tmp/zone5 tcpclient -RHl0 -i 127.43.0.4 127.43.0.2 53 axfr-get TEST5 rts-tmp/zone5 rts-tmp/zone5.tmp echo $? cat rts-tmp/zone5 rm rts-tmp/zone5 tcpclient -RHl0 -i 127.43.0.5 127.43.0.2 53 axfr-get TEST5 rts-tmp/zone5 rts-tmp/zone5.tmp echo $? cat rts-tmp/zone5 echo '--- axfrdns gives authoritative answers' dnsq any Test4 127.43.0.2 echo $? echo '--- axfrdns handles size-1000 TXT records' dnsq any BIG.TEST 127.43.0.2 echo $? echo '--- axfr-get handles zones with wildcards' tcpclient -RHl0 127.43.0.2 53 axfr-get TEST2 rts-tmp/zone2 rts-tmp/zone2.tmp echo $? cat rts-tmp/zone2 svc -dx $service/dnscache svc -dx $service/tinydns svc -dx $service/pickdns svc -dx $service/walldns svc -dx $service/rbldns svc -dx $service/axfrdns svc -dx $service/dnscache/log svc -dx $service/tinydns/log svc -dx $service/pickdns/log svc -dx $service/walldns/log svc -dx $service/rbldns/log svc -dx $service/axfrdns/log wait wait wait wait wait wait exit 0 tinydyndns-0.4.2.debian1/scan.h000066400000000000000000000025571103424076200163270ustar00rootroot00000000000000#ifndef SCAN_H #define SCAN_H extern unsigned int scan_uint(const char *,unsigned int *); extern unsigned int scan_xint(const char *,unsigned int *); extern unsigned int scan_nbbint(const char *,unsigned int,unsigned int,unsigned int,unsigned int *); extern unsigned int scan_ushort(const char *,unsigned short *); extern unsigned int scan_xshort(const char *,unsigned short *); extern unsigned int scan_nbbshort(const char *,unsigned int,unsigned int,unsigned int,unsigned short *); extern unsigned int scan_ulong(const char *,unsigned long *); extern unsigned int scan_xlong(const char *,unsigned long *); extern unsigned int scan_nbblong(const char *,unsigned int,unsigned int,unsigned int,unsigned long *); extern unsigned int scan_plusminus(const char *,int *); extern unsigned int scan_0x(const char *,unsigned int *); extern unsigned int scan_whitenskip(const char *,unsigned int); extern unsigned int scan_nonwhitenskip(const char *,unsigned int); extern unsigned int scan_charsetnskip(const char *,const char *,unsigned int); extern unsigned int scan_noncharsetnskip(const char *,const char *,unsigned int); extern unsigned int scan_strncmp(const char *,const char *,unsigned int); extern unsigned int scan_memcmp(const char *,const char *,unsigned int); extern unsigned int scan_long(const char *,long *); extern unsigned int scan_8long(const char *,unsigned long *); #endif tinydyndns-0.4.2.debian1/scan_ulong.c000066400000000000000000000005231103424076200175150ustar00rootroot00000000000000#include "scan.h" unsigned int scan_ulong(register const char *s,register unsigned long *u) { register unsigned int pos = 0; register unsigned long result = 0; register unsigned long c; while ((c = (unsigned long) (unsigned char) (s[pos] - '0')) < 10) { result = result * 10 + c; ++pos; } *u = result; return pos; } tinydyndns-0.4.2.debian1/seek.h000066400000000000000000000004011103424076200163140ustar00rootroot00000000000000#ifndef SEEK_H #define SEEK_H typedef unsigned long seek_pos; extern seek_pos seek_cur(int); extern int seek_set(int,seek_pos); extern int seek_end(int); extern int seek_trunc(int,seek_pos); #define seek_begin(fd) (seek_set((fd),(seek_pos) 0)) #endif tinydyndns-0.4.2.debian1/seek_set.c000066400000000000000000000002441103424076200171670ustar00rootroot00000000000000#include #include "seek.h" #define SET 0 /* sigh */ int seek_set(int fd,seek_pos pos) { if (lseek(fd,(off_t) pos,SET) == -1) return -1; return 0; } tinydyndns-0.4.2.debian1/select.h1000066400000000000000000000002071103424076200167310ustar00rootroot00000000000000#ifndef SELECT_H #define SELECT_H /* sysdep: -sysselect */ #include #include extern int select(); #endif tinydyndns-0.4.2.debian1/select.h2000066400000000000000000000002371103424076200167350ustar00rootroot00000000000000#ifndef SELECT_H #define SELECT_H /* sysdep: +sysselect */ #include #include #include extern int select(); #endif tinydyndns-0.4.2.debian1/server.c000066400000000000000000000050301103424076200166710ustar00rootroot00000000000000#include "byte.h" #include "case.h" #include "env.h" #include "buffer.h" #include "strerr.h" #include "ip4.h" #include "uint16.h" #include "ndelay.h" #include "socket.h" #include "droproot.h" #include "qlog.h" #include "response.h" #include "dns.h" extern char *fatal; extern char *starting; extern int respond(char *,char *,char *); extern void initialize(void); static char ip[4]; static uint16 port; static char buf[513]; static int len; static char *q; static int doit(void) { unsigned int pos; char header[12]; char qtype[2]; char qclass[2]; if (len >= sizeof buf) goto NOQ; pos = dns_packet_copy(buf,len,0,header,12); if (!pos) goto NOQ; if (header[2] & 128) goto NOQ; if (header[4]) goto NOQ; if (header[5] != 1) goto NOQ; pos = dns_packet_getname(buf,len,pos,&q); if (!pos) goto NOQ; pos = dns_packet_copy(buf,len,pos,qtype,2); if (!pos) goto NOQ; pos = dns_packet_copy(buf,len,pos,qclass,2); if (!pos) goto NOQ; if (!response_query(q,qtype,qclass)) goto NOQ; response_id(header); if (byte_equal(qclass,2,DNS_C_IN)) response[2] |= 4; else if (byte_diff(qclass,2,DNS_C_ANY)) goto WEIRDCLASS; response[3] &= ~128; if (!(header[2] & 1)) response[2] &= ~1; if (header[2] & 126) goto NOTIMP; if (byte_equal(qtype,2,DNS_T_AXFR)) goto NOTIMP; case_lowerb(q,dns_domain_length(q)); if (!respond(q,qtype,ip)) { qlog(ip,port,header,q,qtype," - "); return 0; } qlog(ip,port,header,q,qtype," + "); return 1; NOTIMP: response[3] &= ~15; response[3] |= 4; qlog(ip,port,header,q,qtype," I "); return 1; WEIRDCLASS: response[3] &= ~15; response[3] |= 1; qlog(ip,port,header,q,qtype," C "); return 1; NOQ: qlog(ip,port,"\0\0","","\0\0"," / "); return 0; } int main() { char *x; int udp53; x = env_get("IP"); if (!x) strerr_die2x(111,fatal,"$IP not set"); if (!ip4_scan(x,ip)) strerr_die3x(111,fatal,"unable to parse IP address ",x); udp53 = socket_udp(); if (udp53 == -1) strerr_die2sys(111,fatal,"unable to create UDP socket: "); if (socket_bind4_reuse(udp53,ip,53) == -1) strerr_die2sys(111,fatal,"unable to bind UDP socket: "); droproot(fatal); initialize(); ndelay_off(udp53); socket_tryreservein(udp53,65536); buffer_putsflush(buffer_2,starting); for (;;) { len = socket_recv4(udp53,buf,sizeof buf,ip,&port); if (len < 0) continue; if (!doit()) continue; if (response_len > 512) response_tc(); socket_send4(udp53,response,response_len,ip,port); /* may block for buffer space; if it fails, too bad */ } } tinydyndns-0.4.2.debian1/sgetopt.c000066400000000000000000000023631103424076200170560ustar00rootroot00000000000000/* sgetopt.c, sgetopt.h: (yet another) improved getopt clone, outer layer D. J. Bernstein, djb@pobox.com. Depends on subgetopt.h, buffer.h. No system requirements. 19991219: Switched to buffer.h. 19970208: Cleanups. 931201: Baseline. No known patent problems. Documentation in sgetopt.3. */ #include "buffer.h" #define SGETOPTNOSHORT #include "sgetopt.h" #define SUBGETOPTNOSHORT #include "subgetopt.h" #define getopt sgetoptmine #define optind subgetoptind #define opterr sgetopterr #define optproblem subgetoptproblem #define optprogname sgetoptprogname int opterr = 1; const char *optprogname = 0; int getopt(int argc,char **argv,const char *opts) { int c; const char *s; if (!optprogname) { optprogname = *argv; if (!optprogname) optprogname = ""; for (s = optprogname;*s;++s) if (*s == '/') optprogname = s + 1; } c = subgetopt(argc,argv,opts); if (opterr) if (c == '?') { char chp[2]; chp[0] = optproblem; chp[1] = '\n'; buffer_puts(buffer_2,optprogname); if (argv[optind] && (optind < argc)) buffer_puts(buffer_2,": illegal option -- "); else buffer_puts(buffer_2,": option requires an argument -- "); buffer_put(buffer_2,chp,2); buffer_flush(buffer_2); } return c; } tinydyndns-0.4.2.debian1/sgetopt.h000066400000000000000000000006771103424076200170710ustar00rootroot00000000000000#ifndef SGETOPT_H #define SGETOPT_H #ifndef SGETOPTNOSHORT #define getopt sgetoptmine #define optarg subgetoptarg #define optind subgetoptind #define optpos subgetoptpos #define opterr sgetopterr #define optproblem subgetoptproblem #define optprogname sgetoptprogname #define opteof subgetoptdone #endif #include "subgetopt.h" extern int sgetoptmine(int,char **,const char *); extern int sgetopterr; extern const char *sgetoptprogname; #endif tinydyndns-0.4.2.debian1/socket.h000066400000000000000000000012111103424076200166550ustar00rootroot00000000000000#ifndef SOCKET_H #define SOCKET_H #include "uint16.h" extern int socket_tcp(void); extern int socket_udp(void); extern int socket_connect4(int,const char *,uint16); extern int socket_connected(int); extern int socket_bind4(int,char *,uint16); extern int socket_bind4_reuse(int,char *,uint16); extern int socket_listen(int,int); extern int socket_accept4(int,char *,uint16 *); extern int socket_recv4(int,char *,int,char *,uint16 *); extern int socket_send4(int,const char *,int,const char *,uint16); extern int socket_local4(int,char *,uint16 *); extern int socket_remote4(int,char *,uint16 *); extern void socket_tryreservein(int,int); #endif tinydyndns-0.4.2.debian1/socket_accept.c000066400000000000000000000006551103424076200202020ustar00rootroot00000000000000#include #include #include #include #include "byte.h" #include "socket.h" int socket_accept4(int s,char ip[4],uint16 *port) { struct sockaddr_in sa; int dummy = sizeof sa; int fd; fd = accept(s,(struct sockaddr *) &sa,&dummy); if (fd == -1) return -1; byte_copy(ip,4,(char *) &sa.sin_addr); uint16_unpack_big((char *) &sa.sin_port,port); return fd; } tinydyndns-0.4.2.debian1/socket_bind.c000066400000000000000000000013511103424076200176510ustar00rootroot00000000000000#include #include #include #include #include "byte.h" #include "socket.h" int socket_bind4(int s,char ip[4],uint16 port) { struct sockaddr_in sa; byte_zero(&sa,sizeof sa); sa.sin_family = AF_INET; uint16_pack_big((char *) &sa.sin_port,port); byte_copy((char *) &sa.sin_addr,4,ip); return bind(s,(struct sockaddr *) &sa,sizeof sa); } int socket_bind4_reuse(int s,char ip[4],uint16 port) { int opt = 1; setsockopt(s,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof opt); return socket_bind4(s,ip,port); } void socket_tryreservein(int s,int size) { while (size >= 1024) { if (setsockopt(s,SOL_SOCKET,SO_RCVBUF,&size,sizeof size) == 0) return; size -= (size >> 5); } } tinydyndns-0.4.2.debian1/socket_conn.c000066400000000000000000000012351103424076200176730ustar00rootroot00000000000000#include #include #include #include #include #include "byte.h" #include "socket.h" int socket_connect4(int s,const char ip[4],uint16 port) { struct sockaddr_in sa; byte_zero(&sa,sizeof sa); sa.sin_family = AF_INET; uint16_pack_big((char *) &sa.sin_port,port); byte_copy((char *) &sa.sin_addr,4,ip); return connect(s,(struct sockaddr *) &sa,sizeof sa); } int socket_connected(int s) { struct sockaddr_in sa; int dummy; char ch; dummy = sizeof sa; if (getpeername(s,(struct sockaddr *) &sa,&dummy) == -1) { read(s,&ch,1); /* sets errno */ return 0; } return 1; } tinydyndns-0.4.2.debian1/socket_listen.c000066400000000000000000000002701103424076200202320ustar00rootroot00000000000000#include #include #include #include #include "socket.h" int socket_listen(int s,int backlog) { return listen(s,backlog); } tinydyndns-0.4.2.debian1/socket_recv.c000066400000000000000000000007051103424076200176760ustar00rootroot00000000000000#include #include #include #include #include "byte.h" #include "socket.h" int socket_recv4(int s,char *buf,int len,char ip[4],uint16 *port) { struct sockaddr_in sa; int dummy = sizeof sa; int r; r = recvfrom(s,buf,len,0,(struct sockaddr *) &sa,&dummy); if (r == -1) return -1; byte_copy(ip,4,(char *) &sa.sin_addr); uint16_unpack_big((char *) &sa.sin_port,port); return r; } tinydyndns-0.4.2.debian1/socket_send.c000066400000000000000000000007001103424076200176630ustar00rootroot00000000000000#include #include #include #include #include "byte.h" #include "socket.h" int socket_send4(int s,const char *buf,int len,const char ip[4],uint16 port) { struct sockaddr_in sa; byte_zero(&sa,sizeof sa); sa.sin_family = AF_INET; uint16_pack_big((char *) &sa.sin_port,port); byte_copy((char *) &sa.sin_addr,4,ip); return sendto(s,buf,len,0,(struct sockaddr *) &sa,sizeof sa); } tinydyndns-0.4.2.debian1/socket_tcp.c000066400000000000000000000004741103424076200175300ustar00rootroot00000000000000#include #include #include #include #include #include "ndelay.h" #include "socket.h" int socket_tcp(void) { int s; s = socket(AF_INET,SOCK_STREAM,0); if (s == -1) return -1; if (ndelay_on(s) == -1) { close(s); return -1; } return s; } tinydyndns-0.4.2.debian1/socket_udp.c000066400000000000000000000004731103424076200175310ustar00rootroot00000000000000#include #include #include #include #include #include "ndelay.h" #include "socket.h" int socket_udp(void) { int s; s = socket(AF_INET,SOCK_DGRAM,0); if (s == -1) return -1; if (ndelay_on(s) == -1) { close(s); return -1; } return s; } tinydyndns-0.4.2.debian1/str.h000066400000000000000000000006561103424076200162110ustar00rootroot00000000000000#ifndef STR_H #define STR_H extern unsigned int str_copy(char *,const char *); extern int str_diff(const char *,const char *); extern int str_diffn(const char *,const char *,unsigned int); extern unsigned int str_len(const char *); extern unsigned int str_chr(const char *,int); extern unsigned int str_rchr(const char *,int); extern int str_start(const char *,const char *); #define str_equal(s,t) (!str_diff((s),(t))) #endif tinydyndns-0.4.2.debian1/str_chr.c000066400000000000000000000005441103424076200170340ustar00rootroot00000000000000#include "str.h" unsigned int str_chr(register const char *s,int c) { register char ch; register const char *t; ch = c; t = s; for (;;) { if (!*t) break; if (*t == ch) break; ++t; if (!*t) break; if (*t == ch) break; ++t; if (!*t) break; if (*t == ch) break; ++t; if (!*t) break; if (*t == ch) break; ++t; } return t - s; } tinydyndns-0.4.2.debian1/str_diff.c000066400000000000000000000006751103424076200171750ustar00rootroot00000000000000#include "str.h" int str_diff(register const char *s,register const char *t) { register char x; for (;;) { x = *s; if (x != *t) break; if (!x) break; ++s; ++t; x = *s; if (x != *t) break; if (!x) break; ++s; ++t; x = *s; if (x != *t) break; if (!x) break; ++s; ++t; x = *s; if (x != *t) break; if (!x) break; ++s; ++t; } return ((int)(unsigned int)(unsigned char) x) - ((int)(unsigned int)(unsigned char) *t); } tinydyndns-0.4.2.debian1/str_len.c000066400000000000000000000003571103424076200170400ustar00rootroot00000000000000#include "str.h" unsigned int str_len(const char *s) { register const char *t; t = s; for (;;) { if (!*t) return t - s; ++t; if (!*t) return t - s; ++t; if (!*t) return t - s; ++t; if (!*t) return t - s; ++t; } } tinydyndns-0.4.2.debian1/str_rchr.c000066400000000000000000000006311103424076200172130ustar00rootroot00000000000000#include "str.h" unsigned int str_rchr(register const char *s,int c) { register char ch; register const char *t; register const char *u; ch = c; t = s; u = 0; for (;;) { if (!*t) break; if (*t == ch) u = t; ++t; if (!*t) break; if (*t == ch) u = t; ++t; if (!*t) break; if (*t == ch) u = t; ++t; if (!*t) break; if (*t == ch) u = t; ++t; } if (!u) u = t; return u - s; } tinydyndns-0.4.2.debian1/str_start.c000066400000000000000000000005341103424076200174140ustar00rootroot00000000000000#include "str.h" int str_start(register const char *s,register const char *t) { register char x; for (;;) { x = *t++; if (!x) return 1; if (x != *s++) return 0; x = *t++; if (!x) return 1; if (x != *s++) return 0; x = *t++; if (!x) return 1; if (x != *s++) return 0; x = *t++; if (!x) return 1; if (x != *s++) return 0; } } tinydyndns-0.4.2.debian1/stralloc.h000066400000000000000000000022011103424076200172100ustar00rootroot00000000000000#ifndef STRALLOC_H #define STRALLOC_H #include "gen_alloc.h" GEN_ALLOC_typedef(stralloc,char,s,len,a) extern int stralloc_ready(stralloc *,unsigned int); extern int stralloc_readyplus(stralloc *,unsigned int); extern int stralloc_copy(stralloc *,const stralloc *); extern int stralloc_cat(stralloc *,const stralloc *); extern int stralloc_copys(stralloc *,const char *); extern int stralloc_cats(stralloc *,const char *); extern int stralloc_copyb(stralloc *,const char *,unsigned int); extern int stralloc_catb(stralloc *,const char *,unsigned int); extern int stralloc_append(stralloc *,const char *); /* beware: this takes a pointer to 1 char */ extern int stralloc_starts(stralloc *,const char *); #define stralloc_0(sa) stralloc_append(sa,"") extern int stralloc_catulong0(stralloc *,unsigned long,unsigned int); extern int stralloc_catlong0(stralloc *,long,unsigned int); #define stralloc_catlong(sa,l) (stralloc_catlong0((sa),(l),0)) #define stralloc_catuint0(sa,i,n) (stralloc_catulong0((sa),(i),(n))) #define stralloc_catint0(sa,i,n) (stralloc_catlong0((sa),(i),(n))) #define stralloc_catint(sa,i) (stralloc_catlong0((sa),(i),0)) #endif tinydyndns-0.4.2.debian1/stralloc_cat.c000066400000000000000000000002311103424076200200330ustar00rootroot00000000000000#include "byte.h" #include "stralloc.h" int stralloc_cat(stralloc *sato,const stralloc *safrom) { return stralloc_catb(sato,safrom->s,safrom->len); } tinydyndns-0.4.2.debian1/stralloc_catb.c000066400000000000000000000004741103424076200202060ustar00rootroot00000000000000#include "stralloc.h" #include "byte.h" int stralloc_catb(stralloc *sa,const char *s,unsigned int n) { if (!sa->s) return stralloc_copyb(sa,s,n); if (!stralloc_readyplus(sa,n + 1)) return 0; byte_copy(sa->s + sa->len,n,s); sa->len += n; sa->s[sa->len] = 'Z'; /* ``offensive programming'' */ return 1; } tinydyndns-0.4.2.debian1/stralloc_cats.c000066400000000000000000000002251103424076200202210ustar00rootroot00000000000000#include "byte.h" #include "str.h" #include "stralloc.h" int stralloc_cats(stralloc *sa,const char *s) { return stralloc_catb(sa,s,str_len(s)); } tinydyndns-0.4.2.debian1/stralloc_copy.c000066400000000000000000000002331103424076200202400ustar00rootroot00000000000000#include "byte.h" #include "stralloc.h" int stralloc_copy(stralloc *sato,const stralloc *safrom) { return stralloc_copyb(sato,safrom->s,safrom->len); } tinydyndns-0.4.2.debian1/stralloc_eady.c000066400000000000000000000003131103424076200202070ustar00rootroot00000000000000#include "alloc.h" #include "stralloc.h" #include "gen_allocdefs.h" GEN_ALLOC_ready(stralloc,char,s,len,a,i,n,x,30,stralloc_ready) GEN_ALLOC_readyplus(stralloc,char,s,len,a,i,n,x,30,stralloc_readyplus) tinydyndns-0.4.2.debian1/stralloc_num.c000066400000000000000000000010531103424076200200660ustar00rootroot00000000000000#include "stralloc.h" int stralloc_catulong0(stralloc *sa,unsigned long u,unsigned int n) { unsigned int len; unsigned long q; char *s; len = 1; q = u; while (q > 9) { ++len; q /= 10; } if (len < n) len = n; if (!stralloc_readyplus(sa,len)) return 0; s = sa->s + sa->len; sa->len += len; while (len) { s[--len] = '0' + (u % 10); u /= 10; } return 1; } int stralloc_catlong0(stralloc *sa,long l,unsigned int n) { if (l < 0) { if (!stralloc_append(sa,"-")) return 0; l = -l; } return stralloc_catulong0(sa,l,n); } tinydyndns-0.4.2.debian1/stralloc_opyb.c000066400000000000000000000003731103424076200202440ustar00rootroot00000000000000#include "stralloc.h" #include "byte.h" int stralloc_copyb(stralloc *sa,const char *s,unsigned int n) { if (!stralloc_ready(sa,n + 1)) return 0; byte_copy(sa->s,n,s); sa->len = n; sa->s[n] = 'Z'; /* ``offensive programming'' */ return 1; } tinydyndns-0.4.2.debian1/stralloc_opys.c000066400000000000000000000002271103424076200202630ustar00rootroot00000000000000#include "byte.h" #include "str.h" #include "stralloc.h" int stralloc_copys(stralloc *sa,const char *s) { return stralloc_copyb(sa,s,str_len(s)); } tinydyndns-0.4.2.debian1/stralloc_pend.c000066400000000000000000000002311103424076200202120ustar00rootroot00000000000000#include "alloc.h" #include "stralloc.h" #include "gen_allocdefs.h" GEN_ALLOC_append(stralloc,char,s,len,a,i,n,x,30,stralloc_readyplus,stralloc_append) tinydyndns-0.4.2.debian1/strerr.h000066400000000000000000000052741103424076200167230ustar00rootroot00000000000000#ifndef STRERR_H #define STRERR_H struct strerr { struct strerr *who; const char *x; const char *y; const char *z; } ; extern struct strerr strerr_sys; extern void strerr_sysinit(void); extern const char *strerr(const struct strerr *); extern void strerr_warn(const char *,const char *,const char *,const char *,const char *,const char *,const struct strerr *); extern void strerr_die(int,const char *,const char *,const char *,const char *,const char *,const char *,const struct strerr *); #define STRERR(r,se,a) \ { se.who = 0; se.x = a; se.y = 0; se.z = 0; return r; } #define STRERR_SYS(r,se,a) \ { se.who = &strerr_sys; se.x = a; se.y = 0; se.z = 0; return r; } #define STRERR_SYS3(r,se,a,b,c) \ { se.who = &strerr_sys; se.x = a; se.y = b; se.z = c; return r; } #define strerr_warn6(x1,x2,x3,x4,x5,x6,se) \ strerr_warn((x1),(x2),(x3),(x4),(x5),(x6),(se)) #define strerr_warn5(x1,x2,x3,x4,x5,se) \ strerr_warn((x1),(x2),(x3),(x4),(x5),0,(se)) #define strerr_warn4(x1,x2,x3,x4,se) \ strerr_warn((x1),(x2),(x3),(x4),0,0,(se)) #define strerr_warn3(x1,x2,x3,se) \ strerr_warn((x1),(x2),(x3),0,0,0,(se)) #define strerr_warn2(x1,x2,se) \ strerr_warn((x1),(x2),0,0,0,0,(se)) #define strerr_warn1(x1,se) \ strerr_warn((x1),0,0,0,0,0,(se)) #define strerr_die6(e,x1,x2,x3,x4,x5,x6,se) \ strerr_die((e),(x1),(x2),(x3),(x4),(x5),(x6),(se)) #define strerr_die5(e,x1,x2,x3,x4,x5,se) \ strerr_die((e),(x1),(x2),(x3),(x4),(x5),0,(se)) #define strerr_die4(e,x1,x2,x3,x4,se) \ strerr_die((e),(x1),(x2),(x3),(x4),0,0,(se)) #define strerr_die3(e,x1,x2,x3,se) \ strerr_die((e),(x1),(x2),(x3),0,0,0,(se)) #define strerr_die2(e,x1,x2,se) \ strerr_die((e),(x1),(x2),0,0,0,0,(se)) #define strerr_die1(e,x1,se) \ strerr_die((e),(x1),0,0,0,0,0,(se)) #define strerr_die6sys(e,x1,x2,x3,x4,x5,x6) \ strerr_die((e),(x1),(x2),(x3),(x4),(x5),(x6),&strerr_sys) #define strerr_die5sys(e,x1,x2,x3,x4,x5) \ strerr_die((e),(x1),(x2),(x3),(x4),(x5),0,&strerr_sys) #define strerr_die4sys(e,x1,x2,x3,x4) \ strerr_die((e),(x1),(x2),(x3),(x4),0,0,&strerr_sys) #define strerr_die3sys(e,x1,x2,x3) \ strerr_die((e),(x1),(x2),(x3),0,0,0,&strerr_sys) #define strerr_die2sys(e,x1,x2) \ strerr_die((e),(x1),(x2),0,0,0,0,&strerr_sys) #define strerr_die1sys(e,x1) \ strerr_die((e),(x1),0,0,0,0,0,&strerr_sys) #define strerr_die6x(e,x1,x2,x3,x4,x5,x6) \ strerr_die((e),(x1),(x2),(x3),(x4),(x5),(x6),0) #define strerr_die5x(e,x1,x2,x3,x4,x5) \ strerr_die((e),(x1),(x2),(x3),(x4),(x5),0,0) #define strerr_die4x(e,x1,x2,x3,x4) \ strerr_die((e),(x1),(x2),(x3),(x4),0,0,0) #define strerr_die3x(e,x1,x2,x3) \ strerr_die((e),(x1),(x2),(x3),0,0,0,0) #define strerr_die2x(e,x1,x2) \ strerr_die((e),(x1),(x2),0,0,0,0,0) #define strerr_die1x(e,x1) \ strerr_die((e),(x1),0,0,0,0,0,0) #endif tinydyndns-0.4.2.debian1/strerr_die.c000066400000000000000000000015241103424076200175310ustar00rootroot00000000000000#include "buffer.h" #include "exit.h" #include "strerr.h" void strerr_warn(const char *x1,const char *x2,const char *x3,const char *x4,const char *x5,const char *x6,const struct strerr *se) { strerr_sysinit(); if (x1) buffer_puts(buffer_2,x1); if (x2) buffer_puts(buffer_2,x2); if (x3) buffer_puts(buffer_2,x3); if (x4) buffer_puts(buffer_2,x4); if (x5) buffer_puts(buffer_2,x5); if (x6) buffer_puts(buffer_2,x6); while(se) { if (se->x) buffer_puts(buffer_2,se->x); if (se->y) buffer_puts(buffer_2,se->y); if (se->z) buffer_puts(buffer_2,se->z); se = se->who; } buffer_puts(buffer_2,"\n"); buffer_flush(buffer_2); } void strerr_die(int e,const char *x1,const char *x2,const char *x3,const char *x4,const char *x5,const char *x6,const struct strerr *se) { strerr_warn(x1,x2,x3,x4,x5,x6,se); _exit(e); } tinydyndns-0.4.2.debian1/strerr_sys.c000066400000000000000000000003041103424076200176010ustar00rootroot00000000000000#include "error.h" #include "strerr.h" struct strerr strerr_sys; void strerr_sysinit(void) { strerr_sys.who = 0; strerr_sys.x = error_str(errno); strerr_sys.y = ""; strerr_sys.z = ""; } tinydyndns-0.4.2.debian1/subgetopt.c000066400000000000000000000025341103424076200174050ustar00rootroot00000000000000#define SUBGETOPTNOSHORT #include "subgetopt.h" #define sgopt subgetopt #define optind subgetoptind #define optpos subgetoptpos #define optarg subgetoptarg #define optproblem subgetoptproblem #define optdone subgetoptdone int optind = 1; int optpos = 0; char *optarg = 0; int optproblem = 0; int optdone = SUBGETOPTDONE; int sgopt(int argc,char **argv,const char *opts) { int c; const char *s; optarg = 0; if (!argv || (optind >= argc) || !argv[optind]) return optdone; if (optpos && !argv[optind][optpos]) { ++optind; optpos = 0; if ((optind >= argc) || !argv[optind]) return optdone; } if (!optpos) { if (argv[optind][0] != '-') return optdone; ++optpos; c = argv[optind][1]; if ((c == '-') || (c == 0)) { if (c) ++optind; optpos = 0; return optdone; } /* otherwise c is reassigned below */ } c = argv[optind][optpos]; ++optpos; s = opts; while (*s) { if (c == *s) { if (s[1] == ':') { optarg = argv[optind] + optpos; ++optind; optpos = 0; if (!*optarg) { optarg = argv[optind]; if ((optind >= argc) || !optarg) { /* argument past end */ optproblem = c; return '?'; } ++optind; } } return c; } ++s; if (*s == ':') ++s; } optproblem = c; return '?'; } tinydyndns-0.4.2.debian1/subgetopt.h000066400000000000000000000010401103424076200174010ustar00rootroot00000000000000#ifndef SUBGETOPT_H #define SUBGETOPT_H #ifndef SUBGETOPTNOSHORT #define sgopt subgetopt #define sgoptarg subgetoptarg #define sgoptind subgetoptind #define sgoptpos subgetoptpos #define sgoptproblem subgetoptproblem #define sgoptprogname subgetoptprogname #define sgoptdone subgetoptdone #endif #define SUBGETOPTDONE -1 extern int subgetopt(int,char **,const char *); extern char *subgetoptarg; extern int subgetoptind; extern int subgetoptpos; extern int subgetoptproblem; extern char *subgetoptprogname; extern int subgetoptdone; #endif tinydyndns-0.4.2.debian1/tai.h000066400000000000000000000011341103424076200161460ustar00rootroot00000000000000#ifndef TAI_H #define TAI_H #include "uint64.h" struct tai { uint64 x; } ; #define tai_unix(t,u) ((void) ((t)->x = 4611686018427387914ULL + (uint64) (u))) extern void tai_now(struct tai *); #define tai_approx(t) ((double) ((t)->x)) extern void tai_add(struct tai *,const struct tai *,const struct tai *); extern void tai_sub(struct tai *,const struct tai *,const struct tai *); #define tai_less(t,u) ((t)->x < (u)->x) #define TAI_PACK 8 extern void tai_pack(char *,const struct tai *); extern void tai_unpack(const char *,struct tai *); extern void tai_uint(struct tai *,unsigned int); #endif tinydyndns-0.4.2.debian1/tai_add.c000066400000000000000000000001601103424076200167470ustar00rootroot00000000000000#include "tai.h" void tai_add(struct tai *t,const struct tai *u,const struct tai *v) { t->x = u->x + v->x; } tinydyndns-0.4.2.debian1/tai_now.c000066400000000000000000000001461103424076200170260ustar00rootroot00000000000000#include #include "tai.h" void tai_now(struct tai *t) { tai_unix(t,time((time_t *) 0)); } tinydyndns-0.4.2.debian1/tai_pack.c000066400000000000000000000004431103424076200171410ustar00rootroot00000000000000#include "tai.h" void tai_pack(char *s,const struct tai *t) { uint64 x; x = t->x; s[7] = x & 255; x >>= 8; s[6] = x & 255; x >>= 8; s[5] = x & 255; x >>= 8; s[4] = x & 255; x >>= 8; s[3] = x & 255; x >>= 8; s[2] = x & 255; x >>= 8; s[1] = x & 255; x >>= 8; s[0] = x; } tinydyndns-0.4.2.debian1/tai_sub.c000066400000000000000000000001601103424076200170100ustar00rootroot00000000000000#include "tai.h" void tai_sub(struct tai *t,const struct tai *u,const struct tai *v) { t->x = u->x - v->x; } tinydyndns-0.4.2.debian1/tai_uint.c000066400000000000000000000001161103424076200171770ustar00rootroot00000000000000#include "tai.h" void tai_uint(struct tai *t,unsigned int u) { t->x = u; } tinydyndns-0.4.2.debian1/tai_unpack.c000066400000000000000000000006021103424076200175010ustar00rootroot00000000000000#include "tai.h" void tai_unpack(const char *s,struct tai *t) { uint64 x; x = (unsigned char) s[0]; x <<= 8; x += (unsigned char) s[1]; x <<= 8; x += (unsigned char) s[2]; x <<= 8; x += (unsigned char) s[3]; x <<= 8; x += (unsigned char) s[4]; x <<= 8; x += (unsigned char) s[5]; x <<= 8; x += (unsigned char) s[6]; x <<= 8; x += (unsigned char) s[7]; t->x = x; } tinydyndns-0.4.2.debian1/taia.h000066400000000000000000000017141103424076200163130ustar00rootroot00000000000000#ifndef TAIA_H #define TAIA_H #include "tai.h" struct taia { struct tai sec; unsigned long nano; /* 0...999999999 */ unsigned long atto; /* 0...999999999 */ } ; extern void taia_tai(const struct taia *,struct tai *); extern void taia_now(struct taia *); extern double taia_approx(const struct taia *); extern double taia_frac(const struct taia *); extern void taia_add(struct taia *,const struct taia *,const struct taia *); extern void taia_addsec(struct taia *,const struct taia *,int); extern void taia_sub(struct taia *,const struct taia *,const struct taia *); extern void taia_half(struct taia *,const struct taia *); extern int taia_less(const struct taia *,const struct taia *); #define TAIA_PACK 16 extern void taia_pack(char *,const struct taia *); extern void taia_unpack(const char *,struct taia *); #define TAIA_FMTFRAC 19 extern unsigned int taia_fmtfrac(char *,const struct taia *); extern void taia_uint(struct taia *,unsigned int); #endif tinydyndns-0.4.2.debian1/taia_add.c000066400000000000000000000006031103424076200171120ustar00rootroot00000000000000#include "taia.h" /* XXX: breaks tai encapsulation */ void taia_add(struct taia *t,const struct taia *u,const struct taia *v) { t->sec.x = u->sec.x + v->sec.x; t->nano = u->nano + v->nano; t->atto = u->atto + v->atto; if (t->atto > 999999999UL) { t->atto -= 1000000000UL; ++t->nano; } if (t->nano > 999999999UL) { t->nano -= 1000000000UL; ++t->sec.x; } } tinydyndns-0.4.2.debian1/taia_approx.c000066400000000000000000000001551103424076200176750ustar00rootroot00000000000000#include "taia.h" double taia_approx(const struct taia *t) { return tai_approx(&t->sec) + taia_frac(t); } tinydyndns-0.4.2.debian1/taia_frac.c000066400000000000000000000001701103424076200172740ustar00rootroot00000000000000#include "taia.h" double taia_frac(const struct taia *t) { return (t->atto * 0.000000001 + t->nano) * 0.000000001; } tinydyndns-0.4.2.debian1/taia_less.c000066400000000000000000000004411103424076200173300ustar00rootroot00000000000000#include "taia.h" /* XXX: breaks tai encapsulation */ int taia_less(const struct taia *t,const struct taia *u) { if (t->sec.x < u->sec.x) return 1; if (t->sec.x > u->sec.x) return 0; if (t->nano < u->nano) return 1; if (t->nano > u->nano) return 0; return t->atto < u->atto; } tinydyndns-0.4.2.debian1/taia_now.c000066400000000000000000000003711103424076200171670ustar00rootroot00000000000000#include #include #include "taia.h" void taia_now(struct taia *t) { struct timeval now; gettimeofday(&now,(struct timezone *) 0); tai_unix(&t->sec,now.tv_sec); t->nano = 1000 * now.tv_usec + 500; t->atto = 0; } tinydyndns-0.4.2.debian1/taia_pack.c000066400000000000000000000005221103424076200173000ustar00rootroot00000000000000#include "taia.h" void taia_pack(char *s,const struct taia *t) { unsigned long x; tai_pack(s,&t->sec); s += 8; x = t->atto; s[7] = x & 255; x >>= 8; s[6] = x & 255; x >>= 8; s[5] = x & 255; x >>= 8; s[4] = x; x = t->nano; s[3] = x & 255; x >>= 8; s[2] = x & 255; x >>= 8; s[1] = x & 255; x >>= 8; s[0] = x; } tinydyndns-0.4.2.debian1/taia_sub.c000066400000000000000000000006701103424076200171570ustar00rootroot00000000000000#include "taia.h" /* XXX: breaks tai encapsulation */ void taia_sub(struct taia *t,const struct taia *u,const struct taia *v) { unsigned long unano = u->nano; unsigned long uatto = u->atto; t->sec.x = u->sec.x - v->sec.x; t->nano = unano - v->nano; t->atto = uatto - v->atto; if (t->atto > uatto) { t->atto += 1000000000UL; --t->nano; } if (t->nano > unano) { t->nano += 1000000000UL; --t->sec.x; } } tinydyndns-0.4.2.debian1/taia_tai.c000066400000000000000000000001321103424076200171340ustar00rootroot00000000000000#include "taia.h" void taia_tai(const struct taia *ta,struct tai *t) { *t = ta->sec; } tinydyndns-0.4.2.debian1/taia_uint.c000066400000000000000000000002301103424076200173350ustar00rootroot00000000000000#include "taia.h" /* XXX: breaks tai encapsulation */ void taia_uint(struct taia *t,unsigned int s) { t->sec.x = s; t->nano = 0; t->atto = 0; } tinydyndns-0.4.2.debian1/tdlookup.c000066400000000000000000000167521103424076200172410ustar00rootroot00000000000000#include #include "uint16.h" #include "open.h" #include "tai.h" #include "cdb.h" #include "byte.h" #include "case.h" #include "dns.h" #include "seek.h" #include "response.h" static int want(const char *owner,const char type[2]) { unsigned int pos; static char *d; char x[10]; uint16 datalen; pos = dns_packet_skipname(response,response_len,12); if (!pos) return 0; pos += 4; while (pos < response_len) { pos = dns_packet_getname(response,response_len,pos,&d); if (!pos) return 0; pos = dns_packet_copy(response,response_len,pos,x,10); if (!pos) return 0; if (dns_domain_equal(d,owner)) if (byte_equal(type,2,x)) return 0; uint16_unpack_big(x + 8,&datalen); pos += datalen; } return 1; } static char *d1; static char clientloc[2]; static struct tai now; static struct cdb c; static char data[32767]; static uint32 dlen; static unsigned int dpos; static char type[2]; static uint32 ttl; static int find(char *d,int flagwild) { int r; char ch; struct tai cutoff; char ttd[8]; char ttlstr[4]; char recordloc[2]; double newttl; for (;;) { r = cdb_findnext(&c,d,dns_domain_length(d)); if (r <= 0) return r; dlen = cdb_datalen(&c); if (dlen > sizeof data) return -1; if (cdb_read(&c,data,dlen,cdb_datapos(&c)) == -1) return -1; dpos = dns_packet_copy(data,dlen,0,type,2); if (!dpos) return -1; dpos = dns_packet_copy(data,dlen,dpos,&ch,1); if (!dpos) return -1; if ((ch == '=' + 1) || (ch == '*' + 1)) { --ch; dpos = dns_packet_copy(data,dlen,dpos,recordloc,2); if (!dpos) return -1; if (byte_diff(recordloc,2,clientloc)) continue; } if (flagwild != (ch == '*')) continue; dpos = dns_packet_copy(data,dlen,dpos,ttlstr,4); if (!dpos) return -1; uint32_unpack_big(ttlstr,&ttl); dpos = dns_packet_copy(data,dlen,dpos,ttd,8); if (!dpos) return -1; if (byte_diff(ttd,8,"\0\0\0\0\0\0\0\0")) { tai_unpack(ttd,&cutoff); if (ttl == 0) { if (tai_less(&cutoff,&now)) continue; tai_sub(&cutoff,&cutoff,&now); newttl = tai_approx(&cutoff); if (newttl <= 2.0) newttl = 2.0; if (newttl >= 3600.0) newttl = 3600.0; ttl = newttl; } else if (!tai_less(&cutoff,&now)) continue; } return 1; } } static int dobytes(unsigned int len) { char buf[20]; if (len > 20) return 0; dpos = dns_packet_copy(data,dlen,dpos,buf,len); if (!dpos) return 0; return response_addbytes(buf,len); } static int doname(void) { dpos = dns_packet_getname(data,dlen,dpos,&d1); if (!dpos) return 0; return response_addname(d1); } static int doit(char *q,char qtype[2]) { unsigned int bpos; unsigned int anpos; unsigned int aupos; unsigned int arpos; char *control; char *wild; int flaggavesoa; int flagfound; int r; int flagns; int flagauthoritative; char x[20]; uint16 u16; char addr[8][4]; int addrnum; uint32 addrttl; int i; anpos = response_len; control = q; for (;;) { flagns = 0; flagauthoritative = 0; cdb_findstart(&c); while (r = find(control,0)) { if (r == -1) return 0; if (byte_equal(type,2,DNS_T_SOA)) flagauthoritative = 1; if (byte_equal(type,2,DNS_T_NS)) flagns = 1; } if (flagns) break; if (!*control) return 0; /* q is not within our bailiwick */ control += *control; control += 1; } if (!flagauthoritative) { response[2] &= ~4; goto AUTHORITY; /* q is in a child zone */ } flaggavesoa = 0; flagfound = 0; wild = q; for (;;) { addrnum = 0; addrttl = 0; cdb_findstart(&c); while (r = find(wild,wild != q)) { if (r == -1) return 0; flagfound = 1; if (flaggavesoa && byte_equal(type,2,DNS_T_SOA)) continue; if (byte_diff(type,2,qtype) && byte_diff(qtype,2,DNS_T_ANY) && byte_diff(type,2,DNS_T_CNAME)) continue; if (byte_equal(type,2,DNS_T_A) && (dlen - dpos == 4)) { addrttl = ttl; i = dns_random(addrnum + 1); if (i < 8) { if ((i < addrnum) && (addrnum < 8)) byte_copy(addr[addrnum],4,addr[i]); byte_copy(addr[i],4,data + dpos); } if (addrnum < 1000000) ++addrnum; continue; } if (!response_rstart(q,type,ttl)) return 0; if (byte_equal(type,2,DNS_T_NS) || byte_equal(type,2,DNS_T_CNAME) || byte_equal(type,2,DNS_T_PTR)) { if (!doname()) return 0; } else if (byte_equal(type,2,DNS_T_MX)) { if (!dobytes(2)) return 0; if (!doname()) return 0; } else if (byte_equal(type,2,DNS_T_SOA)) { if (!doname()) return 0; if (!doname()) return 0; if (!dobytes(20)) return 0; flaggavesoa = 1; } else if (!response_addbytes(data + dpos,dlen - dpos)) return 0; response_rfinish(RESPONSE_ANSWER); } for (i = 0;i < addrnum;++i) if (i < 8) { if (!response_rstart(q,DNS_T_A,addrttl)) return 0; if (!response_addbytes(addr[i],4)) return 0; response_rfinish(RESPONSE_ANSWER); } if (flagfound) break; if (wild == control) break; if (!*wild) break; /* impossible */ wild += *wild; wild += 1; } if (!flagfound) response_nxdomain(); AUTHORITY: aupos = response_len; if (flagauthoritative && (aupos == anpos)) { cdb_findstart(&c); while (r = find(control,0)) { if (r == -1) return 0; if (byte_equal(type,2,DNS_T_SOA)) { if (!response_rstart(control,DNS_T_SOA,ttl)) return 0; if (!doname()) return 0; if (!doname()) return 0; if (!dobytes(20)) return 0; response_rfinish(RESPONSE_AUTHORITY); break; } } } else if (want(control,DNS_T_NS)) { cdb_findstart(&c); while (r = find(control,0)) { if (r == -1) return 0; if (byte_equal(type,2,DNS_T_NS)) { if (!response_rstart(control,DNS_T_NS,ttl)) return 0; if (!doname()) return 0; response_rfinish(RESPONSE_AUTHORITY); } } } arpos = response_len; bpos = anpos; while (bpos < arpos) { bpos = dns_packet_skipname(response,arpos,bpos); if (!bpos) return 0; bpos = dns_packet_copy(response,arpos,bpos,x,10); if (!bpos) return 0; if (byte_equal(x,2,DNS_T_NS) || byte_equal(x,2,DNS_T_MX)) { if (byte_equal(x,2,DNS_T_NS)) { if (!dns_packet_getname(response,arpos,bpos,&d1)) return 0; } else if (!dns_packet_getname(response,arpos,bpos + 2,&d1)) return 0; case_lowerb(d1,dns_domain_length(d1)); if (want(d1,DNS_T_A)) { cdb_findstart(&c); while (r = find(d1,0)) { if (r == -1) return 0; if (byte_equal(type,2,DNS_T_A)) { if (!response_rstart(d1,DNS_T_A,ttl)) return 0; if (!dobytes(4)) return 0; response_rfinish(RESPONSE_ADDITIONAL); } } } } uint16_unpack_big(x + 8,&u16); bpos += u16; } if (flagauthoritative && (response_len > 512)) { byte_zero(response + RESPONSE_ADDITIONAL,2); response_len = arpos; if (response_len > 512) { byte_zero(response + RESPONSE_AUTHORITY,2); response_len = aupos; } } return 1; } int respond(char *q,char qtype[2],char ip[4]) { int fd; int r; char key[6]; tai_now(&now); fd = open_read("data.cdb"); if (fd == -1) return 0; cdb_init(&c,fd); byte_zero(clientloc,2); key[0] = 0; key[1] = '%'; byte_copy(key + 2,4,ip); r = cdb_find(&c,key,6); if (!r) r = cdb_find(&c,key,5); if (!r) r = cdb_find(&c,key,4); if (!r) r = cdb_find(&c,key,3); if (!r) r = cdb_find(&c,key,2); if (r == -1) return 0; if (r && (cdb_datalen(&c) == 2)) if (cdb_read(&c,clientloc,2,cdb_datapos(&c)) == -1) return 0; r = doit(q,qtype); cdb_free(&c); close(fd); return r; } tinydyndns-0.4.2.debian1/timeoutread.c000066400000000000000000000010261103424076200177060ustar00rootroot00000000000000#include #include "error.h" #include "iopause.h" #include "timeoutread.h" int timeoutread(int t,int fd,char *buf,int len) { struct taia now; struct taia deadline; iopause_fd x; taia_now(&now); taia_uint(&deadline,t); taia_add(&deadline,&now,&deadline); x.fd = fd; x.events = IOPAUSE_READ; for (;;) { taia_now(&now); iopause(&x,1,&deadline,&now); if (x.revents) break; if (taia_less(&deadline,&now)) { errno = error_timeout; return -1; } } return read(fd,buf,len); } tinydyndns-0.4.2.debian1/timeoutread.h000066400000000000000000000001171103424076200177130ustar00rootroot00000000000000#ifndef TIMEOUTREAD_H #define TIMEOUTREAD_H extern int timeoutread(); #endif tinydyndns-0.4.2.debian1/timeoutwrite.c000066400000000000000000000010321103424076200201220ustar00rootroot00000000000000#include #include "error.h" #include "iopause.h" #include "timeoutwrite.h" int timeoutwrite(int t,int fd,char *buf,int len) { struct taia now; struct taia deadline; iopause_fd x; taia_now(&now); taia_uint(&deadline,t); taia_add(&deadline,&now,&deadline); x.fd = fd; x.events = IOPAUSE_WRITE; for (;;) { taia_now(&now); iopause(&x,1,&deadline,&now); if (x.revents) break; if (taia_less(&deadline,&now)) { errno = error_timeout; return -1; } } return write(fd,buf,len); } tinydyndns-0.4.2.debian1/timeoutwrite.h000066400000000000000000000001221103424076200201260ustar00rootroot00000000000000#ifndef TIMEOUTWRITE_H #define TIMEOUTWRITE_H extern int timeoutwrite(); #endif tinydyndns-0.4.2.debian1/tinydns-conf.c000066400000000000000000000041451103424076200200040ustar00rootroot00000000000000#include #include #include "strerr.h" #include "exit.h" #include "auto_home.h" #include "generic-conf.h" #define FATAL "tinydns-conf: fatal: " void usage(void) { strerr_die1x(100,"tinydns-conf: usage: tinydns-conf acct logacct /tinydns myip"); } char *dir; char *user; char *loguser; struct passwd *pw; char *myip; int main(int argc,char **argv) { user = argv[1]; if (!user) usage(); loguser = argv[2]; if (!loguser) usage(); dir = argv[3]; if (!dir) usage(); if (dir[0] != '/') usage(); myip = argv[4]; if (!myip) usage(); pw = getpwnam(loguser); if (!pw) strerr_die3x(111,FATAL,"unknown account ",loguser); init(dir,FATAL); makelog(loguser,pw->pw_uid,pw->pw_gid); makedir("env"); perm(02755); start("env/ROOT"); outs(dir); outs("/root\n"); finish(); perm(0644); start("env/IP"); outs(myip); outs("\n"); finish(); perm(0644); start("run"); outs("#!/bin/sh\nexec 2>&1\nexec envuidgid "); outs(user); outs(" envdir ./env softlimit -d300000 "); outs(auto_home); outs("/bin/tinydns\n"); finish(); perm(0755); makedir("root"); perm(02755); start("root/data"); finish(); perm(0644); start("root/add-ns"); outs("#!/bin/sh\nexec "); outs(auto_home); outs("/bin/tinydns-edit data data.new add ns ${1+\"$@\"}\n"); finish(); perm(0755); start("root/add-childns"); outs("#!/bin/sh\nexec "); outs(auto_home); outs("/bin/tinydns-edit data data.new add childns ${1+\"$@\"}\n"); finish(); perm(0755); start("root/add-host"); outs("#!/bin/sh\nexec "); outs(auto_home); outs("/bin/tinydns-edit data data.new add host ${1+\"$@\"}\n"); finish(); perm(0755); start("root/add-alias"); outs("#!/bin/sh\nexec "); outs(auto_home); outs("/bin/tinydns-edit data data.new add alias ${1+\"$@\"}\n"); finish(); perm(0755); start("root/add-mx"); outs("#!/bin/sh\nexec "); outs(auto_home); outs("/bin/tinydns-edit data data.new add mx ${1+\"$@\"}\n"); finish(); perm(0755); start("root/Makefile"); outs("data.cdb: data\n"); outs("\t"); outs(auto_home); outs("/bin/tinydns-data\n"); finish(); perm(0644); _exit(0); } tinydyndns-0.4.2.debian1/tinydns-data.c000066400000000000000000000240411103424076200177650ustar00rootroot00000000000000#include #include #include #include #include "uint16.h" #include "uint32.h" #include "str.h" #include "byte.h" #include "fmt.h" #include "ip4.h" #include "exit.h" #include "case.h" #include "scan.h" #include "buffer.h" #include "strerr.h" #include "getln.h" #include "cdb_make.h" #include "stralloc.h" #include "open.h" #include "dns.h" #define TTL_NS 259200 #define TTL_POSITIVE 86400 #define TTL_NEGATIVE 2560 #define FATAL "tinydns-data: fatal: " void die_datatmp(void) { strerr_die2sys(111,FATAL,"unable to create data.tmp: "); } void nomem(void) { strerr_die1sys(111,FATAL); } void ttdparse(stralloc *sa,char ttd[8]) { unsigned int i; char ch; byte_zero(ttd,8); for (i = 0;(i < 16) && (i < sa->len);++i) { ch = sa->s[i]; if ((ch >= '0') && (ch <= '9')) ch -= '0'; else if ((ch >= 'a') && (ch <= 'f')) ch -= 'a' - 10; else ch = 0; if (!(i & 1)) ch <<= 4; ttd[i >> 1] |= ch; } } void locparse(stralloc *sa,char loc[2]) { loc[0] = (sa->len > 0) ? sa->s[0] : 0; loc[1] = (sa->len > 1) ? sa->s[1] : 0; } void ipprefix_cat(stralloc *out,char *s) { unsigned long u; char ch; unsigned int j; for (;;) if (*s == '.') ++s; else { j = scan_ulong(s,&u); if (!j) return; s += j; ch = u; if (!stralloc_catb(out,&ch,1)) nomem(); } } void txtparse(stralloc *sa) { char ch; unsigned int i; unsigned int j; j = 0; i = 0; while (i < sa->len) { ch = sa->s[i++]; if (ch == '\\') { if (i >= sa->len) break; ch = sa->s[i++]; if ((ch >= '0') && (ch <= '7')) { ch -= '0'; if ((i < sa->len) && (sa->s[i] >= '0') && (sa->s[i] <= '7')) { ch <<= 3; ch += sa->s[i++] - '0'; if ((i < sa->len) && (sa->s[i] >= '0') && (sa->s[i] <= '7')) { ch <<= 3; ch += sa->s[i++] - '0'; } } } } sa->s[j++] = ch; } sa->len = j; } char defaultsoa[20]; void defaultsoa_init(int fd) { struct stat st; if (fstat(fd,&st) == -1) strerr_die2sys(111,FATAL,"unable to stat data: "); uint32_pack_big(defaultsoa,st.st_mtime); if (byte_equal(defaultsoa,4,"\0\0\0\0")) defaultsoa[3] = 1; byte_copy(defaultsoa + 4,16,"\0\0\100\000\0\0\010\000\0\020\000\000\0\0\012\000"); } int fdcdb; struct cdb_make cdb; static stralloc key; static stralloc result; void rr_add(const char *buf,unsigned int len) { if (!stralloc_catb(&result,buf,len)) nomem(); } void rr_addname(const char *d) { rr_add(d,dns_domain_length(d)); } void rr_start(const char type[2],unsigned long ttl,const char ttd[8],const char loc[2]) { char buf[4]; if (!stralloc_copyb(&result,type,2)) nomem(); if (byte_equal(loc,2,"\0\0")) rr_add("=",1); else { rr_add(">",1); rr_add(loc,2); } uint32_pack_big(buf,ttl); rr_add(buf,4); rr_add(ttd,8); } void rr_finish(const char *owner) { if (byte_equal(owner,2,"\1*")) { owner += 2; result.s[2] -= 19; } if (!stralloc_copyb(&key,owner,dns_domain_length(owner))) nomem(); case_lowerb(key.s,key.len); if (cdb_make_add(&cdb,key.s,key.len,result.s,result.len) == -1) die_datatmp(); } buffer b; char bspace[1024]; static stralloc line; int match = 1; unsigned long linenum = 0; #define NUMFIELDS 15 static stralloc f[NUMFIELDS]; static char *d1; static char *d2; char dptr[DNS_NAME4_DOMAIN]; char strnum[FMT_ULONG]; void syntaxerror(const char *why) { strnum[fmt_ulong(strnum,linenum)] = 0; strerr_die4x(111,FATAL,"unable to parse data line ",strnum,why); } int main() { int fddata; int i; int j; int k; char ch; unsigned long ttl; char ttd[8]; char loc[2]; unsigned long u; char ip[4]; char type[2]; char soa[20]; char buf[4]; umask(022); fddata = open_read("data"); if (fddata == -1) strerr_die2sys(111,FATAL,"unable to open data: "); defaultsoa_init(fddata); buffer_init(&b,buffer_unixread,fddata,bspace,sizeof bspace); fdcdb = open_trunc("data.tmp"); if (fdcdb == -1) die_datatmp(); if (cdb_make_start(&cdb,fdcdb) == -1) die_datatmp(); while (match) { ++linenum; if (getln(&b,&line,&match,'\n') == -1) strerr_die2sys(111,FATAL,"unable to read line: "); while (line.len) { ch = line.s[line.len - 1]; if ((ch != ' ') && (ch != '\t') && (ch != '\n')) break; --line.len; } if (!line.len) continue; if (line.s[0] == '#') continue; if (line.s[0] == '-') continue; j = 1; for (i = 0;i < NUMFIELDS;++i) { if (j >= line.len) { if (!stralloc_copys(&f[i],"")) nomem(); } else { k = byte_chr(line.s + j,line.len - j,':'); if (!stralloc_copyb(&f[i],line.s + j,k)) nomem(); j += k + 1; } } switch(line.s[0]) { case '%': locparse(&f[0],loc); if (!stralloc_copyb(&key,"\0%",2)) nomem(); if (!stralloc_0(&f[1])) nomem(); ipprefix_cat(&key,f[1].s); if (cdb_make_add(&cdb,key.s,key.len,loc,2) == -1) die_datatmp(); break; case 'Z': if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem(); if (!stralloc_0(&f[3])) nomem(); if (!scan_ulong(f[3].s,&u)) uint32_unpack_big(defaultsoa,&u); uint32_pack_big(soa,u); if (!stralloc_0(&f[4])) nomem(); if (!scan_ulong(f[4].s,&u)) uint32_unpack_big(defaultsoa + 4,&u); uint32_pack_big(soa + 4,u); if (!stralloc_0(&f[5])) nomem(); if (!scan_ulong(f[5].s,&u)) uint32_unpack_big(defaultsoa + 8,&u); uint32_pack_big(soa + 8,u); if (!stralloc_0(&f[6])) nomem(); if (!scan_ulong(f[6].s,&u)) uint32_unpack_big(defaultsoa + 12,&u); uint32_pack_big(soa + 12,u); if (!stralloc_0(&f[7])) nomem(); if (!scan_ulong(f[7].s,&u)) uint32_unpack_big(defaultsoa + 16,&u); uint32_pack_big(soa + 16,u); if (!stralloc_0(&f[8])) nomem(); if (!scan_ulong(f[8].s,&ttl)) ttl = TTL_NEGATIVE; ttdparse(&f[9],ttd); locparse(&f[10],loc); rr_start(DNS_T_SOA,ttl,ttd,loc); if (!dns_domain_fromdot(&d2,f[1].s,f[1].len)) nomem(); rr_addname(d2); if (!dns_domain_fromdot(&d2,f[2].s,f[2].len)) nomem(); rr_addname(d2); rr_add(soa,20); rr_finish(d1); break; case '.': case '&': if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem(); if (!stralloc_0(&f[3])) nomem(); if (!scan_ulong(f[3].s,&ttl)) ttl = TTL_NS; ttdparse(&f[4],ttd); locparse(&f[5],loc); if (!stralloc_0(&f[1])) nomem(); if (byte_chr(f[2].s,f[2].len,'.') >= f[2].len) { if (!stralloc_cats(&f[2],".ns.")) nomem(); if (!stralloc_catb(&f[2],f[0].s,f[0].len)) nomem(); } if (!dns_domain_fromdot(&d2,f[2].s,f[2].len)) nomem(); if (line.s[0] == '.') { rr_start(DNS_T_SOA,ttl ? TTL_NEGATIVE : 0,ttd,loc); rr_addname(d2); rr_add("\12hostmaster",11); rr_addname(d1); rr_add(defaultsoa,20); rr_finish(d1); } rr_start(DNS_T_NS,ttl,ttd,loc); rr_addname(d2); rr_finish(d1); if (ip4_scan(f[1].s,ip)) { rr_start(DNS_T_A,ttl,ttd,loc); rr_add(ip,4); rr_finish(d2); } break; case '+': case '=': if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem(); if (!stralloc_0(&f[2])) nomem(); if (!scan_ulong(f[2].s,&ttl)) ttl = TTL_POSITIVE; ttdparse(&f[3],ttd); locparse(&f[4],loc); if (!stralloc_0(&f[1])) nomem(); if (ip4_scan(f[1].s,ip)) { rr_start(DNS_T_A,ttl,ttd,loc); rr_add(ip,4); rr_finish(d1); if (line.s[0] == '=') { dns_name4_domain(dptr,ip); rr_start(DNS_T_PTR,ttl,ttd,loc); rr_addname(d1); rr_finish(dptr); } } break; case '@': if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem(); if (!stralloc_0(&f[4])) nomem(); if (!scan_ulong(f[4].s,&ttl)) ttl = TTL_POSITIVE; ttdparse(&f[5],ttd); locparse(&f[6],loc); if (!stralloc_0(&f[1])) nomem(); if (byte_chr(f[2].s,f[2].len,'.') >= f[2].len) { if (!stralloc_cats(&f[2],".mx.")) nomem(); if (!stralloc_catb(&f[2],f[0].s,f[0].len)) nomem(); } if (!dns_domain_fromdot(&d2,f[2].s,f[2].len)) nomem(); if (!stralloc_0(&f[3])) nomem(); if (!scan_ulong(f[3].s,&u)) u = 0; rr_start(DNS_T_MX,ttl,ttd,loc); uint16_pack_big(buf,u); rr_add(buf,2); rr_addname(d2); rr_finish(d1); if (ip4_scan(f[1].s,ip)) { rr_start(DNS_T_A,ttl,ttd,loc); rr_add(ip,4); rr_finish(d2); } break; case '^': case 'C': if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem(); if (!dns_domain_fromdot(&d2,f[1].s,f[1].len)) nomem(); if (!stralloc_0(&f[2])) nomem(); if (!scan_ulong(f[2].s,&ttl)) ttl = TTL_POSITIVE; ttdparse(&f[3],ttd); locparse(&f[4],loc); if (line.s[0] == 'C') rr_start(DNS_T_CNAME,ttl,ttd,loc); else rr_start(DNS_T_PTR,ttl,ttd,loc); rr_addname(d2); rr_finish(d1); break; case '\'': if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem(); if (!stralloc_0(&f[2])) nomem(); if (!scan_ulong(f[2].s,&ttl)) ttl = TTL_POSITIVE; ttdparse(&f[3],ttd); locparse(&f[4],loc); rr_start(DNS_T_TXT,ttl,ttd,loc); txtparse(&f[1]); i = 0; while (i < f[1].len) { k = f[1].len - i; if (k > 127) k = 127; ch = k; rr_add(&ch,1); rr_add(f[1].s + i,k); i += k; } rr_finish(d1); break; case ':': if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem(); if (!stralloc_0(&f[3])) nomem(); if (!scan_ulong(f[3].s,&ttl)) ttl = TTL_POSITIVE; ttdparse(&f[4],ttd); locparse(&f[5],loc); if (!stralloc_0(&f[1])) nomem(); scan_ulong(f[1].s,&u); uint16_pack_big(type,u); if (byte_equal(type,2,DNS_T_AXFR)) syntaxerror(": type AXFR prohibited"); if (byte_equal(type,2,"\0\0")) syntaxerror(": type 0 prohibited"); if (byte_equal(type,2,DNS_T_SOA)) syntaxerror(": type SOA prohibited"); if (byte_equal(type,2,DNS_T_NS)) syntaxerror(": type NS prohibited"); if (byte_equal(type,2,DNS_T_CNAME)) syntaxerror(": type CNAME prohibited"); if (byte_equal(type,2,DNS_T_PTR)) syntaxerror(": type PTR prohibited"); if (byte_equal(type,2,DNS_T_MX)) syntaxerror(": type MX prohibited"); txtparse(&f[2]); rr_start(type,ttl,ttd,loc); rr_add(f[2].s,f[2].len); rr_finish(d1); break; default: syntaxerror(": unrecognized leading character"); } } if (cdb_make_finish(&cdb) == -1) die_datatmp(); if (fsync(fdcdb) == -1) die_datatmp(); if (close(fdcdb) == -1) die_datatmp(); /* NFS stupidity */ if (rename("data.tmp","data.cdb") == -1) strerr_die2sys(111,FATAL,"unable to move data.tmp to data.cdb: "); _exit(0); } tinydyndns-0.4.2.debian1/tinydns-edit.c000066400000000000000000000142751103424076200200110ustar00rootroot00000000000000#include #include #include #include #include "stralloc.h" #include "buffer.h" #include "exit.h" #include "open.h" #include "getln.h" #include "strerr.h" #include "scan.h" #include "byte.h" #include "str.h" #include "fmt.h" #include "ip4.h" #include "dns.h" #define FATAL "tinydns-edit: fatal: " #define TTL_NS 259200 #define TTL_POSITIVE 86400 char *fn; char *fnnew; void die_usage() { strerr_die1x(100,"tinydns-edit: usage: tinydns-edit data data.new add [ns|childns|host|alias|mx] domain a.b.c.d"); } void nomem() { strerr_die2x(111,FATAL,"out of memory"); } void die_read() { strerr_die4sys(100,FATAL,"tinydns-edit: fatal: unable to read ",fn,": "); } void die_write() { strerr_die4sys(100,FATAL,"tinydns-edit: fatal: unable to write ",fnnew,": "); } char mode; static char *target; char targetip[4]; int fd; buffer b; char bspace[1024]; int fdnew; buffer bnew; char bnewspace[1024]; static stralloc line; int match = 1; #define NUMFIELDS 10 static stralloc f[NUMFIELDS]; static char *d1; static char *d2; char ip[4]; char ipstr[IP4_FMT]; char strnum[FMT_ULONG]; static char *names[26]; static int used[26]; void put(const char *buf,unsigned int len) { if (buffer_putalign(&bnew,buf,len) == -1) die_write(); } int main(int argc,char **argv) { unsigned long ttl; struct stat st; int i; int j; int k; char ch; if (!*argv) die_usage(); if (!*++argv) die_usage(); fn = *argv; if (!*++argv) die_usage(); fnnew = *argv; if (!*++argv) die_usage(); if (str_diff(*argv,"add")) die_usage(); if (!*++argv) die_usage(); if (str_equal(*argv,"ns")) mode = '.'; else if (str_equal(*argv,"childns")) mode = '&'; else if (str_equal(*argv,"host")) mode = '='; else if (str_equal(*argv,"alias")) mode = '+'; else if (str_equal(*argv,"mx")) mode = '@'; else die_usage(); if (!*++argv) die_usage(); if (!dns_domain_fromdot(&target,*argv,str_len(*argv))) nomem(); if (!*++argv) die_usage(); if (!ip4_scan(*argv,targetip)) die_usage(); umask(077); fd = open_read(fn); if (fd == -1) die_read(); if (fstat(fd,&st) == -1) die_read(); buffer_init(&b,buffer_unixread,fd,bspace,sizeof bspace); fdnew = open_trunc(fnnew); if (fdnew == -1) die_write(); if (fchmod(fdnew,st.st_mode & 0644) == -1) die_write(); buffer_init(&bnew,buffer_unixwrite,fdnew,bnewspace,sizeof bnewspace); switch(mode) { case '.': case '&': ttl = TTL_NS; for (i = 0;i < 26;++i) { ch = 'a' + i; if (!stralloc_copyb(&f[0],&ch,1)) nomem(); if (!stralloc_cats(&f[0],".ns.")) nomem(); if (!dns_domain_todot_cat(&f[0],target)) nomem(); if (!dns_domain_fromdot(&names[i],f[0].s,f[0].len)) nomem(); } break; case '+': case '=': ttl = TTL_POSITIVE; break; case '@': ttl = TTL_POSITIVE; for (i = 0;i < 26;++i) { ch = 'a' + i; if (!stralloc_copyb(&f[0],&ch,1)) nomem(); if (!stralloc_cats(&f[0],".mx.")) nomem(); if (!dns_domain_todot_cat(&f[0],target)) nomem(); if (!dns_domain_fromdot(&names[i],f[0].s,f[0].len)) nomem(); } break; } while (match) { if (getln(&b,&line,&match,'\n') == -1) die_read(); put(line.s,line.len); if (line.len && !match) put("\n",1); while (line.len) { ch = line.s[line.len - 1]; if ((ch != ' ') && (ch != '\t') && (ch != '\n')) break; --line.len; } if (!line.len) continue; if (line.s[0] == '#') continue; j = 1; for (i = 0;i < NUMFIELDS;++i) { if (j >= line.len) { if (!stralloc_copys(&f[i],"")) nomem(); } else { k = byte_chr(line.s + j,line.len - j,':'); if (!stralloc_copyb(&f[i],line.s + j,k)) nomem(); j += k + 1; } } switch(mode) { case '.': case '&': if (line.s[0] == mode) { if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem(); if (dns_domain_equal(d1,target)) { if (byte_chr(f[2].s,f[2].len,'.') >= f[2].len) { if (!stralloc_cats(&f[2],".ns.")) nomem(); if (!stralloc_catb(&f[2],f[0].s,f[0].len)) nomem(); } if (!dns_domain_fromdot(&d2,f[2].s,f[2].len)) nomem(); if (!stralloc_0(&f[3])) nomem(); if (!scan_ulong(f[3].s,&ttl)) ttl = TTL_NS; for (i = 0;i < 26;++i) if (dns_domain_equal(d2,names[i])) { used[i] = 1; break; } } } break; case '=': if (line.s[0] == '=') { if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem(); if (dns_domain_equal(d1,target)) strerr_die2x(100,FATAL,"host name already used"); if (!stralloc_0(&f[1])) nomem(); if (ip4_scan(f[1].s,ip)) if (byte_equal(ip,4,targetip)) strerr_die2x(100,FATAL,"IP address already used"); } break; case '@': if (line.s[0] == '@') { if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem(); if (dns_domain_equal(d1,target)) { if (byte_chr(f[2].s,f[2].len,'.') >= f[2].len) { if (!stralloc_cats(&f[2],".mx.")) nomem(); if (!stralloc_catb(&f[2],f[0].s,f[0].len)) nomem(); } if (!dns_domain_fromdot(&d2,f[2].s,f[2].len)) nomem(); if (!stralloc_0(&f[4])) nomem(); if (!scan_ulong(f[4].s,&ttl)) ttl = TTL_POSITIVE; for (i = 0;i < 26;++i) if (dns_domain_equal(d2,names[i])) { used[i] = 1; break; } } } break; } } if (!stralloc_copyb(&f[0],&mode,1)) nomem(); if (!dns_domain_todot_cat(&f[0],target)) nomem(); if (!stralloc_cats(&f[0],":")) nomem(); if (!stralloc_catb(&f[0],ipstr,ip4_fmt(ipstr,targetip))) nomem(); switch(mode) { case '.': case '&': case '@': for (i = 0;i < 26;++i) if (!used[i]) break; if (i >= 26) strerr_die2x(100,FATAL,"too many records for that domain"); ch = 'a' + i; if (!stralloc_cats(&f[0],":")) nomem(); if (!stralloc_catb(&f[0],&ch,1)) nomem(); if (mode == '@') if (!stralloc_cats(&f[0],":")) nomem(); break; } if (!stralloc_cats(&f[0],":")) nomem(); if (!stralloc_catb(&f[0],strnum,fmt_ulong(strnum,ttl))) nomem(); if (!stralloc_cats(&f[0],"\n")) nomem(); put(f[0].s,f[0].len); if (buffer_flush(&bnew) == -1) die_write(); if (fsync(fdnew) == -1) die_write(); if (close(fdnew) == -1) die_write(); /* NFS dorks */ if (rename(fnnew,fn) == -1) strerr_die6sys(111,FATAL,"unable to move ",fnnew," to ",fn,": "); _exit(0); } tinydyndns-0.4.2.debian1/tinydns-get.c000066400000000000000000000030061103424076200176310ustar00rootroot00000000000000#include "str.h" #include "byte.h" #include "scan.h" #include "exit.h" #include "stralloc.h" #include "buffer.h" #include "strerr.h" #include "uint16.h" #include "response.h" #include "case.h" #include "printpacket.h" #include "parsetype.h" #include "ip4.h" #include "dns.h" extern int respond(char *,char *,char *); #define FATAL "tinydns-get: fatal: " void usage(void) { strerr_die1x(100,"tinydns-get: usage: tinydns-get type name [ip]"); } void oops(void) { strerr_die2sys(111,FATAL,"unable to parse: "); } static char ip[4]; static char type[2]; static char *q; static stralloc out; int main(int argc,char **argv) { uint16 u16; if (!*argv) usage(); if (!*++argv) usage(); if (!parsetype(*argv,type)) usage(); if (!*++argv) usage(); if (!dns_domain_fromdot(&q,*argv,str_len(*argv))) oops(); if (*++argv) { if (!ip4_scan(*argv,ip)) usage(); } if (!stralloc_copys(&out,"")) oops(); uint16_unpack_big(type,&u16); if (!stralloc_catulong0(&out,u16,0)) oops(); if (!stralloc_cats(&out," ")) oops(); if (!dns_domain_todot_cat(&out,q)) oops(); if (!stralloc_cats(&out,":\n")) oops(); if (!response_query(q,type,DNS_C_IN)) oops(); response[3] &= ~128; response[2] &= ~1; response[2] |= 4; case_lowerb(q,dns_domain_length(q)); if (byte_equal(type,2,DNS_T_AXFR)) { response[3] &= ~15; response[3] |= 4; } else if (!respond(q,type,ip)) goto DONE; if (!printpacket_cat(&out,response,response_len)) oops(); DONE: buffer_putflush(buffer_1,out.s,out.len); _exit(0); } tinydyndns-0.4.2.debian1/tinydns.c000066400000000000000000000002631103424076200170560ustar00rootroot00000000000000#include "dns.h" const char *fatal = "tinydns: fatal: "; const char *starting = "starting tinydns\n"; static char seed[128]; void initialize(void) { dns_random_init(seed); } tinydyndns-0.4.2.debian1/tinydyndns-conf000077500000000000000000000051401103424076200202750ustar00rootroot00000000000000#!/bin/sh set -e usage () { exec 1>&2 echo "Usage: $0 acct logacct /etc/tinydyn myip mydomain" exit 1 } if [ $# -ne 5 ]; then usage; fi cwd=`pwd` acct=$1 logacct=$2 dir=$3 ip=$4 mydomain=$5 acct_uid=`id -u $acct` acct_gid=`id -g $acct` logacct_uid=`id -u $logacct` tinydns-conf $acct $logacct $dir $ip cd $dir # data file cd root ./add-ns $mydomain $ip ./add-alias $mydomain $ip chown $acct . data make chown $acct data.cdb # modify Makefile cat <Makefile'{new}' default: @echo 'tinydyndns modifies the binary database data.cdb directly. Use' @echo "'make rebuild' to rebuild data.cdb with a NS, SOA, A record for" @echo 'the nameserver, and A records for all dynamic hostnames in the' @echo 'local passwd database, pointing to the IP address 127.14.14.14.' @echo EOT cat Makefile >>Makefile'{new}' cat <>Makefile'{new}' rebuild: clean data.cdb cut -d: -f1 <../pop/passwd |sed -e 's/\$\$/.${mydomain}/' \\ |xargs tinydyndns-data add clean: rm -f data.cdb EOT mv -f Makefile'{new}' Makefile cd .. # pop3 mkdir -p pop chown $acct pop chmod 750 pop cd pop cat <run #!/bin/sh exec softlimit -m 4000000 envdir ./env tcpserver -vRHl$mydomain $ip 110 \\ pop3front-auth cvm-pwfile sh -c ' echo "login: \$USER: \$TCPREMOTEIP" >&7 cd $dir/root setlock data.cdb \\ tinydyndns-update \${USER}.$mydomain \$TCPREMOTEIP >&7 2>&1 cd $dir/pop exec pop3front-maildir Maildir ' 2>&1 7>&1 EOF chmod 750 run touch passwd chown $acct passwd # setpasswd script cat <setpasswd #!/bin/sh if [ -z "\$1" -o -z "\$2" ]; then echo "Usage: \$0 host passwd" >&2; exit; fi HOST=\$1 PASSWD=\$2 if ! grep "^\$HOST:" $dir/pop/passwd >/dev/null; then cat $dir/pop/passwd >$dir/pop/passwd'{new}' echo "\$HOST:\$PASSWD:$acct_uid:$acct_gid::$dir/pop:/bin/false" \\ >>$dir/pop/passwd'{new}' else sed -e \\ "s}^\$HOST:.*$}\$HOST:\$PASSWD:$acct_uid:$acct_gid::$dir/pop:/bin/false}g" \\ $dir/pop/passwd >$dir/pop/passwd'{new}' fi mv -f $dir/pop/passwd'{new}' $dir/pop/passwd chmod 600 $dir/pop/passwd ( cd $dir/root; tinydyndns-data add \${HOST}.$mydomain ) EOF chmod 750 setpasswd chown $acct setpasswd # envdir mkdir -p env chmod 750 env echo "$dir/pop/passwd" >env/CVM_PWFILE_PATH echo 'plain' >env/CVM_PWFILE_PWCMP # Maildir echo "|bouncesaying 'This address does not accept mail.'" >.qmail mkdir -m 700 Maildir mkdir -m 700 Maildir/tmp mkdir -m 700 Maildir/new mkdir -m 700 Maildir/cur chown -R $acct Maildir # logdir mkdir -p log chown $logacct log chmod 750 log cd log cat <run #!/bin/sh exec setuidgid $logacct multilog t ./main EOF chmod 750 run cd $cwd exit 0 tinydyndns-0.4.2.debian1/tinydyndns-conf.8000066400000000000000000000030021103424076200204330ustar00rootroot00000000000000.TH tinydyndns-conf 8 .SH NAME tinydyndns-conf \- sets up a pop-before-dyndns service .SH SYNOPSIS .B tinydyndns-conf .I acct .I logacct .I dir .I myip .I mydomain .SH DESCRIPTION .B tinydyndns-conf creates a service directory .I dir that runs .BR tinydns (8), and a service directory .IR dir /pop that runs a pop3 service and updates .BR tinydns ' database after a successful login. .P You can run the services under .BR svscan (8) or .BR runsvdir (8) by creating symbolic links in the /service directory: .P ln -s \fIdir\fR /service/\fIdir\fR ln -s \fIdir\fR/pop /service/\fIdir\fR-pop .P The service will start within five seconds, and will be restarted upon reboot. You can use .BR svc (8) to control the service. .P .B tinydyndns-conf runs .P tinydns-conf .I acct .I logacct .I dir .I myip .P to set up a DNS publication service. .P .B tinydyndns-conf modifies .IR dir /root/Makefile to not run .BR tinydns-data (8) upon normal request. .P .B tinydyndns-conf arranges for .BR tcpserver (1) to listen on TCP port 110, and to start .BR pop3front-auth (8), .BR cvm-pwfile (8), and after a successful login .BR tinydyndns-update (8), and .BR pop3front-maildir (8) upon connections. .P .B tinydyndns-conf creates a .I setpasswd script and a default .I passwd database in .IR dir /pop for the use with .BR cvm-pwfile (8). .SH SEE ALSO tinydyndns-update(8), tinydyndns-data(8), tinydns(8), tcpserver(1), pop3front-auth(8), cvm-pwfile(8), pop3front-maildir(8) .P http://smarden.org/tinydyndns/ .SH AUTHOR Gerrit Pape tinydyndns-0.4.2.debian1/tinydyndns-data.8000066400000000000000000000053501103424076200204270ustar00rootroot00000000000000.TH tinydyndns-data 8 .SH NAME tinydyndns-data \- add or remove TYPE A record to or from data.cdb .SH SYNOPSIS .B tinydyndns-data add|remove .I fqdns .SH DESCRIPTION .I fqdns consists of one or more argument, each specifying a fully qualified domain name (fqdn). .P .B tinydyndns-data adds a TYPE A record to or removes it from data.cdb in the current directory. Other than .BR tinydns-data (8), .B tinydyndns-data does not know about the source file data but changes the binary database data.cdb directly. .P .B tinydyndns-data reads data.cdb and copies its data to data.tmp. While reading the records, .B tinydyndns-data checks for each .I fqdn in .I fqdns if this hostname has a TYPE A record in data.cdb, drops the record when called with the option .IR remove , or refuses to add the record when called with the option .IR add . .P When called with the option .IR add , .B tinydyndns-data then adds all new .IR fqdn s to data.tmp. The data of the newly created records can optionally be controlled through the environment, see below. Finally .B tinydyndns-data renames data.tmp to data.cdb. .SH OPTIONS .TP add For each .I fqdn in .IR fqdns , add a TYPE A record for .I fqdn to data.cdb with the default IP address (127.14.14.14). .TP remove For each .I fqdn in .IR fqdns , remove all TYPE A records for .I fqdn from data.cdb. .SH ENVIRONMENT .TP .I IP The environment variable .I IP overrides the default IP address (``127.14.14.14'') for newly created records. .I $IP must be a valid IP address. .TP .I TTL time-to-live. The environment variable .I TTL overrides the default time-to-live in seconds (0 if .I TTD is set, otherwise 5). .I $TTL must be an integer. .TP .I TTD time-to-die. .I $TTD must be an integer, specifying a number of seconds. If .I TTD is set, the timestamp of newly created records is set to the current time plus .I $TTD seconds, and .I TTL is set to zero by default, so that .BR tinydns (8) interpretes the timestamp as time-to-die. Note: you probably want to adjust SOA ttl, or create a wildcard record, to prevent DNS caches from caching nxdomain, when using this feature. .TP .I LOC location. .I $LOC must be two characters long. If .I LOC is set, it specifies the client location for newly created records. .SH EXIT CODES .B tinydyndns-data exits 111 if anything goes wrong and leaves data.cdb unchanged. .P .B tinydyndns-data exits 0 if all .I fqdns were processed and the new data.cdb was written. .P For each .I fqdn in .I fqdns that .B tinydyndns-data was not able to remove or add (e.g., not there, or already there), it increases the exit code by one and exits non-zero (maximum is 100). .SH FILES ./data.cdb ./data.tmp .SH SEE ALSO tinydyndns-update(8), tinydyndns-conf(8) .P http://smarden.org/tinydyndns/ .SH AUTHOR Gerrit Pape tinydyndns-0.4.2.debian1/tinydyndns-data.c000066400000000000000000000120761103424076200205050ustar00rootroot00000000000000#include #include #include "strerr.h" #include "error.h" #include "cdb.h" #include "cdb_make.h" #include "open.h" #include "buffer.h" #include "stralloc.h" #include "str.h" #include "byte.h" #include "dns.h" #include "ip4.h" #include "case.h" #include "seek.h" #include "tai.h" #include "env.h" #include "scan.h" #define USAGE " add|remove fqdn ..." #define FATAL "tinydyndns-data: fatal: " #define WARNING "tinydyndns-data: warning: " #define INFO "tinydyndns-data: info: " char *progname; void usage () { strerr_die4x(1, "usage: ", progname, USAGE, "\n"); } void die_nomem() { strerr_die2x(111, FATAL, "out of memory."); } void fatal(const char *m1, const char *m2) { strerr_die4sys(111, FATAL, m1, m2, ": "); } void warn(const char *m1, const char *m2) { strerr_warn3(WARNING, m1, m2, 0); } void info(const char *m1, const char *m2) { buffer_puts(buffer_1, INFO); buffer_puts(buffer_1, m1); buffer_puts(buffer_1, m2); buffer_putsflush(buffer_1, "\n"); } unsigned int add =0; unsigned int rem =0; unsigned long ttl; unsigned long ttd; const char *ip; const char *loc; int rc =0; int fdcdb; int fdtmp; stralloc sa ={0}; static char *host; struct cdb_make c; struct cdb cdb; char **fqdn; uint32 pos =0; void get(buffer *b, char *buf, unsigned int l) { int r; while (l > 0) { r =buffer_get(b, buf, l); if (r == -1) fatal("unable to read data.cdb", 0); if (r == 0) strerr_die2x(111, FATAL, "unable to read data.cdb: truncated file"); buf +=r; l -=r; } } int main(int argc, char ** argv) { buffer bcdb; char bcdbspace[4096]; char buf[8]; char ipbuf[4]; uint32 eod; uint32 klen; uint32 dlen; stralloc key ={0}; char *s; struct tai tt, plus; progname =*argv++; if (! *argv) usage(); switch (**argv) { case 'a': /* add */ add =1; break; case 'r': /* remove */ rem =1; break; default: usage(); } if (! *++argv) usage(); if ((s =env_get("TTL"))) scan_ulong(s, &ttl); if ((s =env_get("TTD"))) scan_ulong(s, &ttd); if (! (ip =env_get("IP"))) ip ="127.14.14.14"; if ((loc =env_get("LOC"))) if (! loc[0] || ! loc[1]) loc =0; /* open data.cdb */ if ((fdcdb =open_read("data.cdb")) == -1) fatal("unable to open data.cdb", 0); buffer_init(&bcdb, buffer_unixread, fdcdb, bcdbspace, sizeof bcdbspace); /* lock data.cdb */ /* open data.tmp */ if ((fdtmp =open_trunc("data.tmp")) == -1) fatal("unable to open data.tmp", 0); if (cdb_make_start(&c, fdtmp) == -1) fatal("unable to create ok.cdb.tmp", 0); /* size of database */ get(&bcdb, buf, 4); pos +=4; uint32_unpack(buf, &eod); while (pos < 2048) { get(&bcdb, buf, 4); pos +=4; } while (pos < eod) { get(&bcdb, buf, 4); pos +=4; uint32_unpack(buf, &klen); get(&bcdb, buf, 4); pos +=4; uint32_unpack(buf, &dlen); if (! stralloc_ready(&sa, klen +dlen)) die_nomem(); get(&bcdb, sa.s, klen +dlen); pos +=klen +dlen; if (rem) { int skip =0; for (fqdn =argv; *fqdn; ++fqdn) { if (! dns_domain_fromdot(&host, *fqdn, str_len(*fqdn))) die_nomem(); case_lowerb(host, dns_domain_length(host)); if (byte_equal(host, dns_domain_length(host), sa.s)) { info("remove: ", *fqdn); skip =1; rc--; break; } } if (skip) continue; } if (cdb_make_add(&c, sa.s, klen, sa.s +klen, dlen) == -1) fatal("unable to write data.tmp", 0); } if (add) { seek_begin(fdcdb); cdb_init(&cdb, fdcdb); if (! ip4_scan(ip, ipbuf)) strerr_die3x(100, FATAL, "unable to scan IP address: ", ip); for (fqdn =argv; *fqdn; ++fqdn) { if (! dns_domain_fromdot(&host, *fqdn, str_len(*fqdn))) die_nomem(); case_lowerb(host, dns_domain_length(host)); if (cdb_find(&cdb, host, dns_domain_length(host)) == 1) { warn(*fqdn, ": already in cdb."); rc++; continue; } if (! stralloc_copyb(&sa, DNS_T_A, 2)) die_nomem(); if (loc) { if (! stralloc_append(&sa, ">")) die_nomem(); if (! stralloc_catb(&sa, loc, 2)) die_nomem(); } else if (! stralloc_append(&sa, "=")) die_nomem(); if (! ttd && ! ttl) ttl =5; uint32_pack_big(buf, ttl); if (! stralloc_catb(&sa, buf, 4)) die_nomem(); /* ttl */ if (ttd) { tai_now(&tt); tai_uint(&plus, ttd); tai_add(&tt, &tt, &plus); tai_pack(buf, &tt); if (! stralloc_catb(&sa, buf, 8)) die_nomem(); } else if (! stralloc_catb(&sa, "\0\0\0\0\0\0\0\0", 8)) die_nomem(); /* ttd */ if (! stralloc_catb(&sa, ipbuf, 4)) die_nomem(); if (! stralloc_copyb(&key, host, dns_domain_length(host))) die_nomem(); if (cdb_make_add(&c, key.s, key.len, sa.s, sa.len) == -1) fatal("unable to write data.tmp", 0); info("add: ", *fqdn); } cdb_free(&cdb); } close(fdcdb); if (cdb_make_finish(&c) == -1) fatal("unable to write data.tmp", 0); if (fsync(fdtmp) == -1) fatal("unable to write data.cdb.tmp", 0); close(fdtmp); if (rename("data.tmp","data.cdb") == -1) fatal("unable to move data.tmp to data.cdb", 0); if (rem) for (fqdn =argv; *fqdn; ++fqdn) rc++; /* info("done", ""); */ if (rc > 100) rc =100; _exit(rc); } tinydyndns-0.4.2.debian1/tinydyndns-update.8000066400000000000000000000046131103424076200210010ustar00rootroot00000000000000.TH tinydyndns-update 8 .SH NAME tinydyndns-update \- update TYPE A record in data.cdb .SH SYNOPSIS .B tinydyndns-update .I fqdn .I dynip .SH DESCRIPTION .B tinydyndns-update changes the data of a TYPE A record in data.cdb in the current directory. Other than .BR tinydns-data (8), .B tinydndns-update does not know about the source file .I data but changes the binary database data.cdb directly. .P First .B tinydyndns-update checks if the given .I fqdn has a TYPE A record in data.cdb. Then it checks if the given IP address differs from the one in the TYPE A record in data.cdb, or if the record's timestamp should be updated. Finally if data.cdb needs to change, .B tinydyndns-update copies data.cdb to data.tmp, changes the IP address of the TYPE A record of .I fqdn to .I dynip in .IR data.tmp , optionally adjusts time-to-live or time-to-die, and renames data.tmp to data.cdb. .SH ENVIRONMENT .TP .I TTL time-to-live. The environment variable .I TTL overrides the default time-to-live in seconds (0 if .I TTD is set, otherwise 5). If .I TTL is not set or zero, the time-to-live of the record will not change. .I $TTL must be an integer. .TP .I TTD time-to-die. .I $TTD must be an integer, specifying a number of seconds. If .I TTD is set, the timestamp of the record is set to the current time plus .I $TTD seconds, and .I TTL is set to zero by default, so that .BR tinydns (8) interpretes the timestamp as time-to-die. Note: you probably want to adjust SOA ttl, or create a wildcard record, to prevent DNS caches from caching nxdomain, when using this feature. .TP .I LOC location. .I $LOC must be two characters long. If .I LOC is set, it specifies the client location for records to be updated. .SH EXIT CODES If .B tinydyndns-update cannot find a TYPE A record for .I fqdn in data.cdb, it prints a warning and exits 114. .P If .I dynip does not differ from the IP address of the TYPE A record of .I fqdn in data.cdb, and the environment variable .I TTD is not set, .B tinydyndns-update prints a note and exits 0. .P .B tinydyndns-update exits 100 if it has trouble opening data.cdb, and leaves data.cdb unchanged. .P .B tinydyndns-update exits 111 on temporary error, and leaves data.cdb unchanged. .P If data.cdb was changed successfully, .B tinydyndns-update exits 0. .SH FILES ./data.cdb ./data.tmp .SH SEE ALSO tinydyndns-data(8), tinydyndns-conf(8) .P http://smarden.org/tinydyndns/ .SH AUTHOR Gerrit Pape tinydyndns-0.4.2.debian1/tinydyndns-update.c000066400000000000000000000103031103424076200210450ustar00rootroot00000000000000#include #include #include #include #include #include "strerr.h" #include "error.h" #include "str.h" #include "dns.h" #include "cdb.h" #include "ip4.h" #include "buffer.h" #include "seek.h" #include "byte.h" #include "open.h" #include "env.h" #include "scan.h" #define USAGE " fqdn dynip" #define FATAL "tinydyndns-update: fatal: " #define INFO "tinydyndns-update: info: " char *progname; void usage () { strerr_die4x(1, "usage: ", progname, USAGE, "\n"); } void die_nomem() { strerr_die2x(111, FATAL, "out of memory."); } char *dynhost; char *dynip; unsigned long ttl =0; unsigned long ttd =0; char *loc; static char *host; char ip[4]; char data[21]; unsigned int l; static struct cdb c; int fdcdb; int fdtmp; int main (int argc, char ** argv) { int i; unsigned int dlen; uint32 dpos; buffer bcdb; char bcdbspace[4096]; buffer btmp; char btmpspace[4096]; char *s; struct tai tt, plus; progname =argv[0]; if (! (dynhost =argv[1])) usage(); if (! (dynip =argv[2])) usage(); if (! ip4_scan(dynip, ip)) usage(); if (! dns_domain_fromdot(&host, dynhost, str_len(dynhost))) die_nomem(); if ((s =env_get("TTL"))) scan_ulong(s, &ttl); if ((s =env_get("TTD"))) scan_ulong(s, &ttd); if ((loc =env_get("LOC"))) if (! loc[0] || ! loc[1]) loc =0; /* setlock? */ /* open cdb */ if ((fdcdb =open_read("data.cdb")) == -1) strerr_die2sys(100, FATAL, "unable to open data.cdb: "); cdb_init(&c, fdcdb); cdb_findstart(&c); /* search host */ for (;;) { if(! cdb_findnext(&c, host, dns_domain_length(host))) { cdb_free(&c); close(fdcdb); strerr_die3x(114, FATAL, dynhost, ": not found in data.cdb."); } dpos =cdb_datapos(&c); dlen =cdb_datalen(&c); /* check data size */ if ((dlen != 19) && (dlen != 21)) continue; /* read data */ if (cdb_read(&c, data, dlen, dpos) == -1) { cdb_free(&c); close(fdcdb); strerr_die3sys(111, FATAL, dynhost, ": cdb_read: "); } if (dlen == 19) if (data[2] != '=') continue; if (dlen == 21) { if (data[2] != '>') continue; if (! loc || ! byte_equal(&data[3], 2, loc)) continue; } l =dlen -19; /* check record type */ if (byte_equal(data, 2, DNS_T_A)) break; } cdb_free(&c); /* manipulate data */ if (! ttd) { if (byte_equal(&data[15 +l], 4, ip)) if (byte_diff(&data[3 +l], 4, "\0\0\0\0")) strerr_die3x(0, INFO, dynhost, ": IP address not changed."); if (! ttl) ttl =5; byte_zero(&data[7 +l], 8); } else { tai_now(&tt); tai_uint(&plus, ttd); tai_add(&tt, &tt, &plus); tai_pack(&data[7 +l], &tt); } uint32_pack_big(&data[3 +l], ttl); byte_copy(&data[15 +l], 4, ip); /* copy cdb cdb.tmp */ if (seek_begin(fdcdb) == -1) strerr_die3sys(111, FATAL, dynhost, ": seek: "); if ((fdtmp =open_trunc("data.cdb.tmp")) == -1) strerr_die2sys(111, FATAL, "unable to create data.cdb.tmp: "); buffer_init(&bcdb, buffer_unixread, fdcdb, bcdbspace, sizeof bcdbspace); buffer_init(&btmp, buffer_unixwrite, fdtmp, btmpspace, sizeof btmpspace); while ((i =buffer_feed(&bcdb)) > 0) { if (buffer_put(&btmp, buffer_peek(&bcdb), i) == -1) strerr_die2sys(111, FATAL, "unable to write data.cdb.tmp: "); buffer_seek(&bcdb, i); } if (i == -1) strerr_die2sys(111, FATAL, "unable to read data.cdb: "); if (buffer_flush(&btmp) == -1) strerr_die2sys(111, FATAL, "unable to write data.cdb.tmp: "); /* manipulate cdb.tmp */ if (seek_set(fdtmp, dpos) == -1) strerr_die3sys(111, FATAL, dynhost, ": seek: "); if (write(fdtmp, data, 19 +l) != 19 +l) strerr_die3sys(111, FATAL, dynhost, ": write: "); if (fsync(fdtmp) == -1) strerr_die2sys(111, FATAL, "unable to write data.cdb.tmp: "); if (close(fdtmp) == -1) strerr_die2sys(111, FATAL, "unable to write data.cdb.tmp: "); close(fdcdb); /* move cdb.tmp cdb */ if (rename("data.cdb.tmp", "data.cdb") == -1) strerr_die2sys(111, FATAL, "unable to move data.cdb.tmp to data.cdb: "); buffer_puts(buffer_1, INFO); buffer_puts(buffer_1, "update: "); buffer_puts(buffer_1, dynhost); buffer_puts(buffer_1, " -> "); buffer_puts(buffer_1, dynip); buffer_putsflush(buffer_1, "\n"); _exit(0); } tinydyndns-0.4.2.debian1/trycpp.c000066400000000000000000000001431103424076200167040ustar00rootroot00000000000000int main() { #ifdef NeXT printf("nextstep\n"); exit(0); #endif printf("unknown\n"); exit(0); } tinydyndns-0.4.2.debian1/trydrent.c000066400000000000000000000001331103424076200172350ustar00rootroot00000000000000#include #include void foo() { DIR *dir; struct dirent *d; } tinydyndns-0.4.2.debian1/trylsock.c000066400000000000000000000000231103424076200172320ustar00rootroot00000000000000int main() { ; } tinydyndns-0.4.2.debian1/trypoll.c000066400000000000000000000005201103424076200170670ustar00rootroot00000000000000#include #include #include int main() { struct pollfd x; x.fd = open("trypoll.c",O_RDONLY); if (x.fd == -1) _exit(111); x.events = POLLIN; if (poll(&x,1,10) == -1) _exit(1); if (x.revents != POLLIN) _exit(1); /* XXX: try to detect and avoid poll() imitation libraries */ _exit(0); } tinydyndns-0.4.2.debian1/tryshsgr.c000066400000000000000000000004151103424076200172520ustar00rootroot00000000000000int main() { short x[4]; x[0] = x[1] = 1; if (getgroups(1,x) == 0) if (setgroups(1,x) == -1) _exit(1); if (getgroups(1,x) == -1) _exit(1); if (x[1] != 1) _exit(1); x[1] = 2; if (getgroups(1,x) == -1) _exit(1); if (x[1] != 2) _exit(1); _exit(0); } tinydyndns-0.4.2.debian1/trysysel.c000066400000000000000000000001561103424076200172650ustar00rootroot00000000000000#include #include #include /* SVR4 silliness */ void foo() { ; } tinydyndns-0.4.2.debian1/tryulong32.c000066400000000000000000000005231103424076200174150ustar00rootroot00000000000000int main() { unsigned long u; u = 1; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; if (!u) _exit(0); _exit(1); } tinydyndns-0.4.2.debian1/tryulong64.c000066400000000000000000000005231103424076200174220ustar00rootroot00000000000000int main() { unsigned long u; u = 1; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u; if (!u) _exit(1); _exit(0); } tinydyndns-0.4.2.debian1/uint16.h000066400000000000000000000004071103424076200165210ustar00rootroot00000000000000#ifndef UINT16_H #define UINT16_H typedef unsigned short uint16; extern void uint16_pack(char *,uint16); extern void uint16_pack_big(char *,uint16); extern void uint16_unpack(const char *,uint16 *); extern void uint16_unpack_big(const char *,uint16 *); #endif tinydyndns-0.4.2.debian1/uint16_pack.c000066400000000000000000000002621103424076200175110ustar00rootroot00000000000000#include "uint16.h" void uint16_pack(char s[2],uint16 u) { s[0] = u & 255; s[1] = u >> 8; } void uint16_pack_big(char s[2],uint16 u) { s[1] = u & 255; s[0] = u >> 8; } tinydyndns-0.4.2.debian1/uint16_unpack.c000066400000000000000000000005501103424076200200540ustar00rootroot00000000000000#include "uint16.h" void uint16_unpack(const char s[2],uint16 *u) { uint16 result; result = (unsigned char) s[1]; result <<= 8; result += (unsigned char) s[0]; *u = result; } void uint16_unpack_big(const char s[2],uint16 *u) { uint16 result; result = (unsigned char) s[0]; result <<= 8; result += (unsigned char) s[1]; *u = result; } tinydyndns-0.4.2.debian1/uint32.h1000066400000000000000000000004051103424076200165760ustar00rootroot00000000000000#ifndef UINT32_H #define UINT32_H typedef unsigned int uint32; extern void uint32_pack(char *,uint32); extern void uint32_pack_big(char *,uint32); extern void uint32_unpack(const char *,uint32 *); extern void uint32_unpack_big(const char *,uint32 *); #endif tinydyndns-0.4.2.debian1/uint32.h2000066400000000000000000000004061103424076200166000ustar00rootroot00000000000000#ifndef UINT32_H #define UINT32_H typedef unsigned long uint32; extern void uint32_pack(char *,uint32); extern void uint32_pack_big(char *,uint32); extern void uint32_unpack(const char *,uint32 *); extern void uint32_unpack_big(const char *,uint32 *); #endif tinydyndns-0.4.2.debian1/uint32_pack.c000066400000000000000000000004461103424076200175130ustar00rootroot00000000000000#include "uint32.h" void uint32_pack(char s[4],uint32 u) { s[0] = u & 255; u >>= 8; s[1] = u & 255; u >>= 8; s[2] = u & 255; s[3] = u >> 8; } void uint32_pack_big(char s[4],uint32 u) { s[3] = u & 255; u >>= 8; s[2] = u & 255; u >>= 8; s[1] = u & 255; s[0] = u >> 8; } tinydyndns-0.4.2.debian1/uint32_unpack.c000066400000000000000000000010601103424076200200470ustar00rootroot00000000000000#include "uint32.h" void uint32_unpack(const char s[4],uint32 *u) { uint32 result; result = (unsigned char) s[3]; result <<= 8; result += (unsigned char) s[2]; result <<= 8; result += (unsigned char) s[1]; result <<= 8; result += (unsigned char) s[0]; *u = result; } void uint32_unpack_big(const char s[4],uint32 *u) { uint32 result; result = (unsigned char) s[0]; result <<= 8; result += (unsigned char) s[1]; result <<= 8; result += (unsigned char) s[2]; result <<= 8; result += (unsigned char) s[3]; *u = result; } tinydyndns-0.4.2.debian1/uint64.h1000066400000000000000000000001461103424076200166050ustar00rootroot00000000000000#ifndef UINT64_H #define UINT64_H /* sysdep: -ulong64 */ typedef unsigned long long uint64; #endif tinydyndns-0.4.2.debian1/uint64.h2000066400000000000000000000001411103424076200166010ustar00rootroot00000000000000#ifndef UINT64_H #define UINT64_H /* sysdep: +ulong64 */ typedef unsigned long uint64; #endif tinydyndns-0.4.2.debian1/utime.c000066400000000000000000000005361103424076200165140ustar00rootroot00000000000000#include #include #include "scan.h" #include "exit.h" char *fn; char *ustr; unsigned long u; time_t ut[2]; int main(int argc,char **argv) { fn = argv[1]; if (!fn) _exit(100); ustr = argv[2]; if (!ustr) _exit(100); scan_ulong(ustr,&u); ut[0] = ut[1] = u; if (utime(fn,ut) == -1) _exit(111); _exit(0); } tinydyndns-0.4.2.debian1/walldns-conf.c000066400000000000000000000021631103424076200177560ustar00rootroot00000000000000#include #include #include "strerr.h" #include "exit.h" #include "auto_home.h" #include "generic-conf.h" #define FATAL "walldns-conf: fatal: " void usage(void) { strerr_die1x(100,"walldns-conf: usage: walldns-conf acct logacct /walldns myip"); } char *dir; char *user; char *loguser; struct passwd *pw; char *myip; int main(int argc,char **argv) { user = argv[1]; if (!user) usage(); loguser = argv[2]; if (!loguser) usage(); dir = argv[3]; if (!dir) usage(); if (dir[0] != '/') usage(); myip = argv[4]; if (!myip) usage(); pw = getpwnam(loguser); if (!pw) strerr_die3x(111,FATAL,"unknown account ",loguser); init(dir,FATAL); makelog(loguser,pw->pw_uid,pw->pw_gid); makedir("env"); perm(02755); start("env/ROOT"); outs(dir); outs("/root\n"); finish(); perm(0644); start("env/IP"); outs(myip); outs("\n"); finish(); perm(0644); start("run"); outs("#!/bin/sh\nexec 2>&1\nexec envuidgid "); outs(user); outs(" envdir ./env softlimit -d250000 "); outs(auto_home); outs("/bin/walldns\n"); finish(); perm(0755); makedir("root"); perm(02755); _exit(0); } tinydyndns-0.4.2.debian1/walldns.c000066400000000000000000000025131103424076200170320ustar00rootroot00000000000000#include "byte.h" #include "dns.h" #include "dd.h" #include "response.h" const char *fatal = "walldns: fatal: "; const char *starting = "starting walldns\n"; void initialize(void) { ; } int respond(char *q,char qtype[2]) { int flaga; int flagptr; char ip[4]; int j; flaga = byte_equal(qtype,2,DNS_T_A); flagptr = byte_equal(qtype,2,DNS_T_PTR); if (byte_equal(qtype,2,DNS_T_ANY)) flaga = flagptr = 1; if (flaga || flagptr) { if (dd(q,"",ip) == 4) { if (flaga) { if (!response_rstart(q,DNS_T_A,655360)) return 0; if (!response_addbytes(ip,4)) return 0; response_rfinish(RESPONSE_ANSWER); } return 1; } j = dd(q,"\7in-addr\4arpa",ip); if (j >= 0) { if (flaga && (j == 4)) { if (!response_rstart(q,DNS_T_A,655360)) return 0; if (!response_addbytes(ip + 3,1)) return 0; if (!response_addbytes(ip + 2,1)) return 0; if (!response_addbytes(ip + 1,1)) return 0; if (!response_addbytes(ip + 0,1)) return 0; response_rfinish(RESPONSE_ANSWER); } if (flagptr) { if (!response_rstart(q,DNS_T_PTR,655360)) return 0; if (!response_addname(q)) return 0; response_rfinish(RESPONSE_ANSWER); } return 1; } } response[2] &= ~4; response[3] &= ~15; response[3] |= 5; return 1; } tinydyndns-0.4.2.debian1/warn-auto.sh000066400000000000000000000001001103424076200174610ustar00rootroot00000000000000#!/bin/sh # WARNING: This file was auto-generated. Do not edit! tinydyndns-0.4.2.debian1/warn-shsgr000066400000000000000000000003131103424076200172340ustar00rootroot00000000000000Oops. Your getgroups() returned 0, and setgroups() failed; this means that I can't reliably do my shsgr test. Please either ``make'' as root or ``make'' while you're in one or more supplementary groups. tinydyndns-0.4.2.debian1/x86cpuid.c000066400000000000000000000011651103424076200170420ustar00rootroot00000000000000#include void nope() { exit(1); } int main() { unsigned long x[4]; unsigned long y[4]; int i; int j; char c; signal(SIGILL,nope); x[0] = 0; x[1] = 0; x[2] = 0; x[3] = 0; asm volatile(".byte 15;.byte 162" : "=a"(x[0]),"=b"(x[1]),"=c"(x[3]),"=d"(x[2]) : "0"(0) ); if (!x[0]) return 0; asm volatile(".byte 15;.byte 162" : "=a"(y[0]),"=b"(y[1]),"=c"(y[2]),"=d"(y[3]) : "0"(1) ); for (i = 1;i < 4;++i) for (j = 0;j < 4;++j) { c = x[i] >> (8 * j); if (c < 32) c = 32; if (c > 126) c = 126; putchar(c); } printf("-%08x-%08x\n",y[0],y[3]); return 0; }