From d0a403a0e075482ea98532b65fc20ee94b0f21f3 Mon Sep 17 00:00:00 2001 From: Thomas Ward Date: Mon, 9 Mar 2020 16:14:55 -0400 Subject: [PATCH] Add a reverse_lookup function to Resolver. Utilize the inbuilt ipaddress library and in-built resolver query libraries to provide a reverse_lookup function. This could make it easier for users to set up their own Resolver instances which continue to behave as stub resolvers but also more easily make PTR record lookups, which would be able to be used as a direct result. This had been written by me as an extension of the Resolver class in my own private class (called DNSResolver, which I only use internally on a few private applications) which extended the init file to define the nameservers if not specified (default: google DNS) and then extended to add the reverse_lookup function call as well. Feel free to reject if it doesn't make sense, but it would be a nifty function to have (because `dig` for instance has a `-x` flag you can pass which accepts an IP address and will auto-reverse it to get the in-addr.arpa lookup result from nameservers, whether they're stub resolvers or not, which is a nifty function to have here.) --- dns/resolver.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/dns/resolver.py b/dns/resolver.py index 3f5e4518..ead0ed53 100644 --- a/dns/resolver.py +++ b/dns/resolver.py @@ -18,6 +18,7 @@ """DNS stub resolver.""" from urllib.parse import urlparse +import ipaddress import socket import sys import time @@ -1030,6 +1031,31 @@ class Resolver(object): self.cache.put((_qname, rdtype, rdclass), answer) return answer + def reverse_lookup(self, ipaddr): + """Use a resolver to run a Reverse IP Lookup for PTR records. + + This utilizes the in-built query function to perform a PTR lookup and + tests to make sure that the entered string is in fact an IP address. + + This utilizes the in-built ipaddress library for Python to validate that + the address is an IPv4 or IPv6 address, and errors if the specified + value is not a valid IPv4 or IPv6 address. It also uses the same library + to get the in-addr.arpa string to query to get the PTR record. + + *ipaddr*, a ``str``, the IP address you want to get the PTR record for. + """ + try: + ip = ipaddress.IPv4Address(ipaddr) + except ipaddress.AddressValueError: + try: + ip = ipaddress.IPv6Address(ipaddr) + except ipaddress.AddressValueError: + raise ipaddress.AddressValueError("The specified string does not " + "appear to be any known type of" + "IP Address.") + + return self.query(ip.reverse_pointer, dns.rdatatype.PTR) + def use_tsig(self, keyring, keyname=None, algorithm=dns.tsig.default_algorithm): """Add a TSIG signature to the query. -- 2.47.3