#!/bin/bash
# tld.sh V1.07 by Sven Neuhaus <sven@ping.de>
# Last modified: Tue Jan 22 11:09:37 CET 2008
#
# cronjob to check changes in TLD wildcard A-Records
# cron will send mail if there have been changes.
#
# Needs echo, (GNU) date, sed, test, touch, sort, uniq, diff, rm, 
# dnsq and dnsqr (part of djbdns) in PATH
# Run in a safe directory. Root privileges not required.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
# 
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

DEBUG=1
OLDER=wildcards.`date --iso-8601 --date="2 days ago"`
YESTERDAY=wildcards.`date --iso-8601 --date=yesterday`
TODAY=wildcards.`date --iso-8601`

touch -a $OLDER $YESTERDAY       # create unless exist

debug () { # echo to stderr if DEBUG 
  if [ $DEBUG -ge 1 ]; then 
    echo $* 1>&2
  fi
}

# IANA domain list: http://www.iana.org/domains/root/db/
# not yet active: post xxx
# inactive: bl eh mf um
( for TLD in aero asia biz cat com coop edu gov info int jobs mil mobi museum \
    name net org pro travel \
    ac ad ae af ag ai al am an ao aq ar as at au aw ax az \
    ba bb bd be bf bg bh bi bj bm bn bo br bs bt bv bw by bz \
    ca cc cd cf cg ch ci ck cl cm cn co cr cu cv cx cy cz \
    de dj dk dm do dz ec ee eg er es et eu fi fj fk fm fo fr \
    ga gb gd ge gf gg gh gi gl gm gn gp gq gr gs gt gu gw gy \
    hk hm hn hr ht hu id ie il im in io iq ir is it je jm jo jp \
    ke kg kh ki km kn kp kr kw ky kz la lb lc li lk lr ls lt lu lv ly \
    ma mc md me mg mh mk ml mm mn mo mp mq mr ms mt mu mv mw mx my mz \
    na nc ne nf ng ni nl no np nr nu nz om \
    pa pe pf pg ph pk pl pm pn pr ps pt pw py qa re ro ru rw \
    sa sb sc sd se sg sh si sj sk sl sm sn so sr st sv sy sz \
    tc td tf tg th tj tk tl tm tn to tp tr tt tv tw tz \
    ua ug uk us uy uz va vc ve vg vi vn vu wf ws ye yt yu za zm zw
  do
    # find a nameserver for this TLD...
    debug -n query tld $TLD
    for NSAUTH in `dnsqr ns $TLD. | \
        sed -ne 's/^answer.* NS \([a-zA-Z0-9.-]*\)/\1/p'`
      do
        # ...and query it.
	debug -n ,ns $NSAUTH
# .tw has record for '*' but it's no wildcard(!), so this fails:
#        dnsq a '*.'$TLD $NSAUTH | \
#			sed -ne "s/^answer:.* A \([0-9.]*\)/$TLD \1/p"

        TMPNAM=$RANDOM$RANDOM$RANDOM$RANDOM
        IFS="
"
        for ANSWER in `dnsq a $TMPNAM.$TLD $NSAUTH | sed -n \
			-e "s/^answer: $TMPNAM\.$TLD [0-9]* A \([0-9.]*\)/$TLD \1/p" \
			-e "s/^answer: $TMPNAM\.$TLD [0-9]* CNAME \([a-zA-Z0-9.-]*\)/\1/p"`
              # CNAMEs without TLD in front
          do
            # is it a numerical IP? If so, print it with the TLD
            echo $ANSWER | grep -e "^$TLD [0-9.]*$"
            # if its a hostname (from a CNAME record), look it up
		    if [ $? -gt 0 ]; then
              debug -n ,cname lookup.$ANSWER.
              dnsqr a $ANSWER | sed -ne "s/^answer: .* A \([0-9.]*\)/$TLD \1/p"
              # $? = 0
              true
            else
              debug -n ,X
            fi
          done

        # done with this TLD if success
        if [ $? -eq 0 ] ; then
          debug ,ok
          break
	fi
      done
  done 
) | sort | uniq > $TODAY

diff -u $YESTERDAY $TODAY

# cleanup
rm $OLDER

#eof

