diff options
| author | Lexi Winter <lexi@le-fay.org> | 2025-07-12 11:50:39 +0100 |
|---|---|---|
| committer | Lexi Winter <lexi@le-fay.org> | 2025-07-12 11:50:39 +0100 |
| commit | 801796549782295f49217badfbd7d4ac222cb37a (patch) | |
| tree | 4f50ff87fc33175ff562c560aa27dafcb0f312c3 /bin | |
| parent | 2a043adc93836284236ea073362fe6ca232e8474 (diff) | |
| download | dns-801796549782295f49217badfbd7d4ac222cb37a.tar.gz dns-801796549782295f49217badfbd7d4ac222cb37a.tar.bz2 | |
bin/get_catalog: use dnspython
Diffstat (limited to 'bin')
| -rwxr-xr-x | bin/get_catalog | 95 |
1 files changed, 54 insertions, 41 deletions
diff --git a/bin/get_catalog b/bin/get_catalog index d9e744b..772d5b4 100755 --- a/bin/get_catalog +++ b/bin/get_catalog @@ -1,41 +1,54 @@ -#! /bin/sh -# -# Fetch the catalog zone '$1' from the server '$2' and print a list of zones. - -set -e - -catalog="$1" -server="$2" - -tempfile="$(mktemp -t catalog)" -trap 'rm $tempfile' 0 - -if ! dig "$catalog" axfr @"$server" +noall +answer >"$tempfile"; then - printf >&2 '%s: query failed\n' "$0" - exit 1 -fi - -# Make sure the result has an SOA, otherwise the query failed. -if ! awk <"$tempfile" " -BEGIN { - exitcode=1 -} - -\$1 == \"$catalog.\" && \$4 == \"SOA\" { - exitcode=0 -} - -END { - exit exitcode -} -"; then - printf >&2 '%s: no SOA found in zone; transfer failed?\n' "$0" - exit 1 -fi - -awk <"$tempfile" " -\$1 ~ /zones.$catalog/ && \$4 == \"PTR\" { - zone = \$5 - sub(/\\.$/, \"\", zone) - print zone -}" +#! /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 (Exception(str(last_exc))) + +def print_catalog(zone): + for name, node in zone.nodes.items(): + for rdata in node.rdatasets: + if rdata.rdtype == dns.rdatatype.PTR: + for ptr in rdata: + print(str(ptr.target).rstrip('.')) + + +def main(): + if len(sys.argv) != 3: + print(f"Usage: {sys.argv[0]} <zone> <server>") + 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"Zone transfer failed: {e}") + return 1 + + return 0 + +if __name__ == "__main__": + sys.exit(main()) |
