Changeset 685


Ignore:
Timestamp:
07/27/15 17:32:49 (9 years ago)
Author:
Kris Deugau
Message:

/trunk

Add some new template pattern options to autogenerate -net/-gw/-bcast
tags, and "n'th usable IP in range". Update online reference
reverse-patterns.html with the new patterns.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/DNSDB.pm

    r679 r685  
    16031603# really have a sane way to handle this type of expansion at the moment
    16041604# 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.
    16061609sub _template4_expand {
     1610  # ugh pthui
     1611  my $self;
     1612  $self = shift if ref($_[0]) eq 'DNSDB';
     1613
    16071614  my $tmpl = shift;
    16081615  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  }
    16091627
    16101628  my @ipparts = split /\./, $ip;
     
    16151633    push @ippad, sprintf("%0.3u", $_);
    16161634  }
     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)
    16171732
    16181733  # IP substitutions in template records:
     
    16501765  $$tmpl =~ s/\%([1234])h/$iphex[$1-1]/g;
    16511766  $$tmpl =~ s/\%([1234])0/$ippad[$1-1]/g;
     1767
    16521768} # _template4_expand()
    16531769
     
    16611777    my $tmphost = $hname;
    16621778    # 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');
    16641780    if ($tmphost =~ /\%/ || lc($tmphost) !~ /^(?:\*\.)?(?:[0-9a-z_.-]+)$/) {
    16651781      $errstr = "Invalid template $hname";
     
    59656081##  forked process
    59666082  sub __publish_subnet {
    5967     my $obj = shift;    # *sigh*  need to pass in the DNSDB object so we can read a couple of options
     6083    my $self = shift;   # *sigh*  need to pass in the DNSDB object so we can read a couple of options
    59686084    my $sub = shift;
    59696085    my $recflags = shift;
     
    59806096
    59816097    my $iplist = $sub->splitref(32);
     6098    my $ipindex = -1;
    59826099    foreach (@$iplist) {
    59836100      my $ip = $_->addr;
     6101      $ipindex++;
    59846102      # make as if we split the non-octet-aligned block into octet-aligned blocks as with SOA
    59856103      my $lastoct = (split /\./, $ip)[3];
    5986       next if $ip =~ /\.0$/ && $obj->{template_skip_0};
    5987       next if $ip =~ /\.255$/ && $obj->{template_skip_255};
    59886104      next if $$recflags{$ip}; # && $self->{skip_bcast_255}
    59896105      $$recflags{$ip}++;
     
    59916107      my $rec = $hpat;  # start fresh with the template for each IP
    59926108##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;
    59956113      if ($ptronly || $zone->masklen > 24) {
    59966114        print $fh "^$lastoct.$arpabase:$rec:$ttl:$stamp:$loc\n" or die $!;
  • trunk/reverse-patterns.html

    r534 r685  
    1212    <div id="main">
    1313      <h2>Reverse DNS Template Reference</h2>
    14       <table class="container" cellpadding="2" cellspacing="2">
     14      <table class="container" cellpadding="2" cellspacing="2" style="max-width:850px;">
    1515        <tbody>
    1616          <tr class="tableheader">
     
    4242            <td>323241453</td>
    4343          </tr>
     44          <tr class="row0">
     45            <td colspan="3">
     46              %i and %r also allow explicitly defining the separator; eg %.i or %_r.  Dot/period (.), dash (-),
     47              and underscore (_) are the only characters supported since DNS names may not contain most
     48              other non-alphanumerics.
     49            </td>
     50          </tr>
     51          <tr class="row0">
     52            <td colspan="3">
     53              %blank% may be used to specifically prevent template expansion on a segment of a block if
     54              desired;  eg, if 192.168.23.0/24 has "unused-%i.example.com" set, adding an A+PTR template
     55              for 192.168.23.48/30 of "%blank%" will leave 192.168.23.48 through .51 without PTR records
     56              unless specific entries exist for those IPs.
     57            </td>
     58          </tr>
    4459          <tr class="tableheader">
    4560            <td colspan="3">Per-octet patterns (1, 2, 3, or 4 specify
     
    6782            <td>c0-168-023-2d</td>
    6883          </tr>
     84
     85          <tr class="row0"><td colspan="3">&nbsp;</td></tr>
     86
     87          <tr class="tableheader">
     88            <td colspan="3">Extensions</td>
     89          </tr>
     90          <tr class="tableheader">
     91            <td></td>
     92            <td>Substitution pattern</td>
     93            <td>Example expansion using 192.168.23.40/29</td>
     94          </tr>
     95          <tr class="row0">
     96            <td>Network/<br />gateway/<br />broadcast</td>
     97            <td>%ngb%</td>
     98            <td>
     99              customer-%i%ngb%.example.com<br />
     100              192.168.23.40 -> customer-net.example.com<br />
     101              192.168.23.41 -> customer-gw.example.com<br />
     102              192.168.23.42 -> customer-192-168-23-42.example.com<br />
     103              192.168.23.43 -> customer-192-168-23-43.example.com<br />
     104              192.168.23.44 -> customer-192-168-23-44.example.com<br />
     105              192.168.23.45 -> customer-192-168-23-45.example.com<br />
     106              192.168.23.46 -> customer-192-168-23-46.example.com<br />
     107              192.168.23.47 -> customer-bcast.example.com
     108            </td>
     109          </tr>
     110          <tr class="row1">
     111            <td colspan="3">
     112              Any IP pattern component is blanked on the network, gateway, and broadcast IPs when this is
     113              used.<br />
     114              Each of n, g, or b can be prefixed with a dash, eg %-ng-b% or %n-g-b%, which will
     115              blank that entire entry instead of substituting <tt>net</tt>, <tt>gw</tt>, or <tt>bcast</tt>.
     116            </td>
     117          </tr>
     118          <tr class="row0">
     119            <td>n'th usable IP</td>
     120            <td>%c</td>
     121            <td>
     122              customer-%3d-%c.example.com<br />
     123              192.168.23.40 -> customer-23.example.com<br />
     124              192.168.23.41 -> customer-23.example.com<br />
     125              192.168.23.42 -> customer-23-1.example.com<br />
     126              192.168.23.43 -> customer-23-2.example.com<br />
     127              192.168.23.44 -> customer-23-3.example.com<br />
     128              192.168.23.45 -> customer-23-4.example.com<br />
     129              192.168.23.46 -> customer-23-5.example.com<br />
     130              192.168.23.47 -> customer-23.example.com
     131            </td>
     132          </tr>
     133          <tr class="row1">
     134            <td colspan="3">
     135              c can be prefixed with a dash (%-c), which starts the numbering from the conventional gateway IP
     136              instead.  (.41 above would be 1, .42 2, etc, finishing with 6 at .46).
     137            </td>
     138          </tr>
    69139        </tbody>
    70140      </table>
    71       <p> %i and %r also allow explicitly defining the separator; eg %.i
    72         or %_r. '.', '-', and '_' are the only characters<br />
    73         supported since DNS names may not contain most other
    74         non-alphanumerics.</p>
    75       <p>%blank% may be used to specifically prevent template expansion on
    76         a segment of a block if desired;  eg, if<br />
    77         192.168.23.0/24 has "unused-%i.example.com" set, adding an A+PTR
    78         template for 192.168.23.48/30 of<br />
    79         "%blank%" will leave 192.168.23.48 through .51 without PTR records
    80         unless specific entries exist for those IPs.<p>
     141
    81142    </div>
    82143  </body>
Note: See TracChangeset for help on using the changeset viewer.