diff -r 0e79917de9f7 -r b814f87ed40d bin/pvl.hosts-dns --- a/bin/pvl.hosts-dns Thu Dec 19 01:20:33 2013 +0200 +++ b/bin/pvl.hosts-dns Thu Dec 19 01:46:59 2013 +0200 @@ -93,6 +93,64 @@ # preserve ordering yield rr +def split_ipv6_parts (prefix) : + for hextet in prefix.rstrip(':').split(':') : + for nibble in hextet.rjust(4, '0') : + yield nibble + +def build_ipv6_parts (parts) : + for i in xrange(0, len(parts), 4) : + yield ''.join(parts[i:i+4]) + + # suffix :: + if len(parts) < 32 : + yield '' + yield '' + +def parse_prefix (prefix) : + """ + Return an ipaddr.IPNetwork from given IPv4/IPv6 prefix. + + >>> parse_prefix('127.0.0.0/8') + IPv4Network('127.0.0.0/8') + >>> parse_prefix('127.') + IPv4Network('127.0.0.0/8') + >>> parse_prefix('10') + IPv4Network('10.0.0.0/8') + >>> parse_prefix('192.168') + IPv4Network('192.168.0.0/16') + >>> parse_prefix('fe80:') + IPv6Network('fe80::/16') + >>> parse_prefix('2001:db8::') + IPv6Network('2001:db8::/32') + >>> parse_prefix('2001:db8:1:2') + IPv6Network('2001:db8:1:2::/64') + """ + + if '/' in prefix : + return ipaddr.IPNetwork(prefix) + + elif '.' in prefix or prefix.isdigit() : + parts = prefix.rstrip('.').split('.') + prefixlen = len(parts) * 8 + + return ipaddr.IPv4Network('{prefix}/{prefixlen}'.format( + prefix = '.'.join(parts + ['0' for i in xrange(4 - len(parts))]), + prefixlen = prefixlen, + )) + + elif ':' in prefix : + parts = list(split_ipv6_parts(prefix)) + prefixlen = len(parts) * 4 + + return ipaddr.IPv6Network('{prefix}/{prefixlen}'.format( + prefix = ':'.join(build_ipv6_parts(parts)), + prefixlen = prefixlen, + )) + + else : + raise ValueError("Unrecognized IP prefix string: %s" % (prefix, )) + def process_hosts_ips (options, hosts, prefix) : """ Yield (ip, fqnd) for hosts within given prefix. @@ -174,7 +232,7 @@ help="Generate forward zone for domain") parser.add_option('--reverse-zone', metavar='PREFIX', - help="Generate reverse zone for prefx") + help="Generate reverse zone for prefix") parser.add_option('--unknown-host', metavar='NAME', help="Generate records for unused IPs") @@ -193,7 +251,7 @@ if options.reverse_zone : apply_zone(options, - process_hosts_reverse(options, hosts, ipaddr.IPNetwork(options.reverse_zone)), + process_hosts_reverse(options, hosts, parse_prefix(options.reverse_zone)), ) if __name__ == '__main__':