#!/usr/bin/perl $debug = 0; require Time::Local; # read in servers file $path = "/etc/bind/reverse"; $server_file = shift || "$path/hosts"; increment_serial(); open(SERVERS,"<$server_file"); while($in = ) { chop($in); ($ip, $host) = split(/\s+/,$in); if($host && $ip) { $reverse{$ip} = $host; print "Preloading $host: [$ip]\n" if($debug); } } close(SERVERS); # read in DHCP leases open(LEASES,") { chop($in); # is this a start of lease line? if(($trim) = $in =~ /^lease(.*){$/) { ($ip) = $trim =~ /.*?(\d+\.\d+\.\d+\.\d+).*/; $host = ""; print "Found lease: ($trim)[$ip]\n" if($debug); } # is this a hostname line? If so, and we have a valid IP, store if($ip && (($host) = $in =~ /\s*client-hostname.*\"(.*)\".*/)) { $reverse{$ip} = $host; if((defined $dhcp_date{$host}) && ($dhcp_date{$host} > $dhcp_date)) { # no op } else { $dhcp{$host} = $ip; $dhcp_date{$host} = $dhcp_date; } print "Found host for lease: $ip -> $host\n" if($debug); } # is this the end of a stanza? If so, discard ip and host if($ip && (($year,$month,$day,$hour,$minute,$second) = /\s*\d+\s*(\d+)\/(\d+)\/(\d+)\s+(\d+):(\d+):(\d+);/)) { $unix_date = timelocal($second,$minute,$hour,$day,$month,$year); $dhcp_date = $unix_date; } if($in =~ /.*}.*/) { $ip = undef; $host = undef; $dhcp_date = undef; print "end stanza\n" if($debug); } } close(LEASES); $networks_file = "$path/networks"; open(NETWORKS,"<$networks_file"); while($in = ) { chop($in); ($net, $ext,$pre) = split(/\s+/,$in); $ext{$net} = $ext; $pre{$net} = $pre; print "Preloading $net: e[$ext] p[$pre]\n" if($debug); push(@networks,$net); } # reverse the network name foreach $ip (keys %reverse) { $host = $reverse{$ip}; print "$ip -> $host\n" if($debug); } foreach $net (@networks) { build_reverse($net); } ping_hosts(); build_dynamic(); sub increment_serial { $serial_file = "$path/serial"; open(SERIAL,"<$serial_file") || die "No serial file"; $in = ; chop($in); if($in < 1997022700) { $in = "2007000777"; } else { $in++; } $official_serial = $in; open(SERIAL,">$serial_file"); print SERIAL $in . "\n"; print "Official serial is $official_serial" if($debug); close(SERIAL); } sub build_reverse { my $net = shift; @r = split(/\./,$net); # we could recurse here, but we dont die "I only do class C" if(@r < 3); $myaddr = ""; while(defined($a = pop(@r))) { $myaddr .= "." if($myaddr ne ""); $myaddr .= $a; } print "Building reverse for $net / $myaddr\n" if($debug); $bigstring = ""; for($i=1;$i<256;$i++) { $thisip = "$net\.$i"; if(defined $reverse{$thisip}) { $host = $reverse{$thisip}; print "Looking up $thisip: $host\n" if($debug); } else { $host = $pre{$net} . $i . $ext{$net}; } $bigstring .= "$i\tIN\tPTR\t$host\.\n"; } $zone_file = "$path/rev.$net"; $template_file = "$path/template"; open(TEMPLATE,"<$path/template"); open(OUT,">$zone_file"); while($in =