#!/usr/bin/perl
#
# This script parses the dhcp server leases file and fetches hostnames
# sent by clients. Two lines are printed for each match, forward (A) and
# reverse (PTR).
# 
# Syntax is: <name> <type> <content>
# 
# Example: foo.int.fatal.se A 10.185.10.1
#          1.10.185.10.in-addr.arpa PTR foo.int.fatal.se
#


use strict;

# -------------------------------------
# configuration variables
# -------------------------------------

my $leasefile="/var/lib/dhcp3/dhcpd.leases";
my $domain="int.fatal.se";
my $domain2="int.fjortis.info";
my $debug=0;

# -------------------------------------
# End of configuration
# -------------------------------------

sub validip {
	my $ip = shift(@_);

	if ($ip =~ m/\d+\.\d+.\d+\.\d+/) {
		print STDERR $ip . " is a valid ip!\n" if $debug;
		return 1;
	} else {
		print STDERR $ip . " is NOT a valid ip!\n" if $debug;
		return 0;
	}
}

sub makereverse {
	my $ip = shift(@_);
	my @tmp;

	@tmp = split(/\./, $ip);
	
	return $tmp[3] . "." . $tmp[2] . "." . $tmp[1] . "." . $tmp[0] . ".in-addr.arpa";
}


open LF, "< $leasefile" or die("Unable to open lease file: $leasefile");

my $leaseip=0;

while (<LF>) {
	if (m/^\s*lease/) {
		my @tmp;
		@tmp = split(" ");
		$leaseip = $tmp[1];
		print STDERR "lease found with ip " . $tmp[1] . "\n" if $debug;
	}

	if (m/^\s*}\s*$/) {
		$leaseip=0;
	}

	if (m/^\s*client-hostname/ && validip($leaseip)) {
		my @tmp;
		my $host;
		@tmp = split("\"");
		$host = $tmp[1];
		$host =~ s/\.$domain$//; # if client sent full hostname, strip it off.
		$host =~ s/\.$domain2$//; # if client sent full hostname, strip it off.

		print STDERR $leaseip . " -- " . $host . "\n" if $debug;
		if ($host =~ m/[^a-zA-Z0-9-]/) {
			print STDERR "IGNORING Invalid hostname " . $host . " set from " . $leaseip . ".\n";
		} else {
			print STDOUT $host . "." . $domain . " A " . $leaseip . "\n";
			print STDOUT $host . "." . $domain2 . " A " . $leaseip . "\n";
			# FIXME: add reverse!
			print STDOUT makereverse($leaseip) . " PTR " . $host . "." . $domain . "\n";
		}
	}
}

close(LF);


