DBNDNS

Convert zonefile records into djbdns format

#!/usr/bin/perl -w
use strict;
use Net::DNS::RR;

# format a DNS record for DJBDNS
while (<STDIN>) {
        my $loc = Net::DNS::RR->new($_);

        print ":",$loc->name,":",Net::DNS::typesbyname($loc->type),":";
        foreach (unpack "C*",$loc->rr_rdata) {
                if (($_ > 47 && $_ < 58) || 
                    ($_ > 64 && $_ < 91) || 
                    ($_ > 96 && $_ < 123)) {
                        print chr($_);
                } else {
                        printf "\\%03o", $_;
                }
        }
        print ":",$loc->ttl,"\n";
}

It is possible to correct IPv4 dynamic entries based on DHCP entries. This uses IPv6 assignments to tell which names and MAC addresses belong tegether in the DNS and so needs no other configuration than locations of files.

#!/bin/bash

DHCP=/var/lib/dhcp3/dhcpd.leases
DBNDNS=/etc/sv/root/data

while inotifywait -e modify "${DHCP}"
do
while read
do
	if test "${REPLY:0:5}" = "lease"
	then
		IP=$(cut -f2 -d" " <<<"${REPLY}")
		MAC=
		continue
	elif test "${REPLY:0:20}" = "  hardware ethernet " 
	then
		MAC=${REPLY:20:2}${REPLY:23:2}${REPLY:26:2}${REPLY:29:2}${REPLY:32:2}${REPLY:35:2}
	else
		continue
	fi

	unset ALIAS
	unset HOST

	# echo IP is $IP MAC is $MAC

	#MAC=$(tr -d : <<<"$1")

	FLIP=$(( ${MAC:1:1} ^ 2 ))

	if test "${FLIP}" = "10"; then FLIP="a"; fi
	if test "${FLIP}" = "11"; then FLIP="b"; fi
	if test "${FLIP}" = "12"; then FLIP="c"; fi
	if test "${FLIP}" = "13"; then FLIP="d"; fi
	if test "${FLIP}" = "14"; then FLIP="e"; fi
	if test "${FLIP}" = "15"; then FLIP="f"; fi

	while read
	do
		if test -z  "${REPLY}"
		then
			continue
		fi

		if test "${REPLY:$((${#REPLY}-1)):1}" = "."
		then
			HOST[${#HOST[*]}]="${REPLY:0:$((${#REPLY}-1))}"
		else
			HOST[${#HOST[*]}]="${REPLY}"
		fi
	done <<<"$(egrep -i $'^\^'${MAC:11:1}$'\.'${MAC:10:1}$'\.'${MAC:9:1}$'\.'${MAC:8:1}$'\.'${MAC:7:1}$'\.'${MAC:6:1}$'\.e\.f\.f\.f\.'\
${MAC:5:1}$'\.'${MAC:4:1}$'\.'${MAC:3:1}$'\.'${MAC:2:1}$'\.'${FLIP}$'\.'${MAC:0:1}\
$'.{32}\.ip6\.arpa:' "${DBNDNS}"|cut -f2 -d":")"

	while read
	do
		if test -z  "${REPLY}"
		then
			continue
		fi

		for N in ${HOST[*]}
		do
			if test "${N}" = "${REPLY:1}"
			then
				continue 2
			fi
		done
		ALIAS[${#ALIAS[*]}]="${REPLY:1}"
	done <<<"$(egrep -i $'^3[^:]*:.{16}'${MAC:0:1}${FLIP}${MAC:2:4}$'fffe'${MAC:6:6}':' "${DBNDNS}"|cut -d":" -f1)"

	# disable all lines - we lose which is the nodename but is obvious from ipv6 reverse DNS
	sed -i $'s/^[=+-]\\([^:]*\\):\\('"${IP}"$'\\):\\([0-9]*\\)$/-\\1:\\2:\\3/' "${DBNDNS}"

	for N in ${HOST[*]}
	do
		# echo host: $N
		sed -i $'s/^[=-]'"${N}"$':.*$/='"${N}"$':'"${IP}"$':7200/' "${DBNDNS}"
	done

	echo

	for N in ${ALIAS[*]}
	do
		# echo alias: $N
		sed -i $'s/^[\+-]'"${N}"$':.*$/+'"${N}"$':'"${IP}"$':7200/' "${DBNDNS}"
	done
done < "${DHCP}"
done