From d8b9de5fccd3809f334b101f8d9db209f9211f12 Mon Sep 17 00:00:00 2001 From: Babak Farrokhi Date: Tue, 14 Jun 2016 16:58:13 +0430 Subject: [PATCH] This should not exist in this branch to make merging easier --- dnsdiag.py | 238 ----------------------------------------------------- 1 file changed, 238 deletions(-) delete mode 100755 dnsdiag.py diff --git a/dnsdiag.py b/dnsdiag.py deleted file mode 100755 index 354f7d2..0000000 --- a/dnsdiag.py +++ /dev/null @@ -1,238 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2016, Babak Farrokhi -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# -# * Redistributions of source code must retain the above copyright notice, this -# list of conditions and the following disclaimer. -# -# * Redistributions in binary form must reproduce the above copyright notice, -# this list of conditions and the following disclaimer in the documentation -# and/or other materials provided with the distribution. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -import getopt -import ipaddress -import os -import signal -import socket -import sys - -import dns.flags -import dns.rdatatype -import dns.resolver - -__VERSION__ = 1.1 -__PROGNAME__ = os.path.basename(sys.argv[0]) -shutdown = False - - -def usage(): - print("""%s version %1.1f -usage: %s [-h] [-q] [-v] [-s server] [-p port] [-P port] [-S address] [-c count] [-t type] [-w wait] hostname - -h --help Show this help - -q --quiet Quiet - -v --verbose Print actual dns response - -s --server DNS server to use (default: first entry from /etc/resolv.conf) - -p --port DNS server port number (default: 53) - -T --tcp Use TCP instead of UDP - -4 --ipv4 Use IPv4 as default network protocol - -6 --ipv6 Use IPv6 as default network protocol -""" % (__PROGNAME__, __VERSION__, __PROGNAME__)) - sys.exit(0) - - -class myResolver(dns.resolver.Resolver): - def __init__(self, nameservers=None, port=53, af=socket.AF_INET, use_tcp=False): - super(myResolver, self).__init__() - self.use_tcp = use_tcp - self.port = port - self.default_af = af - self.port = port - self.retry_servfail = 0 - resolved_nameservers = [] - for n in nameservers: - try: - ipaddress.ip_address(n) - except ValueError: # so it is not a valid IPv4 or IPv6 address, so try to resolve host name - try: - r = socket.getaddrinfo(n, port=None, family=self.default_af)[1][4][0] - except OSError: - print('Error: cannot resolve hostname:', n) - # sys.exit(1) - return # todo: to be handled gracefully - else: - resolved_nameservers.append(r) - - else: - resolved_nameservers.append(n) - - self.nameservers = resolved_nameservers - - def lookupA(self, hostname): - try: - answers = self.query(hostname, 'A', tcp=self.use_tcp, af=self.default_af, - raise_on_no_answer=False) - except Exception as e: - print(e) - pass - - else: - a = [] - for t in answers: - a.append(t.address) - return a - - return [] - - def lookupAAAA(self, hostname): - try: - answers = self.query(hostname, 'AAAA', tcp=self.use_tcp, af=self.default_af, - raise_on_no_answer=False) - except: - pass - - else: - a = [] - try: - for t in answers: - a.append(t.address) - return a - except: - return [] - - return [] - - def lookupNS(self, hostname): - try: - answers = self.query(hostname, 'NS', tcp=self.use_tcp, af=self.default_af, - raise_on_no_answer=False) - except: - pass - - else: - return answers - - -def signal_handler(sig, frame): - global shutdown - if shutdown: # pressed twice, so exit immediately - sys.exit(0) - shutdown = True # pressed once, exit gracefully - - -def printHeader(title): - print("\n>> %s" % title) - print('=' * 65) - - -def validHostname(hostname): - return True # placeholder - - -def main(): - try: - signal.signal(signal.SIGTSTP, signal.SIG_IGN) # ignore CTRL+Z - signal.signal(signal.SIGINT, signal_handler) # custom CTRL+C handler - except AttributeError: # OS Does not support some signals, probably windows - pass - - if len(sys.argv) == 1: - usage() - - # defaults - quiet = False - verbose = False - dnsserver = dns.resolver.get_default_resolver().nameservers[0] - dst_port = 53 - use_tcp = False - address_family = socket.AF_INET - default_parent = 'a.gtld-servers.net' - - try: - opts, args = getopt.getopt(sys.argv[1:], "qhs:vp:T46", - ["help", "server=", "quiet", "verbose", - "port=", "srcip=", "tcp", "ipv4", "ipv6"]) - except getopt.GetoptError as err: - # print help information and exit: - print(err) # will print something like "option -a not recognized" - usage() - - if args and len(args) == 1: - hostname = args[0] - else: - usage() - - for o, a in opts: - if o in ("-h", "--help"): - usage() - elif o in ("-v", "--verbose"): - verbose = True - quiet = False - elif o in ("-s", "--server"): - dnsserver = a - elif o in ("-p", "--port"): - dst_port = int(a) - elif o in ("-q", "--quiet"): - quiet = True - verbose = False - elif o in ("-T", "--tcp"): - use_tcp = True - elif o in ("-4", "--ipv4"): - address_family = socket.AF_INET - elif o in ("-6", "--ipv6"): - address_family = socket.AF_INET6 - else: - usage() - - # check if we have a valid hostname to evaluate - if not validHostname(hostname): - print("Invalid hostname:", hostname) - exit(1) - - # check if a valid DNS Server is provided - try: - ipaddress.ip_address(dnsserver) - except ValueError: # so it is not a valid IPv4 or IPv6 address, so try to resolve host name - try: - dnsserver = socket.getaddrinfo(dnsserver, port=None, family=address_family)[1][4][0] - except OSError: - print('Error: cannot resolve hostname:', dnsserver) - sys.exit(1) - - # Lookup from master parent - res = myResolver(nameservers=[default_parent], port=dst_port, af=address_family, use_tcp=use_tcp) - printHeader("Domain NS Records (from parent: %s)" % default_parent) - answers = res.lookupNS(hostname) - for a in answers: - A = res.lookupA(a.target) - AAAA = res.lookupAAAA(a.target) - print("%-25s\t%s\t%s" % (a.target, '\t'.join(A), '\t'.join(AAAA))) - - # Lookup from your DNS server - yourdns = str(a.target) - res = myResolver(nameservers=[yourdns], port=dst_port, af=address_family, use_tcp=use_tcp) - printHeader("Domain NS Records (from your DNS: %s)" % a.target) - answers = res.lookupNS(hostname) - for a in answers: - A = res.lookupA(a.target) - AAAA = res.lookupAAAA(a.target) - print("%-25s\t%s\t%s" % (a.target, '\t'.join(A), '\t'.join(AAAA))) - - -if __name__ == '__main__': - main()