#
# hosttbl.awk - parse AXFR records from DIG, look at only the A and CNAME
#             records and print a host table format file to stdout.
#
# Variables passed in:
#	DOMAIN	current domain, i.e. "cse.nau.edu."
#	ALIASLV	number in range 0..N of how many domain levels of aliases
#		to include in host entries.  For example,
#			ALIASLV=0	1.2.3.4 host.dom.ain
#			ALIASLV=1	1.2.3.4 host.dom.ain host
#			ALIASLV=2	1.2.3.4 host.dom.ain host host.dom
#
#
# Copyright (C) 1993-2000 Paul A. Balyoz <pab@domtools.com>
#
#    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.
#
#    You should have received a copy of the GNU General Public License
#    along with this program; if not, write to the Free Software
#    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#

BEGIN {
	killIPs["127.0.0.1"] = 1;
	A[" "] = " ";			# forces A to be an array for sure
	ns[" "] = "0";			# forces ns to be an array for sure
}


# "A" RRs give us the IP address and hostname info for this domain.
#
# Concepts:
#	host		means just the hostname with no domain on the end.
#	host.domain.	means fully qualified domain name for the host.
#	IPaddr		means the IP address as four dot-separated octets.
#
# Algorithm:
#  If the IP address is listed in the killIPs array, skip it.
#  A[IPaddr] = host.domain.
#  f[1] = just the hostname with the domain part removed.
#  If host has not already been seen, set aliases[host.domain.] = host
#  If we've never seen this host.domain. before then set aliases[host.domain.] = host
#  Else if host is not already in the aliases[host.domain.] array, then
#	Add host to front of aliases[host.domain.] array.

$2=="A" {
	if (killIPs[$3] != 1) {
		A[$3] = $1;
		num = split ($1, f, ".");
		# Add f[] derivations to aliases[] list if not already in there.
		# i.e.  pine, pine.cse   (if ALIASLV is 2)
		for (j=1; j<=ALIASLV; j++) {
			dn = f[1];
			for (k=2; k<=j; k++)
				if (f[k] != "")
					dn = dn "." f[k];
			if (seen[$1] != 1) {
				aliases[$1] = dn;
				seen[$1] = 1;
			} else {
				alreadythere = 0;
				split (aliases[$1], faliases, " ");
				for (i in faliases)
					if (faliases[i] == dn)
						alreadythere = 1;
				if (!alreadythere)
					aliases[$1] = dn " " aliases[$1];
			}
		}
	}
	next;
}


# "CNAME" RRs specify hostname aliases for existing hosts,
# so add the alias to the list of names for that host.
# CNAMEs pointing to other CNAMEs will be ignored (besides, it's illegal!)

$2=="CNAME" {
	num = split ($1, f, ".");
	# Add f[] derivations to aliases[] list if not already in there.
	# i.e.  pine, pine.cse   (if ALIASLV is 2)
	for (j=1; j<=ALIASLV; j++) {
		dn = f[1];
		for (k=2; k<=j; k++)
			if (f[k] != "")
				dn = dn "." f[k];
		if (seen[$3] != 1) {
			aliases[$3] = dn;
			seen[$3] = 1;
		} else {
			aliases[$3] = aliases[$3] " " dn;
		}
	}
	next;
}


#
# "NS" records give us the hostnames of all nameservers for this domain.
# Some nameservers may not be in our local domain.
#

$2=="NS" {
	ns[$3] = "1";
	next;
}


#
# END - after all input records have been parsed.
# Print all IP addresses and hosts except those that are name-servers
# which are not actually in this domain.  Nameservers which are in
# this domain get printed!
#

END {

# Mark all nameservers that aren't in our domain with a "0".
# Nameservers that are in our domain get a "1".

	numdomain = split (DOMAIN, fdomain, ".");
	realnumdomain = numdomain;
	for (i in ns) {
		if (i == " ")			# throw away placeholder
			continue;
		good = "1";
		numdomain = realnumdomain;
		numns = split (i, fns, ".");
		while (numns > 0 && numdomain > 0 && good == "1") {
			if (fns[numns] != fdomain[numdomain])
				good = "0";
			numns--;
			numdomain--;
		}
		ns[i] = good;
	}

# Print all IP/host combinations if hostname isn't null.
# Strip off the ending dot on the second-field hostnames.

	for (i in A) {
		if (i == " ")			# throw away placeholder
			continue;

		if (ns[A[i]] != "0") {
			printf ("%s\t", i);		# print IP address
			if (length(i) < 8)	printf ("\t");

			num = split (A[i], fi, ".");
			dn = fi[1];
			for (j=2; j<=num; j++)
				if (fi[j] != "")
					dn = dn "." fi[j];

			printf ("%s", dn);		# print full domain name
			if (aliases[A[i]] != "") {
				printf ("\t");
				if (length(dn) < 24)	printf ("\t");
				if (length(dn) < 16)	printf ("\t");
				if (length(dn) < 8)	printf ("\t");
			}

			printf ("%s\n", aliases[A[i]]);	# print host names & aliases
		}
	}
}
