#! /usr/bin/env python3 # vim:set noet sw=8 ts=8 sts=8: import sys, socket import dns.query import dns.zone import dns.rdatatype def resolve(hostname): try: addrs = socket.getaddrinfo( hostname, 53, proto=socket.IPPROTO_UDP) return list(dict.fromkeys([addr[4][0] for addr in addrs])) except Exception as e: raise (Exception(f"resolving {hostname}: {e}")) def axfr(zone, hostname): addrs = resolve(hostname) last_exc = None for addr in addrs: try: return dns.zone.from_xfr(dns.query.xfr(addr, zone)) except Exception as e: last_exc = e raise (last_exc) def print_catalog(zone): nodes = [node for (name, node) in zone.nodes.items() if len(name) == 2 and name[1] == b"zones"] ptrs = [str(ptr.target).rstrip('.') for node in nodes for rdataset in node.rdatasets if rdataset.rdtype == dns.rdatatype.PTR for ptr in rdataset] print("\n".join(ptrs)) def main(): if len(sys.argv) != 3: print(f"Usage: {sys.argv[0]} ", file=sys.stderr) return 1 zone_name = sys.argv[1] server = sys.argv[2] try: zone = axfr(zone_name, server) print_catalog(zone) except Exception as e: print(f"Failed to load catalog: {e}", file=sys.stderr) return 1 return 0 if __name__ == "__main__": sys.exit(main())