%PDF- %PDF-
Direktori : /lib/python3/dist-packages/dnslib/ |
Current File : //lib/python3/dist-packages/dnslib/client.py |
# -*- coding: utf-8 -*- """ DNS Client - DiG-like CLI utility. Mostly useful for testing. Can optionally compare results from two nameservers (--diff) or compare results against DiG (--dig). Usage: python -m dnslib.client [options|--help] See --help for usage. """ from __future__ import print_function try: from subprocess import getoutput,getstatusoutput except ImportError: from commands import getoutput,getstatusoutput import binascii,code,pprint,sys from dnslib.dns import DNSRecord,DNSHeader,DNSQuestion,DNSError,QTYPE,EDNS0 from dnslib.digparser import DigParser if __name__ == '__main__': import argparse,sys,time p = argparse.ArgumentParser(description="DNS Client") p.add_argument("--server","-s",default="8.8.8.8", metavar="<address:port>", help="Server address:port (default:8.8.8.8:53) (port is optional)") p.add_argument("--query",action='store_true',default=False, help="Show query (default: False)") p.add_argument("--hex",action='store_true',default=False, help="Dump packet in hex (default: False)") p.add_argument("--tcp",action='store_true',default=False, help="Use TCP (default: UDP)") p.add_argument("--noretry",action='store_true',default=False, help="Don't retry query using TCP if truncated (default: false)") p.add_argument("--diff",default="", help="Compare response from alternate nameserver (format: address:port / default: false)") p.add_argument("--dig",action='store_true',default=False, help="Compare result with DiG - if ---diff also specified use alternative nameserver for DiG request (default: false)") p.add_argument("--short",action='store_true',default=False, help="Short output - rdata only (default: false)") p.add_argument("--dnssec",action='store_true',default=False, help="Set DNSSEC (DO/AD) flags in query (default: false)") p.add_argument("--debug",action='store_true',default=False, help="Drop into CLI after request (default: false)") p.add_argument("domain",metavar="<domain>", help="Query domain") p.add_argument("qtype",metavar="<type>",default="A",nargs="?", help="Query type (default: A)") args = p.parse_args() # Construct request try: q = DNSRecord(q=DNSQuestion(args.domain,getattr(QTYPE,args.qtype))) if args.dnssec: q.add_ar(EDNS0(flags="do",udp_len=4096)) q.header.ad = 1 address,_,port = args.server.partition(':') port = int(port or 53) if args.query: print(";; Sending%s:" % (" (TCP)" if args.tcp else "")) if args.hex: print(";; QUERY:",binascii.hexlify(q.pack()).decode()) print(q) print() a_pkt = q.send(address,port,tcp=args.tcp) a = DNSRecord.parse(a_pkt) if q.header.id != a.header.id: raise DNSError('Response transaction id does not match query transaction id') if a.header.tc and args.noretry == False: # Truncated - retry in TCP mode a_pkt = q.send(address,port,tcp=True) a = DNSRecord.parse(a_pkt) if args.dig or args.diff: if args.diff: address,_,port = args.diff.partition(':') port = int(port or 53) if args.dig: if getstatusoutput("dig -v")[0] != 0: p.error("DiG not found") if args.dnssec: dig = getoutput("dig +qr +dnssec -p %d %s %s @%s" % ( port, args.domain, args.qtype, address)) else: dig = getoutput("dig +qr +noedns +noadflag -p %d %s %s @%s" % ( port, args.domain, args.qtype, address)) dig_reply = list(iter(DigParser(dig))) # DiG might have retried in TCP mode so get last q/a q_diff = dig_reply[-2] a_diff = dig_reply[-1] else: q_diff = DNSRecord(header=DNSHeader(id=q.header.id), q=DNSQuestion(args.domain, getattr(QTYPE,args.qtype))) q_diff = q diff = q_diff.send(address,port,tcp=args.tcp) a_diff = DNSRecord.parse(diff) if a_diff.header.tc and args.noretry == False: diff = q_diff.send(address,port,tcp=True) a_diff = DNSRecord.parse(diff) if args.short: print(a.short()) else: print(";; Got answer:") if args.hex: print(";; RESPONSE:",binascii.hexlify(a_pkt).decode()) if args.diff and not args.dig: print(";; DIFF :",binascii.hexlify(diff).decode()) print(a) print() if args.dig or args.diff: if q != q_diff: print(";;; ERROR: Diff Question differs") for (d1,d2) in q.diff(q_diff): if d1: print(";; - %s" % d1) if d2: print(";; + %s" % d2) if a != a_diff: print(";;; ERROR: Diff Response differs") for (d1,d2) in a.diff(a_diff): if d1: print(";; - %s" % d1) if d2: print(";; + %s" % d2) if args.debug: code.interact(local=locals()) except DNSError as e: p.error(e)