%PDF- %PDF-
Direktori : /lib/python3/dist-packages/dnslib/ |
Current File : //lib/python3/dist-packages/dnslib/zoneresolver.py |
# -*- coding: utf-8 -*- from __future__ import print_function import copy from dnslib import RR,QTYPE,RCODE from dnslib.server import DNSServer,DNSHandler,BaseResolver,DNSLogger class ZoneResolver(BaseResolver): """ Simple fixed zone file resolver. """ def __init__(self,zone,glob=False): """ Initialise resolver from zone file. Stores RRs as a list of (label,type,rr) tuples If 'glob' is True use glob match against zone file """ self.zone = [(rr.rname,QTYPE[rr.rtype],rr) for rr in RR.fromZone(zone)] self.glob = glob self.eq = 'matchGlob' if glob else '__eq__' def resolve(self,request,handler): """ Respond to DNS request - parameters are request packet & handler. Method is expected to return DNS response """ reply = request.reply() qname = request.q.qname qtype = QTYPE[request.q.qtype] for name,rtype,rr in self.zone: # Check if label & type match if getattr(qname,self.eq)(name) and (qtype == rtype or qtype == 'ANY' or rtype == 'CNAME'): # If we have a glob match fix reply label if self.glob: a = copy.copy(rr) a.rname = qname reply.add_answer(a) else: reply.add_answer(rr) # Check for A/AAAA records associated with reply and # add in additional section if rtype in ['CNAME','NS','MX','PTR']: for a_name,a_rtype,a_rr in self.zone: if a_name == rr.rdata.label and a_rtype in ['A','AAAA']: reply.add_ar(a_rr) if not reply.rr: reply.header.rcode = RCODE.NXDOMAIN return reply if __name__ == '__main__': import argparse,sys,time p = argparse.ArgumentParser(description="Zone DNS Resolver") p.add_argument("--zone","-z",required=True, metavar="<zone-file>", help="Zone file ('-' for stdin)") p.add_argument("--port","-p",type=int,default=53, metavar="<port>", help="Server port (default:53)") p.add_argument("--address","-a",default="", metavar="<address>", help="Listen address (default:all)") p.add_argument("--glob",action='store_true',default=False, help="Glob match against zone file (default: false)") p.add_argument("--udplen","-u",type=int,default=0, metavar="<udplen>", help="Max UDP packet length (default:0)") p.add_argument("--tcp",action='store_true',default=False, help="TCP server (default: UDP only)") p.add_argument("--log",default="request,reply,truncated,error", help="Log hooks to enable (default: +request,+reply,+truncated,+error,-recv,-send,-data)") p.add_argument("--log-prefix",action='store_true',default=False, help="Log prefix (timestamp/handler/resolver) (default: False)") args = p.parse_args() if args.zone == '-': args.zone = sys.stdin else: args.zone = open(args.zone) resolver = ZoneResolver(args.zone,args.glob) logger = DNSLogger(args.log,prefix=args.log_prefix) print("Starting Zone Resolver (%s:%d) [%s]" % ( args.address or "*", args.port, "UDP/TCP" if args.tcp else "UDP")) for rr in resolver.zone: print(" | ",rr[2].toZone(),sep="") print() if args.udplen: DNSHandler.udplen = args.udplen udp_server = DNSServer(resolver, port=args.port, address=args.address, logger=logger) udp_server.start_thread() if args.tcp: tcp_server = DNSServer(resolver, port=args.port, address=args.address, tcp=True, logger=logger) tcp_server.start_thread() while udp_server.isAlive(): time.sleep(1)