Changeset 637
- Timestamp:
- 05/27/14 17:26:04 (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/DNSDB.pm
r636 r637 5815 5815 } 5816 5816 5817 # Utility sub-sub for reverse records; with "any-record-in-any-zone" 5818 # we may need to do extra processing on $val to make it publishable. 5819 sub __revswap { 5820 my $host = shift; 5821 my $val = shift; 5822 return ($val, $host) if $val =~ /\.arpa/; 5823 $val = new NetAddr::IP $val; 5824 my $newval = _ZONE($val, 'ZONE', 'r', '.').($val->{isv6} ? '.ip6.arpa' : '.in-addr.arpa'); 5825 return ($newval, $host); 5826 } 5827 5817 5828 ## WARNING: This works to export even the whole Internet's worth of IP space... 5818 5829 ## if you have the disk/RAM to handle the dataset, and you call this sub based on /16-sized chunks … … 5830 5841 my $stamp = shift; 5831 5842 my $loc = shift; 5843 my $zone = new NetAddr::IP shift; 5832 5844 my $ptronly = shift || 0; 5845 5846 # do this conversion once, not (number-of-ips-in-subnet) times 5847 my $arpabase = _ZONE($zone, 'ZONE.in-addr.arpa', 'r', '.'); 5833 5848 5834 5849 my $iplist = $sub->splitref(32); … … 5836 5851 my $ip = $_->addr; 5837 5852 # make as if we split the non-octet-aligned block into octet-aligned blocks as with SOA 5853 my $lastoct = (split /\./, $ip)[3]; 5838 5854 next if $ip =~ /\.(0|255)$/; # && $self->{skip_net_0} 5839 5855 next if $$recflags{$ip}; # && $self->{skip_bcast_255} … … 5841 5857 next if $hpat eq '%blank%'; # Allows blanking a subnet so no records are published. 5842 5858 my $rec = $hpat; # start fresh with the template for each IP 5859 ##fixme: there really isn't a good way to handle sub-/24 zones here. This way at least 5860 # seems less bad than some alternatives. 5843 5861 _template4_expand(\$rec, $ip); 5844 print $fh ($ptronly ? "^"._ZONE($_, 'ZONE.in-addr.arpa', 'r', '.').":$rec" : "=$rec:$ip"). 5845 ":$ttl:$stamp:$loc\n" or die $!; 5862 if ($ptronly || $zone->masklen > 24) { 5863 print $fh "^$lastoct.$arpabase:$rec:$ttl:$stamp:$loc\n" or die $!; 5864 if (!$ptronly) { 5865 # print a separate A record. Arguably we could use an = record here instead. 5866 print $fh "+$rec:$ip:$ttl:$stamp:$loc\n" or die $!; 5867 } 5868 } else { 5869 print $fh "=$rec:$ip:$ttl:$stamp:$loc\n" or die $!; 5870 } 5846 5871 } 5847 5872 } … … 5850 5875 5851 5876 ##fixme? append . to all host/val hostnames 5877 #print "debug: rawdata: $host $typemap{$type} $val\n"; 5852 5878 5853 5879 if ($typemap{$type} eq 'SOA') { … … 5880 5906 } elsif ($typemap{$type} eq 'A') { 5881 5907 5908 ($host,$val) = __revswap($host,$val) if $revrec eq 'y'; 5882 5909 print $datafile "+$host:$val:$ttl:$stamp:$loc\n" or die $!; 5883 5910 … … 5912 5939 } elsif ($typemap{$type} eq 'AAAA') { 5913 5940 5914 # print $datafile ":$host:28:";5941 ($host,$val) = __revswap($host,$val) if $revrec eq 'y'; 5915 5942 my $altgrp = 0; 5916 5943 my @altconv; … … 5936 5963 } elsif ($typemap{$type} eq 'MX') { 5937 5964 5938 ##fixme: what if we get an MX AXFRed into a reverse zone? 5965 ($host,$val) = __revswap($host,$val) if $revrec eq 'y'; 5939 5966 print $datafile "\@$host"."::$val:$dist:$ttl:$stamp:$loc\n" or die $!; 5940 5967 5941 5968 } elsif ($typemap{$type} eq 'TXT') { 5942 5969 5970 ($host,$val) = __revswap($host,$val) if $revrec eq 'y'; 5943 5971 ##fixme: split v-e-r-y long TXT strings? will need to do so for BIND export, at least 5944 if ($revrec eq 'n') { 5945 $val =~ s/:/\\072/g; # may need to replace other symbols 5946 print $datafile "'$host:$val:$ttl:$stamp:$loc\n" or die $!; 5947 } else { 5948 $host =~ s/:/\\072/g; # may need to replace other symbols 5949 my $val2 = NetAddr::IP->new($val); 5950 print $datafile "'"._ZONE($val2, 'ZONE', 'r', '.').($val2->{isv6} ? '.ip6.arpa' : '.in-addr.arpa'). 5951 ":$host:$ttl:$stamp:$loc\n" or die $!; 5952 } 5972 $val =~ s/:/\\072/g; # may need to replace other symbols 5973 print $datafile "'$host:$val:$ttl:$stamp:$loc\n" or die $!; 5953 5974 5954 5975 # by-hand TXT … … 5971 5992 } elsif ($typemap{$type} eq 'CNAME') { 5972 5993 5973 if ($revrec eq 'n') { 5974 print $datafile "C$host:$val:$ttl:$stamp:$loc\n" or die $!; 5975 } else { 5976 my $val2 = NetAddr::IP->new($val); 5977 print $datafile "C"._ZONE($val2, 'ZONE', 'r', '.').($val2->{isv6} ? '.ip6.arpa' : '.in-addr.arpa'). 5978 ":$host:$ttl:$stamp:$loc\n" or die $!; 5979 } 5994 ($host,$val) = __revswap($host,$val) if $revrec eq 'y'; 5995 print $datafile "C$host:$val:$ttl:$stamp:$loc\n" or die $!; 5980 5996 5981 5997 } elsif ($typemap{$type} eq 'SRV') { 5998 5999 ($host,$val) = __revswap($host,$val) if $revrec eq 'y'; 5982 6000 5983 6001 # data is two-byte values for priority, weight, port, in that order, 5984 6002 # followed by length/string data 5985 6003 5986 print $datafile ":$host:33:".octalize($dist,'d').octalize($weight,'d').octalize($port,'d') or die $!;6004 my $prefix = ":$host:33:".octalize($dist,'d').octalize($weight,'d').octalize($port,'d'); 5987 6005 5988 6006 $val .= '.' if $val !~ /\.$/; 5989 6007 foreach (split /\./, $val) { 5990 printf $datafile"\\%0.3o%s", length($_), $_ or die $!;5991 } 5992 print $datafile " \\000:$ttl:$stamp:$loc\n" or die $!;6008 $prefix .= sprintf "\\%0.3o%s", length($_), $_ or die $!; 6009 } 6010 print $datafile "$prefix\\000:$ttl:$stamp:$loc\n" or die $!; 5993 6011 5994 6012 } elsif ($typemap{$type} eq 'RP') { 5995 6013 6014 ($host,$val) = __revswap($host,$val) if $revrec eq 'y'; 5996 6015 # RP consists of two mostly free-form strings. 5997 6016 # The first is supposed to be an email address with @ replaced by . (as with the SOA contact) … … 6010 6029 } elsif ($typemap{$type} eq 'PTR') { 6011 6030 6012 $zone = NetAddr::IP->new($zone);6013 6031 $$recflags{$val}++; 6014 if (!$zone->{isv6} && $zone->masklen > 24) { 6015 ($val) = ($val =~ /\.(\d+)$/); 6016 print $datafile "^$val."._ZONE($zone, 'ZONE', 'r', '.').'.in-addr.arpa'. 6017 ":$host:$ttl:$stamp:$loc\n" or die $!; 6032 if ($revrec eq 'y') { 6033 6034 if ($val =~ /\.arpa$/) { 6035 # someone put in the formal .arpa name. humor them. 6036 print $datafile "^$val:$host:$ttl:$stamp:$loc\n" or die $!; 6037 } else { 6038 $zone = NetAddr::IP->new($zone); 6039 if (!$zone->{isv6} && $zone->masklen > 24) { 6040 # sub-octet v4 zone 6041 ($val) = ($val =~ /\.(\d+)$/); 6042 print $datafile "^$val."._ZONE($zone, 'ZONE', 'r', '.').'.in-addr.arpa'. 6043 ":$host:$ttl:$stamp:$loc\n" or die $!; 6044 } else { 6045 # not going to care about strange results if $val is not an IP value and is resolveable in DNS 6046 $val = NetAddr::IP->new($val); 6047 print $datafile "^". 6048 _ZONE($val, 'ZONE', 'r', '.').($val->{isv6} ? '.ip6.arpa' : '.in-addr.arpa'). 6049 ":$host:$ttl:$stamp:$loc\n" or die $!; 6050 } 6051 } # non-".arpa" $val 6052 6018 6053 } else { 6019 $val = NetAddr::IP->new($val);6020 print $datafile "^".6021 _ZONE($val, 'ZONE', 'r', '.').($val->{isv6} ? '.ip6.arpa' : '.in-addr.arpa').6022 ":$host:$ttl:$stamp:$loc\n" or die $!;6054 # PTRs in forward zones are less bizarre and insane than some other record types 6055 # in reverse zones... OTOH we can't validate them any which way, so we cross our 6056 # fingers and close our eyes and make it Someone Else's Problem. 6057 print $datafile "^$host:$val:$ttl:$stamp:$loc\n" or die $!; 6023 6058 } 6024 6059 … … 6049 6084 if ($val->masklen <= 16) { 6050 6085 foreach my $sub ($val->split(16)) { 6051 __publish_subnet($sub, $recflags, $host, $datafile, $ttl, $stamp, $loc, 1);6086 __publish_subnet($sub, $recflags, $host, $datafile, $ttl, $stamp, $loc, $zone, 1); 6052 6087 } 6053 6088 } else { 6054 __publish_subnet($val, $recflags, $host, $datafile, $ttl, $stamp, $loc, 1);6089 __publish_subnet($val, $recflags, $host, $datafile, $ttl, $stamp, $loc, $zone, 1); 6055 6090 } 6056 6091 … … 6063 6098 if ($val->masklen <= 16) { 6064 6099 foreach my $sub ($val->split(16)) { 6065 __publish_subnet($sub, $recflags, $host, $datafile, $ttl, $stamp, $loc, 0);6100 __publish_subnet($sub, $recflags, $host, $datafile, $ttl, $stamp, $loc, $zone, 0); 6066 6101 } 6067 6102 } else { 6068 __publish_subnet($val, $recflags, $host, $datafile, $ttl, $stamp, $loc, 0);6103 __publish_subnet($val, $recflags, $host, $datafile, $ttl, $stamp, $loc, $zone, 0); 6069 6104 } 6070 6105 … … 6078 6113 6079 6114 # All delegations need to create one or more NS records. The NS record handler knows what to do. 6080 _printrec_tiny($datafile,$re vrec,$recflags,$zone,$host,$reverse_typemap{'NS'},6115 _printrec_tiny($datafile,$recid,$revrec,$recflags,$zone,$host,$reverse_typemap{'NS'}, 6081 6116 $val,$dist,$weight,$port,$ttl,$loc,$stamp); 6082 6117 if ($revrec eq 'y') { 6083 6118 # In the case of a sub-/24 v4 reverse delegation, we need to generate CNAMEs 6084 6119 # to redirect all of the individual IP lookups as well. 6120 # OR 6121 # create NS records for each IP 6085 6122 # Not sure how this would actually resolve if a /24 or larger was delegated 6086 6123 # one way, and a sub-/24 in that >=/24 was delegated elsewhere... … … 6103 6140 6104 6141 } elsif ($type == 44) { # SSHFP 6142 6143 ($host,$val) = __revswap($host,$val) if $revrec eq 'y'; 6144 6105 6145 my ($algo,$fpt,$fp) = split /\s+/, $val; 6106 6146
Note:
See TracChangeset
for help on using the changeset viewer.