# HG changeset patch # User Tero Marttila # Date 1368133525 -10800 # Node ID b58236f9ea7b767eb950a9ee494f2c7d032fc2dc # Parent 87c5570a205f547ec0e89b6f7b2046724b6b8471 process-zone: support AAAA/ip6.arpa for --reverse-zone, as well as implicit record names diff -r 87c5570a205f -r b58236f9ea7b bin/process-zone --- a/bin/process-zone Thu May 09 23:39:02 2013 +0300 +++ b/bin/process-zone Fri May 10 00:05:25 2013 +0300 @@ -11,6 +11,8 @@ from datetime import datetime import logging +import ipaddr + log = logging.getLogger('main') # command-line options, global state @@ -83,7 +85,7 @@ help="Domain to use for hosts in reverse zone") parser.add_option('--reverse-zone', metavar='NET', - help="Generate forward zone for given subnet (x.z.y)") + help="Generate forward zone for given subnet (x.z.y | a:b:c:d)") # parser.add_option('--doctest', action='store_true', @@ -244,7 +246,7 @@ # skip return - # indented lines don't have name + # XXX: indented lines keep name from previous record if line.indent : name = None @@ -645,11 +647,11 @@ if timestamp : yield TXTRecord(r.name, timestamp.strftime(TIMESTAMP_FORMAT), ttl=r.ttl) -def reverse_addr (ip) : +def reverse_ipv4 (ip) : """ - Return in-addr.arpa reverse for given IPv4 IP. + Return in-addr.arpa reverse for given IPv4 prefix. """ - + # parse octets = tuple(int(part) for part in ip.split('.')) @@ -658,6 +660,17 @@ return '.'.join([str(octet) for octet in reversed(octets)] + ['in-addr', 'arpa']) +def reverse_ipv6 (ip6) : + """ + Return ip6.arpa reverse for given IPv6 prefix. + """ + + parts = [int(part, 16) for part in ip6.split(':')] + parts = ['{0:04x}'.format(part) for part in parts] + parts = ''.join(parts) + + return '.'.join(tuple(reversed(parts)) + ( 'ip6', 'arpa')) + def fqdn (*parts) : fqdn = '.'.join(parts) @@ -672,28 +685,37 @@ Process zone data -> reverse zone data. """ + name = None + for r in zone : - if r.type != 'A' : + # keep name from previous.. + if r.name : + name = r.name + + if r.type == 'A' : + ip, = r.data + ptr = reverse_ipv4(ip) + + elif r.type == 'AAAA' : + ip, = r.data + ptr = reverse_ipv6(ip) + + else : continue - ip, = r.data - - # generate reverse-addr - reverse = reverse_addr(ip) - # verify - if zone and reverse.endswith(origin) : - reverse = reverse[:-(len(origin) + 1)] + if zone and ptr.endswith(origin) : + ptr = ptr[:-(len(origin) + 1)] else : - log.warning("Reverse does not match zone origin, skipping: (%s) -> %s <-> %s", ip, reverse, origin) + log.warning("Reverse does not match zone origin, skipping: (%s) -> %s <-> %s", ip, ptr, origin) continue # domain to use host_domain = r.origin or domain - host_fqdn = fqdn(r.name, host_domain) + host_fqdn = fqdn(name, host_domain) - yield ZoneRecord(reverse, 'PTR', [host_fqdn]) + yield ZoneRecord(ptr, 'PTR', [host_fqdn]) def write_zone_records (file, zone) : for r in zone : @@ -777,7 +799,14 @@ zone = list(process_zone_meta(zone, ignore=set(options.meta_ignore))) elif options.reverse_zone : - origin = reverse_addr(options.reverse_zone) + if ':' in options.reverse_zone : + # IPv6 + origin = reverse_ipv6(options.reverse_zone) + + else : + # IPv4 + origin = reverse_ipv4(options.reverse_zone) + domain = options.reverse_domain if not domain : diff -r 87c5570a205f -r b58236f9ea7b bin/update --- a/bin/update Thu May 09 23:39:02 2013 +0300 +++ b/bin/update Fri May 10 00:05:25 2013 +0300 @@ -123,6 +123,7 @@ update_hosts $ZONES/hosts/10 $DATA/pvl.txt --reverse-zone 10 --reverse-domain pvl -q update_hosts $ZONES/hosts/10.0 $DATA/test.pvl.txt --reverse-zone 10.0 --reverse-domain test.pvl -q + update_hosts $ZONES/hosts/fdc4:4cef:395a $DATA/test.pvl.txt --reverse-zone fdc4:4cef:395a --reverse-domain test.pvl -q update_hosts $ZONES/hosts/192.168 $DATA/pvl.txt --reverse-zone 192.168 --reverse-domain pvl -q # XXX: unsupported --forward-zone with pvl.txt