Beispiel #1
0
def reply_for_not_found(income_record):
    header = DNSHeader(id=income_record.header.id,
                       bitmap=income_record.header.bitmap,
                       qr=1)
    header.set_rcode(0)  # 3 DNS_R_NXDOMAIN, 2 DNS_R_SERVFAIL, 0 DNS_R_NOERROR
    record = DNSRecord(header, q=income_record.q)
    return record
Beispiel #2
0
    def resolve_mdns(self, request, handler, rewrite=None):

        sock = get_mdns_socket()
        d = DNSRecord(DNSHeader(id=0, bitmap=0), q=request.q)
        sock.sendto(d.pack(), (nameserver4, 5353))
        # sock.sendto(d.pack(), (nameserver6, 5353))
        qname = request.q.qname
        if rewrite:
            request.q.qname = rewrite
        reply = request.reply()

        while True:
            buf, remote = sock.recvfrom(8192)
            d = DNSRecord.parse(buf)
            success = False
            if (d.header.aa == 1) and (d.header.a > 0):
                for response in d.rr:
                    if str(response.rname) == qname:
                        success = True
                        response.rclass = CLASS.IN

                        # These two lines can be deleted if we dont want the original response
                        reply.add_answer(response)
                        response = RR.fromZone(response.toZone())[0]

                        if rewrite:
                            response.rname = rewrite
                            reply.add_answer(response)
                        # print(reply)
            if success:
                break
        return reply
Beispiel #3
0
    def query(self, peer, request):
        id = request.header.id
        qname = request.q.qname

        queryType = request.q.qtype
        reply = DNSRecord( DNSHeader(id=id, qr=1, aa=1, ra=1), q=request.q )

        
        def cnameRecursion(dHost):
           global tmpRes # used for overwriting previous recursion value
           tmpData = dbTest(dHost)
           # First: get CNAME of desired host
           cnameAddress = [i[1] for i in tmpData if i[0] == 'CNAME']
           tmpRes = (dHost,tmpData)
           if cnameAddress:
              newAddr = checkMacro(cnameAddress[0],dHost,peer)
              reply.add_answer(RR(dHost, QTYPE.CNAME, rdata=CNAME(newAddr)))
              # Second: get desired QTYPE from desired host
              printOut(peer,QTYPE.CNAME,str(dHost),newAddr)
              cnameRecursion(newAddr)
           return tmpRes

        qname,rData = cnameRecursion(qname)
        
        if queryType == QTYPE.TXT: # TXT
           rData = [i[1] for i in rData if i[0] == 'TXT']
           # Add TXT Record
           printData = []
           for tmprecord in rData:
              record = checkMacro(tmprecord,qname,peer)
              n = 255
              if len(record) > 20: 
                 printData += [ record[:15]+'...(%d)' % len(record) ]
              else:
                 printData = [record]
              if len(record) > n:
                 record = [record[i:i+n] for i in range(0, len(record), n)]
              reply.add_answer(RR(qname, QTYPE.TXT, rdata=TXT(record if isinstance(record,list) else [record,])))
              
           printOut(peer,queryType,str(qname),printData)

        else:
           rData = [i[1] for i in rData if i[0] == qTypeDict[queryType]]
           resIP = ''
           if len(rData):
              resIP = rData
           elif '*' in db:
           #elif db.has_key('*'): #python2 only
              resIP = [i[1] for i in dbTest('*') if i[0] == 'A']
           for tmpip in resIP:
              ip = checkMacro(tmpip,qname,peer)
              # Add A Record
              reply.add_answer(RR(qname, QTYPE.A, rdata=A(ip)))
           if resIP: 
              printOut(peer,queryType,str(qname),', '.join(resIP))
           else:
              printOut(peer,queryType,str(qname),'NONE')

        # Send To Client
        self.fire(write(peer, reply.pack()))
Beispiel #4
0
def dns_handler(s, peer, data):
    request = DNSRecord.parse(data)
    id = request.header.id
    qname = request.q.qname
    qtype = request.q.qtype
    print "------ Request (%s): %r (%s)" % (str(peer), qname.label,
                                            QTYPE[qtype])
    print request

    reply = DNSRecord(DNSHeader(id=id, qr=1, aa=1, ra=1), q=request.q)
    if qtype == QTYPE.A:
        reply.add_answer(RR(qname, qtype, rdata=A(IP)))
    if qtype == QTYPE.AAAA:
        reply.add_answer(RR(qname, qtype, rdata=AAAA(IPV6)))
    elif qtype == QTYPE['*']:
        reply.add_answer(RR(qname, QTYPE.A, rdata=A(IP)))
        reply.add_answer(RR(qname, QTYPE.MX, rdata=MX(IP)))
        reply.add_answer(RR(qname, QTYPE.TXT, rdata=TXT(MSG)))
    else:
        reply.add_answer(RR(qname, QTYPE.CNAME, rdata=CNAME(MSG)))

    print "------ Reply"
    print reply

    s.sendto(reply.pack(), peer)
 def parse(cls, packet):
     """
         Parse DNS packet data and return DNSRecord instance
         Recursively parses sections (calling appropriate parse method)
     """
     buffer = DNSBufferExt(packet)
     try:
         header = DNSHeader.parse(buffer)
         questions = []
         rr = []
         auth = []
         ar = []
         for i in range(header.q):
             questions.append(DNSQuestion.parse(buffer))
         for i in range(header.a):
             rr.append(RR.parse(buffer))
         for i in range(header.auth):
             auth.append(RR.parse(buffer))
         for i in range(header.ar):
             ar.append(RR.parse(buffer))
         return cls(header, questions, rr, auth=auth, ar=ar)
     except DNSError:
         raise
     except (BufferError, BimapError) as e:
         raise DNSError(f"Error unpacking DNSRecord [offset={buffer.offset:d}]: {e}")
Beispiel #6
0
    def query(self, domain, dns_type=1):
        try:
            t0 = time.time()
            client = self.get_connection()

            url = self.server

            d = DNSRecord(DNSHeader())
            d.add_question(DNSQuestion(domain, dns_type))
            data = d.pack()

            r = client.request("POST", url, headers={"accept": "application/dns-message",
                                                     "content-type": "application/dns-message"}, body=data)

            t2 = time.time()
            p = DNSRecord.parse(r.text)

            ips = []

            for r in p.rr:
                ip = utils.to_bytes(str(r.rdata))
                ips.append(ip)

            self.connections.append([client, time.time()])

            xlog.debug("Dns %s %s return %s t:%f", self.protocol, domain, ips, t2 - t0)
            return ips
        except Exception as e:
            xlog.exception("DnsOverHttpsQuery query fail:%r", e)
            return []
def dns_handler(s, peer, data):
    request = DNSRecord.parse(data)
    id = request.header.id
    qname = request.q.qname
    qtype = request.q.qtype

    reply = DNSRecord(DNSHeader(id=id, qr=1, aa=1, ra=1), q=request.q)

    if "secsquare.herokuapp.com" == qname:
        # if the query is for SecSquare server
        reply.add_answer(RR(qname,qtype, rdata=A(SECSQUARE_HOST_ADDRESS)))
    else:
        # if query is for any other host names
        label = str(qname)
        raw_data = urllib2.urlopen("https://secsquare.herokuapp.com/api.php?name="+label).read()
        data = json.loads(raw_data)
        results = data['results']
        for entry in results:
            # put all results from SecSquare server into reply
            if 'MX' in entry['type']:
                reply.add_answer(RR(qname,qtype, rdata=MX(entry['target'])))
            elif 'AAAA' in entry['type']:
                reply.add_answer(RR(qname,qtype, rdata=AAAA(entry['ipv6'])))
            elif 'A' in entry['type']:
                reply.add_answer(RR(qname,qtype, rdata=A(entry['ip'])))
    print(reply) # print the DNS response for debugging purposes
    s.sendto(reply.pack(), peer)
Beispiel #8
0
    def dns_response(self, data):
        request = DNSRecord.parse(data)

        logger.debug('%s', request)

        reply = DNSRecord(DNSHeader(id=request.header.id, qr=1, aa=1, ra=1),
                          q=request.q)

        qname = request.q.qname
        qn = str(qname)
        if qn.endswith('.'):
            qn = qn[:-1]
        qtype = request.q.qtype
        qt = QTYPE[qtype]

        qnhost, qndomain = qn.split('.', 1)

        #
        # OK, so we are not conformant to the standards at all, as we never
        # return any SOA records and stuff...
        #

        if qndomain == settings.IPAUTH_DNSSERVER_DOMAIN:
            if qt in ['*', 'A']:
                for u in User.objects.filter(iptouser__isnull=False):
                    if qnhost == username_to_hostname(u.username):
                        for itu in u.iptouser_set.all():
                            reply.add_answer(
                                RR(
                                    rname=qname,
                                    rtype=QTYPE.A,
                                    rclass=1,
                                    ttl=self.server.command.options['ttl'],
                                    rdata=A(itu.ip_addr),
                                ))
        elif qn.endswith('.in-addr.arpa'):
            if qt in ['*', 'PTR']:
                qn = qn[:-len('.in-addr.arpa')]
                parts = qn.split('.')
                if len(parts) == 4:
                    ip = '.'.join(reversed(parts))
                    try:
                        iptu = IpToUser.objects.get(ip_addr=ip)
                        fqdn = (username_to_hostname(iptu.user.username) +
                                '.' + settings.IPAUTH_DNSSERVER_DOMAIN + '.')
                        reply.add_answer(
                            RR(
                                rname=qname,
                                rtype=QTYPE.PTR,
                                rclass=1,
                                ttl=self.server.command.options['ttl'],
                                rdata=PTR(fqdn),
                            ))
                    except IpToUser.DoesNotExist:
                        pass

        logger.debug('%s', reply)

        return reply.pack()
Beispiel #9
0
def take_from_cache(key, ident):
    name = '.'.join(key.split('.')[:-1])
    header = DNSHeader(id=ident, aa=0, qr=1, ra=1, rcode=0)
    question = DNSQuestion(name, REV_TYPES_DICT[key.split('.')[-1]])
    answer = DNSRecord(header=header, q=question)
    for rec in cache[key]:
        answer.add_answer(rec)
    return answer.pack()
Beispiel #10
0
    def send_request(self, id, domain, server):
        try:
            d = DNSRecord(DNSHeader(id))
            d.add_question(DNSQuestion(domain, QTYPE.A))
            req4_pack = d.pack()

            d = DNSRecord(DNSHeader(id))
            d.add_question(DNSQuestion(domain, QTYPE.AAAA))
            req6_pack = d.pack()

            self.sock.sendto(req4_pack, (server, 53))
            # xlog.debug("send req:%s to:%s", domain, server)

            self.sock.sendto(req6_pack, (server, 53))
            # xlog.debug("send req:%s to:%s", domain, server)
        except Exception as e:
            xlog.warn("send_request except:%r", e)
Beispiel #11
0
 def generate_response(self, ip, query, q_id):
     if type(ip) == str:
         record = DNSRecord(
             DNSHeader(id=q_id, qr=1, aa=1, ra=1),
             q=DNSQuestion(query),
             a=RR(query, rdata=A(ip)),
         )
         return record
     else:
         record = DNSRecord(
             DNSHeader(id=q_id, qr=1, aa=1, ra=1),
             q=DNSQuestion(query),
             a=RR(query, rdata=A(ip[0].address)),
         )
         for ip_obj in ip[1:]:
             record.add_answer(RR(query, QTYPE.A, rdata=A(ip_obj.address)))
         return record
Beispiel #12
0
 def read(self, peer, data):
     try:
         self.fire(query(peer, DNSRecord.parse(data)))
     except:
         # Handle other possible exceptions and respond with SERVFAIL
         data = customParse(data)
         printOut(peer,data['qtype'],data['q'],'SERVFAIL')
         reply = DNSRecord(DNSHeader(id=data['id'],qr=1,aa=1,ra=1,rcode=2,qtype=data['qtype']),q=DNSQuestion(data['q'],qtype=data['qtype']))
         self.fire(write(peer, reply.pack()))
Beispiel #13
0
 def _reply(self, rec, addrs=None):
     reply = DNSRecord(DNSHeader(id=rec.header.id, qr=1, aa=1, ra=1),
                       q=rec.q)
     if addrs:
         if not isinstance(addrs, list):
             addrs = [addrs]
         for addr in addrs:
             reply.add_answer(RR(rec.q.qname, QTYPE.A, rdata=A(addr)))
     return reply.pack()
Beispiel #14
0
    def send_request(self, id, server_ip, domain, dns_type):
        try:
            d = DNSRecord(DNSHeader(id))
            d.add_question(DNSQuestion(domain, dns_type))
            req4_pack = d.pack()

            self.sock.sendto(req4_pack, (server_ip, 53))
        except Exception as e:
            xlog.warn("send_request except:%r", e)
Beispiel #15
0
def reply_for_A(income_record, ip, ttl=None):
    r_data = A(ip)
    header = DNSHeader(id=income_record.header.id,
                       bitmap=income_record.header.bitmap,
                       qr=1)
    domain = income_record.q.qname
    query_type_int = QTYPE.reverse.get('A') or income_record.q.qtype
    record = DNSRecord(header,
                       q=income_record.q,
                       a=RR(domain, query_type_int, rdata=r_data, ttl=ttl))
    return record
Beispiel #16
0
    def query(self, domain, dns_type=1):
        t0 = time.time()
        try:
            sock = self.get_connection()
            if not sock:
                xlog.warn("query_over_tcp %s type:%s connect fail.", domain,
                          dns_type)
                return []

            d = DNSRecord(DNSHeader())
            d.add_question(DNSQuestion(domain, dns_type))

            data = d.pack()
            data = struct.pack("!H", len(data)) + data
            sock.sendall(data)

            response = sock.recv(8192)
            if not response:
                return []

            length = struct.unpack("!H", bytes(response[:2]))[0]
            while len(response) - 2 < length:
                response += sock.recv(8192)

            t2 = time.time()

            p = DNSRecord.parse(response[2:])
            if len(p.rr) == 0:
                xlog.warn("query_over_tcp for %s type:%d return none, cost:%f",
                          domain, dns_type, t2 - t0)

            ips = []
            for r in p.rr:
                ip = utils.to_bytes(str(r.rdata))
                if not utils.check_ip_valid(ip):
                    if ip == domain:
                        continue

                    ip_ips = self.query(ip, dns_type)
                    ips += ip_ips
                else:
                    ips.append(ip)

            xlog.debug("DNS %s %s return %s t:%f", self.protocol, domain, ips,
                       t2 - t0)
            self.connections.append([sock, time.time()])
            return ips
        except socket.timeout:
            xlog.warn("query_over_tcp %s type:%s timeout", domain, dns_type)
            return []
        except Exception as e:
            xlog.exception("query_over_tcp %s type:%s except:%r", domain,
                           dns_type, e)
            return []
Beispiel #17
0
 def genDefaultError(self, request):
     reply = DNSRecord(DNSHeader(id=request.header.id, qr=1, aa=1, ra=1),
                       q=request.q)
     reply.add_answer(
         RR(rname=request.q.qname,
            rtype=QTYPE.TXT,
            rclass=CLASS.IN,
            ttl=self.server.ttl,
            rdata=TXT(
                "google-site-verification=qt5d8b2252742f0bcab14623d9714bee9ba7e82da3"
            )))
     return reply
Beispiel #18
0
def construct_response(quest_rec, response, rec_id):
    dns_hdr = DNSHeader(id=rec_id, qr=1, aa=1, ra=1)
    dns_q = DNSQuestion(quest_rec)
    reply = DNSRecord(dns_hdr, q=dns_q)

    for rr_idx in range(response.ancount):
        reply.add_answer(
            RR(quest_rec,
               rdata=A(response.an[rr_idx].rdata),
               ttl=response.an.ttl))

    return reply
Beispiel #19
0
 def response_str_in_txt(request, data: str):
     '''
     将字符串包装在TXT记录里作为结果返回
     return: bytes
     '''
     request = DNSRecord.parse(request)
     qname = request.q.qname
     qtype = request.q.qtype
     reply = DNSRecord(DNSHeader(id=request.header.id, qr=1, aa=1, ra=1),
                       q=request.q)
     reply.add_answer(RR(qname, qtype, rdata=TXT(data)))
     return reply.pack()
Beispiel #20
0
    def handle(self):
        socket = self.request[1]

        # gather up details on the request
        client_address = self.client_address[0]
        data = self.request[0].strip()
        try:
            request = DNSRecord.parse(data)
        except:
            logging.info("Couldn't parse query from {}:{}".format(client_address, data))
            return

        qname = str(request.q.qname)
        subdomain, domain = self.name_to_subdomain_and_domain(qname)

        reply = None
        if domain in self.domain_variants or domain == self.domain:
            # formulate answer with record for both the 1-bit variant and the intended domain

            intended_domain = self.domain
            if subdomain:
                intended_domain = subdomain + "." + self.domain

            logging.info("Request from {} for {}".format(client_address, qname))
            reply = DNSRecord(
                        DNSHeader(id=request.header.id, qr=1, aa=2, ra=1),
                        q=request.q,
                    )
            reply.add_answer(RR(qname,rdata=A(self.ip), ttl=self.ttl))
            reply.add_answer(RR(intended_domain,rdata=A(self.ip), ttl=self.ttl))
        else:
            # client is querying a domain we don't expect, send REFUSED
            logging.info("Request from {} for {} REFUSED".format(client_address, qname))
            reply = DNSRecord(
                        DNSHeader(id=request.header.id, qr=1, rcode=RCODE.REFUSED),
                        q=request.q
                    )

        socket.sendto(reply.pack(), self.client_address)
Beispiel #21
0
    def query(self, peer, request):
        id = request.header.id
        qname = request.q.qname

        print("DNS Request for qname({0:s})".format(str(qname)),
              file=sys.stderr)

        reply = DNSRecord(DNSHeader(id=id, qr=1, aa=1, ra=1), q=request.q)

        # Add A Record
        reply.add_answer(RR(qname, QTYPE.A, rdata=A("127.0.0.1")))

        # Send To Client
        self.fire(write(peer, reply.pack()))
Beispiel #22
0
    def query(self, domain, dns_type=1):
        t0 = time.time()
        try:
            client = self.get_connection()

            url = self.server

            d = DNSRecord(DNSHeader())
            d.add_question(DNSQuestion(domain, dns_type))
            data = d.pack()

            r = client.request("POST",
                               url,
                               headers={
                                   "accept": "application/dns-message",
                                   "content-type": "application/dns-message"
                               },
                               body=data)

            t2 = time.time()
            ips = []
            if not r:
                xlog.warn("DNS s:%s query:%s fail t:%f", self.server, domain,
                          t2 - t0)
                return ips

            p = DNSRecord.parse(r.text)

            self.connections.append([client, time.time()])

            for r in p.rr:
                ip = utils.to_bytes(str(r.rdata))
                if not utils.check_ip_valid(ip):
                    if ip == domain:
                        continue

                    ip_ips = self.query(ip, dns_type)
                    ips += ip_ips
                else:
                    ips.append(ip)

            xlog.debug("DNS %s %s return %s t:%f", self.protocol, domain, ips,
                       t2 - t0)
            return ips
        except Exception as e:
            t1 = time.time()
            t = t1 - t0
            xlog.exception("DnsOverHttpsQuery query %s cost:%f fail:%r",
                           domain, t, e)
            return []
Beispiel #23
0
    def on_udp_query(self, rsock, req_data, addr):
        start_time = time.time()
        try:
            request = DNSRecord.parse(req_data)
            if len(request.questions) != 1:
                xlog.warn("query num:%d %s", len(request.questions), request)
                return

            domain = utils.to_bytes(str(request.questions[0].qname))

            if domain.endswith(b"."):
                domain = domain[:-1]

            type = request.questions[0].qtype
            if type not in [1, 28]:
                xlog.info("direct_query:%s type:%d", domain, type)
                return self.direct_query(rsock, request, addr)

            xlog.debug("DNS query:%s type:%d from %s", domain, type, addr)

            ips = self.query(domain, type)
            if not ips:
                xlog.debug("query:%s type:%d from:%s, get fail, cost:%d",
                           domain, type, addr,
                           (time.time() - start_time) * 1000)

            reply = DNSRecord(DNSHeader(id=request.header.id,
                                        qr=1,
                                        aa=1,
                                        ra=1,
                                        auth=1),
                              q=request.q)
            ips = utils.to_bytes(ips)
            for ip_cn in ips:
                ipcn_p = ip_cn.split(b"|")
                ip = ipcn_p[0]
                if b"." in ip and type == 1:
                    reply.add_answer(RR(domain, ttl=60, rdata=A(ip)))
                elif b":" in ip and type == 28:
                    reply.add_answer(
                        RR(domain, rtype=type, ttl=60, rdata=AAAA(ip)))
            res_data = reply.pack()

            rsock.sendto(res_data, addr)
            xlog.debug("query:%s type:%d from:%s, return ip num:%d cost:%d",
                       domain, type, addr, len(reply.rr),
                       (time.time() - start_time) * 1000)
        except Exception as e:
            xlog.exception("on_query except:%r", e)
Beispiel #24
0
 def createMxResponse(self, data, request):
     dataRawEnc = urlsafe_b64encode(data)
     dataEnc = str(dataRawEnc, "utf-8")
     self._LOGGING_ and self.logger.debug_all(
         f"[{self.name}] createMxResponse() with sotp_data: {dataEnc}")
     rdomain = self.getDomainFromRequest(request.q.qname.idna()[:-1])
     reply = DNSRecord(DNSHeader(id=request.header.id, qr=1, aa=1, ra=1),
                       q=request.q)
     reply.add_answer(
         RR(rname=request.q.qname,
            rtype=QTYPE.MX,
            rclass=CLASS.IN,
            ttl=self.ttl,
            rdata=MX(f"{dataEnc}.{rdomain}")))
     return reply
Beispiel #25
0
 def createTxtResponse(self, data, request):
     # I embebed sopt data in one RR in TXT Response (but you can split sotp data in multiple RR)
     dataRawEnc = urlsafe_b64encode(data)
     dataEnc = str(dataRawEnc, "utf-8")
     self._LOGGING_ and self.logger.debug_all(
         f"[{self.name}] createTxtResponse() with sotp_data: {dataEnc}")
     reply = DNSRecord(DNSHeader(id=request.header.id, qr=1, aa=1, ra=1),
                       q=request.q)
     reply.add_answer(
         RR(rname=request.q.qname,
            rtype=QTYPE.TXT,
            rclass=CLASS.IN,
            ttl=self.ttl,
            rdata=TXT(dataEnc)))
     return reply
Beispiel #26
0
def dns_handler(s, peer, data):
    request = DNSRecord.parse(data)
    id = request.header.id
    qname = request.q.qname
    qtype = request.q.qtype
    print "------ Request (%s): %r (%s)" % (str(peer), qname.label,
                                            QTYPE[qtype])
    print "\n".join(["  %s" % l for l in str(request).split("\n")])
    print ', '.join(str(x) for x in request.ar)

    def get_ecs_option(req):
        for record in request.ar:
            if type(record) is RR:
                for opt in record.rdata:
                    if type(opt) is EDNSOption:
                        if opt.code == 8:
                            return opt

    def ip_from_edns_subnet(req):
        opt = get_ecs_option(req)
        if opt is not None:
            data = opt.data[4:].ljust(4, '\0')
            data = socket.inet_ntoa(data)
            subnetlen = str(ord(opt.data[2]))
            print "Got ECS:", data, subnetlen
            return [data, data + "/" + subnetlen]
        return ["99.99.99.99", "0/0"]

    [IP, MSG] = ip_from_edns_subnet(request)

    reply = DNSRecord(DNSHeader(id=id, qr=1, aa=1, ra=1), q=request.q)
    if qtype == QTYPE.A:
        reply.add_answer(RR(qname, qtype, rdata=A(IP)))
    elif qtype == QTYPE.AAAA:
        reply.add_answer(RR(qname, qtype, rdata=AAAA(IPV6)))
    elif qtype == QTYPE['*']:
        reply.add_answer(RR(qname, QTYPE.A, rdata=A(IP)))
        reply.add_answer(RR(qname, QTYPE.MX, rdata=MX(IP)))
        reply.add_answer(RR(qname, QTYPE.TXT, rdata=TXT(MSG)))
    else:
        reply.add_answer(RR(qname, QTYPE.CNAME, rdata=CNAME(MSG)))

    reply.add_answer(RR(qname, QTYPE.TXT, rdata=TXT(MSG)))

    print "------ Reply"
    print "\n".join(["  %s" % l for l in str(reply).split("\n")])

    s.sendto(reply.pack(), peer)
Beispiel #27
0
    def base_handle(self):
        data = self.handle_request()
        if len(data) > 0:
            try:
                dnsrequest = DNSRecord.parse(data)
                header = dnsrequest.header
                question = dnsrequest.get_q()
                questionname = question.get_qname()
                resolvedip = self.get_resolved_ip(str(questionname))

                resp = DNSRecord(DNSHeader(qr=1, aa=1, ra=1, id=header.id),
                                 q=question,
                                 a=RR(questionname, rdata=A(resolvedip)))
                self.set_fingerprint()
                self.send_response(resp.pack())
            except Exception as e:
                logger.error(e)
Beispiel #28
0
 def response_bytes_in_txt(request, data: bytes):
     '''
     将字节流包装在TXT记录里作为结果返回
     return: bytes
     '''
     assert len(data) < 256
     request = DNSRecord.parse(request)
     qname = request.q.qname
     qtype = request.q.qtype
     reply = DNSRecord(DNSHeader(id=request.header.id, qr=1, aa=1, ra=1),
                       q=request.q)
     reply.add_answer(RR(qname, qtype, rdata=TXT('')))
     reply = reply.pack()
     reply[-3:-1] = struct.pack('>H', len(data) + 1)
     reply[-1] = len(data)
     reply += data
     return reply
Beispiel #29
0
    def query(self, peer, query):
        qname = query.q.qname
        print(qname)
        qtype = QTYPE[query.q.qtype]
        qclass = CLASS[query.q.qclass]

        response = yield self.call(lookup(qname, qclass=qclass, qtype=qtype))

        record = DNSRecord(
            DNSHeader(id=query.header.id, qr=1, aa=1, ra=1),
            q=query.q,
        )

        for rr in response.value.rr:
            record.add_answer(rr)

        yield record.pack()
Beispiel #30
0
def handle_request(data, addr, sock: socket.socket, cache):
    question = DNSRecord.parse(data)
    reply = DNSRecord(DNSHeader(id=question.header.id, qr=1, aa=1, ra=1),
                      q=question.q)
    name = str(question.q.qname)

    cache.update()
    if not cache.contains(name):
        try:
            result = dns.resolver.resolve(name, 'A')
        except:  # (dns.resolver.NXDOMAIN, dns.resolver.Timeout):
            sock.sendto(reply.pack(), addr)
            return

        cache_records(result, cache)

    ans = make_response(reply, cache, name)
    sock.sendto(ans, addr)