Changeset 685 for trunk/DNSDB.pm
- Timestamp:
- 07/27/15 17:32:49 (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/DNSDB.pm
r679 r685 1603 1603 # really have a sane way to handle this type of expansion at the moment 1604 1604 # due to the size of the address space. 1605 # Takes a reference to a template string to be expanded, and an IP to use in the replacement. 1605 # Takes a reference to a template string to be expanded, an IP to use in the replacement, 1606 # an optional netblock for the %ngb (net, gw, bcast) expansion, and an optional index 1607 # number for %c "n'th usable IP in block/range" patterns. 1608 # Alters the template string referred. 1606 1609 sub _template4_expand { 1610 # ugh pthui 1611 my $self; 1612 $self = shift if ref($_[0]) eq 'DNSDB'; 1613 1607 1614 my $tmpl = shift; 1608 1615 my $ip = shift; 1616 my $subnet = shift; # for %ngb and %c 1617 my $ipindex = shift; # for %c 1618 1619 # blank $tmpl on config template_skip_0 or template_skip_255, unless we have a %ngb 1620 if ($$tmpl !~ /\%-?n-?g-?b\%/) { 1621 if ( ($ip =~ /\.0$/ && $self->{template_skip_0}) || 1622 ($ip =~ /\.255$/ && $self->{template_skip_255}) ) { 1623 $$tmpl = ''; 1624 return; 1625 } 1626 } 1609 1627 1610 1628 my @ipparts = split /\./, $ip; … … 1615 1633 push @ippad, sprintf("%0.3u", $_); 1616 1634 } 1635 1636 # Two or three consecutive separator characters (_ or -) should be rare - users that use them 1637 # anywhere other than punycoded internationalized domains get to keep the pieces when it breaks. 1638 # We clean up the ones that we may inadvertently generate after replacing %c and %ngb% 1639 my ($thrsep) = ($$tmpl =~ /[_-]{3}/); 1640 my ($twosep) = ($$tmpl =~ /[_-]{2}/); 1641 1642 # Take the simplest path to pattern substitution; replace only exactly the %c or %ngb% 1643 # patterns as-is. Then check after to see if we've caused doubled separator characters (- or _) 1644 # and eliminate them, but only if the original template didn't have them already. Also 1645 # unconditionally drop separator characters immediately before a dot; these do not always 1646 # strictly make the label invalid but almost always, and any exceptions should never show up 1647 # in a template record that expands to "many" real records anyway. 1648 1649 # %ngb and %c require a netblock 1650 if ($subnet) { 1651 # extract the fragments 1652 my ($ngb,$n,$g,$b) = ($$tmpl =~ /(\%(-?n)(-?g)(-?b)\%)/); 1653 my ($c) = ($$tmpl =~ /(\%-?c)/); my $nld = ''; my $cld = ''; 1654 $c = '' if !$c; 1655 my $skipgw = ($c =~ /\%-c/ ? 0 : 1); 1656 my $ipkill = 0; 1657 1658 ##fixme: still have one edge case not handled well: 1659 # %c%n-gb% 1660 # do we drop the record as per -g, or publish the record with an index of 1 as per %c? 1661 # arguably this is a "that's a STUPID question!" case 1662 1663 if ($c) { 1664 # "n'th usable IP in the block" pattern. We need the caller to provide an index 1665 # number otherwise we see exponential time growth because we have to iterate over 1666 # the whole block to map the IP back to an index. :/ 1667 # NetAddr::IP does not have a method for asking "what index is IP <foo> at?" 1668 1669 # no index, or index == 0, (AKA network address), or IP == broadcast, blank the index fragment 1670 if (!$ipindex || ($$subnet->broadcast->addr eq $ip)) { 1671 $$tmpl =~ s/$c//; 1672 } else { 1673 # if we have %c, AKA "skip the gateway", and we're on the nominal gateway IP, blank the index fragment 1674 if ($skipgw && $$subnet->first->addr eq $ip) { 1675 $$tmpl =~ s/$c//; 1676 } 1677 # else replace the index fragment with the passed index minus $skipgw, so that we can start the 1678 # resulting index at 1 on net+2 1679 else { 1680 $$tmpl =~ s/$c/($ipindex-$skipgw)/e; 1681 } 1682 } 1683 } # if ($c) 1684 1685 if ($ngb) { 1686 # individually check the network, standard gateway (net+1) IP, and broadcast IP 1687 # blank $$tmpl if n, g, or b was prefixed with - (this allows "hiding" net/gw/bcast entries) 1688 1689 if ($$subnet->network->addr eq $ip) { 1690 if ($n eq '-n') { 1691 $$tmpl = ''; 1692 } else { 1693 $$tmpl =~ s/$ngb/net/; 1694 $ipkill = 1; 1695 } 1696 } elsif ($$subnet->first->addr eq $ip) { 1697 if ($g eq '-g') { 1698 $$tmpl = ''; 1699 } else { 1700 $$tmpl =~ s/$ngb/gw/; 1701 $ipkill = 1; 1702 } 1703 } elsif ($$subnet->broadcast->addr eq $ip) { 1704 if ($b eq '-b') { 1705 $$tmpl = ''; 1706 } else { 1707 $$tmpl =~ s/$ngb/bcast/; 1708 $ipkill = 1; 1709 } 1710 } else { 1711 $$tmpl =~ s/$ngb//; 1712 } 1713 } 1714 1715 # We don't (usually) want to expand the IP-related patterns on the -net, -gw, or -bcast IPs. 1716 # Arguably this is another place for another config knob, or possibly further extension of 1717 # the template pattern to control it on a per-subnet basis. 1718 if ($ipkill) { 1719 # kill common IP patterns 1720 $$tmpl =~ s/\%[_.-]?[irdh]//; 1721 # kill IP octet patterns 1722 $$tmpl =~ s/\%[1234][dh0](?:[_.-]\%[1234][dh0]){0,3}//; 1723 } 1724 1725 # and now clean up to make sure we leave a valid DNS label... mostly. Should arguably 1726 # split on /\./ and process each label separately. 1727 $$tmpl =~ s/([_-]){3}/$1/ if !$thrsep; 1728 $$tmpl =~ s/([_-]){2}/$1/ if !$twosep; 1729 $$tmpl =~ s/[_-]\././; 1730 1731 } # if ($subnet) 1617 1732 1618 1733 # IP substitutions in template records: … … 1650 1765 $$tmpl =~ s/\%([1234])h/$iphex[$1-1]/g; 1651 1766 $$tmpl =~ s/\%([1234])0/$ippad[$1-1]/g; 1767 1652 1768 } # _template4_expand() 1653 1769 … … 1661 1777 my $tmphost = $hname; 1662 1778 # we don't actually need to test with the real IP passed; that saves a bit of fiddling. 1663 _template4_expand(\$tmphost, '10.10.10.10');1779 DNSDB::_template4_expand(\$tmphost, '10.10.10.10'); 1664 1780 if ($tmphost =~ /\%/ || lc($tmphost) !~ /^(?:\*\.)?(?:[0-9a-z_.-]+)$/) { 1665 1781 $errstr = "Invalid template $hname"; … … 5965 6081 ## forked process 5966 6082 sub __publish_subnet { 5967 my $ obj= shift; # *sigh* need to pass in the DNSDB object so we can read a couple of options6083 my $self = shift; # *sigh* need to pass in the DNSDB object so we can read a couple of options 5968 6084 my $sub = shift; 5969 6085 my $recflags = shift; … … 5980 6096 5981 6097 my $iplist = $sub->splitref(32); 6098 my $ipindex = -1; 5982 6099 foreach (@$iplist) { 5983 6100 my $ip = $_->addr; 6101 $ipindex++; 5984 6102 # make as if we split the non-octet-aligned block into octet-aligned blocks as with SOA 5985 6103 my $lastoct = (split /\./, $ip)[3]; 5986 next if $ip =~ /\.0$/ && $obj->{template_skip_0};5987 next if $ip =~ /\.255$/ && $obj->{template_skip_255};5988 6104 next if $$recflags{$ip}; # && $self->{skip_bcast_255} 5989 6105 $$recflags{$ip}++; … … 5991 6107 my $rec = $hpat; # start fresh with the template for each IP 5992 6108 ##fixme: there really isn't a good way to handle sub-/24 zones here. This way at least 5993 # seems less bad than some alternatives. 5994 _template4_expand(\$rec, $ip); 6109 # seems less bad than some alternatives. 6110 $self->_template4_expand(\$rec, $ip, \$sub, $ipindex); 6111 # _template4_expand may blank $rec; if so, don't publish a record 6112 next if !$rec; 5995 6113 if ($ptronly || $zone->masklen > 24) { 5996 6114 print $fh "^$lastoct.$arpabase:$rec:$ttl:$stamp:$loc\n" or die $!;
Note:
See TracChangeset
for help on using the changeset viewer.