Index: trunk/DNSDB.pm
===================================================================
--- trunk/DNSDB.pm	(revision 303)
+++ trunk/DNSDB.pm	(revision 304)
@@ -846,5 +846,5 @@
 # Not quite a substitution sub, but placed here as it's basically the inverse of above;
 # given the .arpa zone name, return the CIDR netblock the zone is for.
-# Supports v4 non-octet/non-classful netblocks as per the method outlined in the Cricket Book (2nd Ed p217-218)
+# Supports v4 non-octet/non-classful netblocks as per the method outlined in the Grasshopper Book (2nd Ed p217-218)
 # Does NOT support non-quad v6 netblocks via the same scheme;  it shouldn't ever be necessary.
 # Takes a nominal .arpa zone name, returns a success code and NetAddr::IP, or a fail code and message
@@ -866,15 +866,30 @@
 
     # Map result of a range manipulation to a mask length change.  Cheaper than finding the 2-root of $octets[0]+1.
-    my %maskmap = (1 => 1, 3 => 2, 7 => 3, 15 => 4, 31 => 5, 63 => 6, 127 => 7);
+    # Note we will not support /31 blocks, mostly due to issues telling "24-31" -> .24/29 apart from
+    # "24-31" -> .24/31", with a litte bit of "/31 is icky".
+    my %maskmap = (  3 => 2,  7 => 3, 15 => 4, 31 => 5, 63 => 6, 127 => 7,
+		    30 => 2, 29 => 3, 28 => 4, 27 => 5, 26 => 6,  25 => 7
+	);
 
     # Handle "range" blocks, eg, 80-83.168.192.in-addr.arpa (192.168.80.0/22)
     # Need to take the size of the range to offset the basic octet-based mask length,
     # and make sure the first number in the range gets used as the network address for the block
+    # Alternate form:  The second number is actually the real netmask, not the end of the range.
     my $masklen = 0;
-    if ($octs[0] =~ /(\d+)-\d+/) {	# take the range...
-      $masklen -= $maskmap{-(eval $octs[0])};	# find the mask base...
+    if ($octs[0] =~ /(\d+)-(\d+)/) {	# take the range...
+      if (24 < $2 && $2 < 31) {
+	# we have a real netmask
+	$masklen = -$maskmap{$2};
+      } else {
+	# we have a range.  NB:  only real CIDR ranges are supported
+	$masklen -= $maskmap{-(eval $octs[0])};	# find the mask base...
+      }
       $octs[0] = $1;	# set the base octet of the range...
     }
     @octs = reverse @octs;	# We can reverse the octet pieces now that we've extracted and munged any ranges
+
+# arguably we should only allow sub-octet range/mask in-addr.arpa
+# specifications in the least significant octet, but the code is
+# simpler if we deal with sub-octet delegations at any level.
 
     # Now we find the "true" mask with the aid of the "base" calculated above
