Changeset 337
- Timestamp:
- 05/25/12 17:31:09 (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/DNSDB.pm
r336 r337 957 957 return ('OK', $cidr); 958 958 } # done _zone2cidr() 959 960 # Record template %-parameter expansion, IPv4. Note that IPv6 doesn't 961 # really have a sane way to handle this type of expansion at the moment 962 # due to the size of the address space. 963 # Takes a reference to a template string to be expanded, and an IP to use in the replacement. 964 sub _template4_expand { 965 my $tmpl = shift; 966 my $ip = shift; 967 968 my @ipparts = split /\./, $ip; 969 my @iphex; 970 my @ippad; 971 for (@ipparts) { 972 push @iphex, sprintf("%x", $_); 973 push @ippad, sprintf("%u.3", $_); 974 } 975 976 # IP substitutions in template records: 977 #major patterns: 978 #dashed IP, forward and reverse 979 #dotted IP, forward and reverse (even if forward is... dumb) 980 # -> %r for reverse, %i for forward, leading - or . to indicate separator, defaults to - 981 # %r or %-r => %4d-%3d-%2d-%1d 982 # %.r => %4d.%3d.%2d.%1d 983 # %i or %-i => %1d-%2d-%3d-%4d 984 # %.i => %1d.%2d.%3d.%4d 985 $$tmpl =~ s/\%r/\%4d-\%3d-\%2d-\%1d/g; 986 $$tmpl =~ s/\%([-.])r/\%4d$1\%3d$1\%2d$1\%1d/g; 987 $$tmpl =~ s/\%i/\%1d-\%2d-\%3d-\%4d/g; 988 $$tmpl =~ s/\%([-.])i/\%1d$1\%2d$1\%3d$1\%4d/g; 989 990 #hex-coded IP 991 # %h 992 $$tmpl =~ s/\%h/$iphex[0]$iphex[1]$iphex[2]$iphex[3]/g; 993 994 #IP as decimal-coded 32-bit value 995 # %d 996 my $iptmp = $ipparts[0]*256*256*256 + $ipparts[1]*256*256 + $ipparts[2]*256 + $ipparts[3]; 997 $$tmpl =~ s/\%d/$iptmp/g; 998 999 #minor patterns (per-octet) 1000 # %[1234][dh0] 1001 #octet 1002 #hex-coded octet 1003 #0-padded octet 1004 $$tmpl =~ s/\%([1234])d/$ipparts[$1-1]/g; 1005 $$tmpl =~ s/\%([1234])h/$iphex[$1-1]/g; 1006 $$tmpl =~ s/\%([1234])h/$ippad[$1-1]/g; 1007 } # _template4_expand() 959 1008 960 1009 … … 3996 4045 } # while ($domsth) 3997 4046 3998 my $revsth = $dbh->prepare("SELECT rdns_id,revnet,status FROM revzones WHERE status=1"); 4047 my $revsth = $dbh->prepare("SELECT rdns_id,revnet,status FROM revzones WHERE status=1 ". 4048 "ORDER BY masklen(revnet) DESC"); 3999 4049 $recsth = $dbh->prepare("SELECT host,type,val,distance,weight,port,ttl,record_id ". 4000 "FROM records WHERE rdns_id=?"); 4050 "FROM records WHERE rdns_id=? AND type=6 UNION ". 4051 "(SELECT host,type,val,distance,weight,port,ttl,record_id ". 4052 "FROM records WHERE rdns_id=? AND not type=6 ". 4053 "ORDER BY masklen(CAST(val AS inet)) DESC, CAST(val AS inet))"); 4001 4054 $revsth->execute(); 4002 4055 while (my ($revid,$revzone,$revstat) = $revsth->fetchrow_array) { 4003 $recsth->execute($revid );4056 $recsth->execute($revid, $revid); 4004 4057 while (my ($host,$type,$val,$dist,$weight,$port,$ttl,$recid) = $recsth->fetchrow_array) { 4005 4058 next if $recflags{$recid}; … … 4048 4101 my ($refresh, $retry, $expire, $min_ttl) = (split /:/, $val)[0,1,2,3]; 4049 4102 if ($revrec eq 'y') { 4103 ##fixme: have to publish SOA records for each v4 /24 in sub-/16, and each /16 in sub-/8 4104 # what about v6? 4105 # -> only need SOA for local chunks offset from reverse delegation boundaries, so v6 is fine 4050 4106 $zone = NetAddr::IP->new($zone); 4107 # handle split-n-multiply SOA for off-octet (8 < mask < 16) or (16 < mask < 24) v4 zones 4108 if (!$zone->{isv6} && ($zone->masklen < 24) && ($zone->masklen % 8 != 0)) { 4109 foreach my $szone ($zone->split($zone->masklen + (8 - $zone->masklen % 8))) { 4110 $szone = _ZONE($szone, 'ZONE.in-addr.arpa', 'r', '.'); 4111 print $datafile "Z$szone:$primary:$email"."::$refresh:$retry:$expire:$min_ttl:$ttl:$stamp:$loc\n"; 4112 } 4113 return; # skips "default" bits just below 4114 } 4051 4115 $zone = _ZONE($zone, 'ZONE', 'r', '.').($zone->{isv6} ? '.ip6.arpa' : '.in-addr.arpa'); 4052 4116 } … … 4153 4217 4154 4218 $zone = NetAddr::IP->new($zone); 4219 $$recflags{$val}++; 4155 4220 if (!$zone->{isv6} && $zone->masklen > 24) { 4156 4221 ($val) = ($val =~ /\.(\d+)$/); … … 4166 4231 } elsif ($type == 65280) { # A+PTR 4167 4232 4233 $$recflags{$val}++; 4168 4234 print $datafile "=$host:$val:$ttl:$stamp:$loc\n"; 4169 4235 4170 4236 } elsif ($type == 65281) { # AAAA+PTR 4171 4237 4238 #$$recflags{$val}++; 4172 4239 # treat these as two separate records. since tinydns doesn't have 4173 4240 # a native combined type, we have to create them separately anyway. … … 4183 4250 } elsif ($type == 65282) { # PTR template 4184 4251 4252 ##work 4185 4253 # only useful for v4 with standard DNS software, since this expands all 4186 4254 # IPs in $zone (or possibly $val?) with autogenerated records 4187 4188 ##work 4189 use Data::Dumper; 4190 $zone = NetAddr::IP->new($zone); 4191 if (!$zone->{isv6}) { 4192 $val = NetAddr::IP->new($val); 4193 if ($zone == $val) { 4194 my $iplist = $zone->hostenumref; 4195 foreach (@$iplist) { 4196 my $rec = $host; 4197 _template4_expand(\$rec, $_->addr); 4198 print "$_ ptr $rec\n"; 4199 } 4200 } else { 4201 } 4202 } 4203 4204 sub _template4_expand { 4205 my $tmpl = shift; 4206 my $ip = shift; 4207 4208 my @ipparts = split /\./, $ip; 4209 my @iphex; 4210 my @ippad; 4211 for (@ipparts) { 4212 push @iphex, sprintf("%x", $_); 4213 push @ippad, sprintf("%u.3", $_); 4214 } 4215 4216 # IP substitutions in template records: 4217 #major patterns: 4218 #dashed IP, forward and reverse 4219 #dotted IP, forward and reverse (even if forward is... dumb) 4220 # -> %r for reverse, %i for forward, leading - or . to indicate separator, defaults to - 4221 # %r or %-r => %4d-%3d-%2d-%1d 4222 # %.r => %4d.%3d.%2d.%1d 4223 # %i or %-i => %1d-%2d-%3d-%4d 4224 # %.i => %1d.%2d.%3d.%4d 4225 4226 $$tmpl =~ s/\%r/\%4d-\%3d-\%2d-\%1d/g; 4227 $$tmpl =~ s/\%([-.])r/\%4d$1\%3d$1\%2d$1\%1d/g; 4228 $$tmpl =~ s/\%i/\%1d-\%2d-\%3d-\%4d/g; 4229 $$tmpl =~ s/\%([-.])i/\%1d$1\%2d$1\%3d$1\%4d/g; 4230 4231 #hex-coded IP 4232 # %h 4233 $$tmpl =~ s/\%h/$iphex[0]$iphex[1]$iphex[2]$iphex[3]/g; 4234 4235 #IP as decimal-coded 32-bit value 4236 # %d 4237 my $iptmp = $ipparts[0]*256*256*256 + $ipparts[1]*256*256 + $ipparts[2]*256 + $ipparts[3]; 4238 $$tmpl =~ s/\%d/$iptmp/g; 4239 4240 #minor patterns (per-octet) 4241 # %[1234][dh0] 4242 #octet 4243 #hex-coded octet 4244 #0-padded octet 4245 $$tmpl =~ s/\%([1234])d/$ipparts[$1-1]/g; 4246 $$tmpl =~ s/\%([1234])h/$iphex[$1-1]/g; 4247 $$tmpl =~ s/\%([1234])h/$ippad[$1-1]/g; 4248 4249 } # _template4_expand() 4255 $val = NetAddr::IP->new($val); 4256 return if $val->{isv6}; 4257 4258 my $iplist = $val->hostenumref; 4259 foreach (@$iplist) { 4260 my $ip = $_->addr; 4261 # make as if we split the non-octet-aligned block into octet-aligned blocks as with SOA 4262 next if $ip =~ /\.(0|255)$/; 4263 next if $$recflags{$ip}; 4264 $$recflags{$ip}++; 4265 my $rec = $host; # start fresh with the template for each IP 4266 _template4_expand(\$rec, $ip); 4267 print $datafile "^"._ZONE($_, 'ZONE.in-addr.arpa', 'r', '.').":$rec:$ttl:$stamp:$loc\n"; 4268 } 4250 4269 4251 4270 } elsif ($type == 65283) { # A+PTR template 4252 4271 4253 if (!$zone->{isv6}) { # Just In Case. An A+PTR should be impossible to add to a v6 revzone via API. 4254 } 4272 $val = NetAddr::IP->new($val); 4273 # Just In Case. An A+PTR should be impossible to add to a v6 revzone via API. 4274 return if $val->{isv6}; 4275 my $iplist = $val->hostenumref; 4276 foreach (@$iplist) { 4277 my $ip = $_->addr; 4278 # make as if we split the non-octet-aligned block into octet-aligned blocks as with SOA 4279 next if $ip =~ /\.(0|255)$/; 4280 next if $$recflags{$ip}; 4281 $$recflags{$ip}++; 4282 my $rec = $host; # start fresh with the template for each IP 4283 _template4_expand(\$rec, $ip); 4284 print $datafile "=$rec:$ip:$ttl:$stamp:$loc\n"; 4285 } 4255 4286 4256 4287 } elsif ($type == 65284) { # AAAA+PTR template
Note:
See TracChangeset
for help on using the changeset viewer.