def test_authority_domain(self):
     question = Question(Name("server1.gumpe"), Type.A, Class.IN)
     header = Header(1337, 0, 1, 0, 0, 0)
     query = Message(header, questions=[question])
     s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
     s.sendto(query.to_bytes(), (SERVER, PORT))
     data = s.recv(512)
     s.close()
     message = Message.from_bytes(data)
     self.assertCountEqual(message.answers, [
         ResourceRecord(
             name=Name("server1.gumpe."),
             type_=Type.A,
             class_=Class.IN,
             ttl=0,
             rdata=ARecordData("10.0.1.5"),
         ),
         ResourceRecord(
             name=Name("server1.gumpe."),
             type_=Type.A,
             class_=Class.IN,
             ttl=0,
             rdata=ARecordData("10.0.1.4"),
         ),
     ])
Esempio n. 2
0
    def send_request(self, ip, name):

        #create socket and request
        sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        sock.settimeout(self.timeout)

        question = Question(name, Type.A, Class.IN)
        header = Header(9001, 0, 1, 0, 0, 0)
        header.qr = 0
        header.opcode = 0
        header.rd = self.rd
        query = Message(header, [question])

        sock.sendto(query.to_bytes(), (ip, 53))

        # Receive response
        data = sock.recv(512)
        sock.close()
        response = Message.from_bytes(data)
        self.logHeader(response.header)
        if self.caching:
            for r in response.resources:
                if r.type_ == Type.A or r.type_ == Type.CNAME or r.type_ == Type.NS:
                    self.cache.add_record(r)

        return response.answers, response.authorities, response.additionals
Esempio n. 3
0
def main():
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

    question = Question(Name("google.com."), Type.A, Class.IN)
    header = Header(9001, 0, 1, 0, 0, 0)
    header.qr = 0  # 0 for query
    header.opcode = 0  # standad query
    header.rd = 1  #  recursive
    query = Message(header, [question])
    ip = (([
        ip for ip in socket.gethostbyname_ex(socket.gethostname())[2]
        if not ip.startswith("127.")
    ] or [[(s.connect(("8.8.8.8", 53)), s.getsockname()[0], s.close())
           for s in [socket.socket(socket.AF_INET, socket.SOCK_DGRAM)]][0][1]])
          + ["no IP found"])[0]

    sock.sendto(query.to_bytes(), (ip, 53))
    data = sock.recv(1024)
    mess = Message.from_bytes(data)
    """
  answer =  ResourceRecord.to_dict(mess.answers[0])
  auth = ResourceRecord.to_dict(mess.authorities[0])
  addi = ResourceRecord.to_dict(mess.additionals[0])
"""
    rrs = []
    rrs += mess.answers + mess.authorities + mess.additionals
    for r in rrs:
        print("R", r.to_dict())
 def test_concurrent_requests(self):
     queries = []
     answers = []
     question = Question(Name("gaia.cs.umass.edu"), Type.A, Class.IN)
     header = Header(1337, 0, 1, 0, 0, 0)
     header.rd = 1
     queries.append(Message(header, questions=[question]))
     answers.append([
         ResourceRecord(name=Name("gaia.cs.umass.edu"),
                        type_=Type.A,
                        class_=Class.IN,
                        ttl=0,
                        rdata=ARecordData("128.119.245.12")),
     ])
     question = Question(Name("server2.gumpe"), Type.A, Class.IN)
     header = Header(420, 0, 1, 0, 0, 0)
     queries.append(Message(header, questions=[question]))
     answers.append([
         ResourceRecord(name=Name("server2.gumpe"),
                        type_=Type.A,
                        class_=Class.IN,
                        ttl=0,
                        rdata=ARecordData("10.0.1.7")),
     ])
     header = Header(69, 0, 1, 0, 0, 0)
     question = Question(Name("www.gumpe"), Type.A, Class.IN)
     queries.append(Message(header, questions=[question]))
     answers.append([
         ResourceRecord(name=Name("www.gumpe"),
                        type_=Type.A,
                        class_=Class.IN,
                        ttl=0,
                        rdata=ARecordData("10.0.1.7")),
         ResourceRecord(name=Name("www.gumpe"),
                        type_=Type.CNAME,
                        class_=Class.IN,
                        ttl=0,
                        rdata=CNAMERecordData(Name("server2.gumpe"))),
     ])
     sockets = [
         socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
         for _ in range(len(queries))
     ]
     for i in range(len(sockets)):
         sockets[i].sendto(queries[i].to_bytes(), (SERVER, PORT))
     responses = []
     for i in range(len(sockets)):
         responses.append(Message.from_bytes(sockets[i].recv(1024)))
     for i in range(len(sockets)):
         sockets[i].close()
     for i in range(len(queries)):
         self.assertCountEqual(responses[i].answers, answers[i])
Esempio n. 5
0
    def send_query(sock, hostname, ip):
        # Create and send query
        question = Question(Name(hostname), Type.A, Class.IN)
        header = Header(randint(0, 2**16), 0, 1, 0, 0, 0)
        header.qr = 0
        header.opcode = 0
        header.rd = 0  # no recursion desired
        query = Message(header, [question])
        sock.sendto(query.to_bytes(), (ip, 53))

        # Receive response
        data = sock.recv(512)
        return Message.from_bytes(data)
 def test_message_from_bytes(self, HeaderMock, QuestionMock, ResourceMock):
     packet = b"\x01\x02\x03\x04\x05"
     header = Header(9001, 0, 1, 1, 1, 1)
     HeaderMock.from_bytes.return_value = header
     QuestionMock.from_bytes.return_value = (1, 13)
     ResourceMock.from_bytes.side_effect = [(2, 14), (3, 15), (4, 16)]
     message1 = Message.from_bytes(packet)
     message2 = Message(header, [1], [2], [3], [4])
     self.assertEqual(message1, message2)
     HeaderMock.from_bytes.assert_called_with(packet)
     QuestionMock.from_bytes.assert_called_with(packet, 12)
     calls = [call(packet, 13), call(packet, 14), call(packet, 15)]
     ResourceMock.from_bytes.assert_has_calls(calls)
Esempio n. 7
0
def create_http_wire_response(
    request: Request, query_response: Message
) -> Response:
    logger = logging.getLogger("doh-server")
    logger.debug(
        "[HTTP] " + str(request.method) + " " + str(request.headers.get("Accept"))
    )
    if isinstance(query_response, Message):
        query_response.id = 0
        body = query_response.to_wire()
        response = Response(body, content_type=DOH_CONTENT_TYPE)
        response.headers["content-length"] = str(len(body))
        return set_headers(request, response, query_response)
    else:
        return Response(query_response)
Esempio n. 8
0
    def test_server_no_caching(self):
        data = self.send_query("nickstracke.xyz", PORT + 5)

        mess = Message.from_bytes(data)
        ip1 = mess.answers[0].rdata.address
        ip2 = socket.gethostbyname("nickstracke.xyz")
        self.assertEqual(ip1, ip2)
 def send_response(self, records, authoritative, error=0):
     """Send a response to some message."""
     if not error and len(records) == 0:
         error = 3  # NXDOMAIN (Domain Name not found)
     if error != 0:
         header = Header(self.message.header.ident, 0, 0, 0, 0, 0)
         header.rcode = error
     else:
         header = Header(self.message.header.ident, 0, 0, len(records), 0,
                         0)
     header.aa = authoritative  # Authoritative Answer
     header.qr = 1  # Message is Response
     header.rd = self.message.header.rd  # Recursion desired
     header.ra = 1  # Recursion Available
     response = Message(header, answers=records)
     self.sock.sendto(response.to_bytes(), self.address)
 def test_outside_zone(self):
     question = Question(Name("gaia.cs.umass.edu"), Type.A, Class.IN)
     header = Header(1337, 0, 1, 0, 0, 0)
     header.rd = 1
     query = Message(header, questions=[question])
     s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
     s.sendto(query.to_bytes(), (SERVER, PORT))
     data = s.recv(512)
     s.close()
     message = Message.from_bytes(data)
     self.assertEqual(message.answers, [
         ResourceRecord(name=Name("gaia.cs.umass.edu"),
                        type_=Type.A,
                        class_=Class.IN,
                        ttl=0,
                        rdata=ARecordData("128.119.245.12")),
     ])
Esempio n. 11
0
 def build_message(self,id, rd, aa, rcode, questions, answers, authorities, additionals):
     header = Header(id, 0, len(questions), len(answers), len(authorities), len(additionals))
     header.qr = 1
     header.opcode = 0
     header.rd = rd
     header.ra = 1
     header.aa = aa
     header.rcode = rcode
     return Message(header, questions=questions, answers=answers, authorities=authorities, additionals=additionals)
Esempio n. 12
0
    def sendQuestion(self, hostname, server):
        sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        sock.settimeout(self.timeout)

        # Create and send query
        identifier = 9001  # placeholder
        question = Question(Name(hostname), Type.A, Class.IN)
        header = Header(identifier, 0, 1, 0, 0, 0)
        header.qr = 0
        header.opcode = 0
        header.rd = 1
        query = Message(header, [question])
        sock.sendto(query.to_bytes(), (server, 53))

        # Receive response
        data = sock.recv(512)
        response = Message.from_bytes(data)
        sock.close()
        return response
Esempio n. 13
0
    def test_concurrency(self):
        s2 = threading.Thread(target=self.send_query,
                              args=("nickstracke.xyz", PORT + 2))
        s2.daemon = True
        s2.start()
        data = self.send_query("nickstracke.xyz", PORT + 3)

        mess = Message.from_bytes(data)
        ip1 = mess.answers[0].rdata.address
        ip2 = socket.gethostbyname("nickstracke.xyz")
        self.assertEqual(ip1, ip2)
Esempio n. 14
0
 def send_query(self, hostname, port):
     question = Question(Name(hostname), Type.A, Class.IN)
     # use port as id
     header = Header(port, 0, 1, 0, 0, 0)
     header.qr = 0  # 0 for query
     header.opcode = 0  # standad query
     header.rd = 1  #  recursive
     query = Message(header, [question])
     ip = (([
         ip for ip in socket.gethostbyname_ex(socket.gethostname())[2]
         if not ip.startswith("127.")
     ] or [[(s.connect(("8.8.8.8", 53)), s.getsockname()[0], s.close())
            for s in [socket.socket(socket.AF_INET, socket.SOCK_DGRAM)]
            ][0][1]]) + ["no IP found"])[0]
     sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
     sock.bind((ip, port))
     print("Sock Test:", sock)
     sock.sendto(query.to_bytes(), (ip, PORT))
     data = sock.recv(1024)
     sock.close()
     return data
 def test_message_to_bytes(self):
     header = MagicMock()
     header.to_bytes.return_value = b"\x01"
     question = MagicMock()
     question.to_bytes.return_value = b"\x02"
     answer = MagicMock()
     answer.to_bytes.return_value = b"\x03"
     authority = MagicMock()
     authority.to_bytes.return_value = b"\x04"
     additional = MagicMock()
     additional.to_bytes.return_value = b"\x05"
     message = Message(header, [question], [answer], [authority],
                       [additional])
     self.assertEqual(message.to_bytes(), b"\x01\x02\x03\x04\x05")
 def run(self):
     """ Run the handler thread"""
     try:
         self.message = Message.from_bytes(self.data)
     except:
         self.message = Message(Header(0, 0, 0, 0, 0, 0))
         self.send_response([], False, 1)
         return
     self.domain = self.message.questions[0].qname
     print(threading.current_thread())
     print("\tDomain:", self.domain)
     print("\tAddress:", self.address)
     authoritative, records = self.lookup_zone(self.domain)
     if records is None:
         if self.message.header.rd:
             sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
             resolver = Resolver(5, Server.cache)
             records = resolver.query_recursive(sock, self.domain,
                                                Resolver.root_server)
             sock.close()
         else:
             records = []
     self.send_response(records, authoritative)
Esempio n. 17
0
    def serve(self):
        """ Start serving request """

        print("[+] - DNS Server up and running.")

        while not self.done:
            data, addr = self.socket.recvfrom(1024)

            try:
                message = Message.from_bytes(data)
            except:
                print("[-] - Received invalid data.")
                continue

            rh = RequestHandler(self.socket, addr, self.ttl, message,
                                self.resolver, self.catalog)
            rh.start()
Esempio n. 18
0
    def serve(self):
        """Start serving requests"""
        sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        sock.bind(("", self.port))

        while not self.done:
            data, address = sock.recvfrom(65565)
            message = Message.from_bytes(data)

            rd = message.header.rd
            rcode = 0
            aa = 1

            self.log("REQUEST RECIEVED:", address)
            answers, authorities, additionals = self.zone_resolution(message.questions)

            if answers == []:
                if authorities == [] and additionals == []:
                    self.log("\tZONE RESOLUTION FAILED")
                    answers = self.consult_cache(message.questions)

                    if answers == []:
                        self.log("\tCACHE LOOKUP FAILED")
                        rcode = 3
                    else:
                        aa = 0

                if rcode == 3 and rd == 1:
                    rcode = 0
                    self.log("\tCALLING RESOLVER")
                    resolver = Resolver(5, True, 0)
                    resolver.rd = 0
                    resolver.rootip = "198.41.0.4"
                    for q in message.questions:
                        self.log("\t\tRESOLVING:", q.qname)

                        hostname, namelist, iplist = resolver.gethostbyname(str(q.qname))
                        if hostname == str(q.qname):
                            for ip in iplist:
                                answers.append(ResourceRecord(q.qname, Type.A, Class.IN, self.ttl, ARecordData(ip)))
                            for n in namelist:
                                answers.append(ResourceRecord(q.qname, Type.CNAME, Class.IN, self.ttl, CNAMERecordData(n)))

            self.log("SENDING RESPONSE:", rcode, "\n")
            mess = self.build_message(message.header.ident, rd, aa, rcode, message.questions, answers, authorities, additionals)
            sock.sendto(mess.to_bytes(), address)
Esempio n. 19
0
    def serve(self):
        """Start serving requests"""
        sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        sock.bind(('localhost', self.port))
        zone = Zone().read_master_file("roothints.md")
        #load zone file into memory
        while not self.done:
            print("Waiting...")
            data, address = sock.recvfrom(512)
            #Following piece of code results in a weird error message which I do not understand. I do quite literally the same thing some other students do but it results in an error message.
            req = Message.from_bytes(data)
            questions = req.questions
            for question in questions:
                hostname = question.qname

                #consult zone and try to answer and cache
                #if recursion is enabled, and zone does not help: use resolver
            #send back reply.
            pass
Esempio n. 20
0
    def run(self):
        """ Run the handler thread"""
        msg = Message.from_bytes(self.data)
        header = msg.header
        recursion = header.rd != 0
        questions = msg.questions

        answers = []
        authorative = []
        additional = []
        for question in questions:
            qname = question.qname
            qtype = question.qtype
            if question.qclass != Class.IN:
                pass
            domains = self.getdomains(str(qname))
            for domain in domains:
                if not self.zone.records.get(domain, False):
                    continue
                for rr in self.zone.records[domain]:
                    if (rr.type_ == Type.A or rr.type_
                            == Type.CNAME) and domain == str(qname):
                        answers.append(rr)
                    if rr.type_ == Type.NS:
                        authorative.append(rr)
                        for rec in self.zone.records[str(rr.rdata.nsdname)]:
                            if rec not in additional:
                                if rec.qtype == Type.A:
                                    additional.append(rec)
            if authorative or answers:
                header_response = Header(9001, 0, 1, len(answers),
                                         len(authorative), len(additionals))
                header_response.qr = True
                header_response.opcode(1)
                header_response.aa(False)
                header_respones.tc(False)
                header_response.rd(False)
                header_response.ra(True)
                header_response.z(False)
                header_respones.rcode(False)

                respons = Message(header_response, [question], answers,
                                  authorities, additionals)

                self.sock.sendto(respons.to_bytes(), self.addr)
                break

            if recursion and (qtype == Type.A or qtype == Type.CNAME):
                answers = []
                resolver = Resolver(100, False, 0, True)
                (hostname, aliaslist,
                 ipaddrlist) = resolver.gethostbyname(question.qname)
                header_response = Header(9001, 0, 1,
                                         len(aliaslist) + len(ipaddrlist), 0,
                                         0)
                header_response.qr = 1
                header_response.opcode = 1
                header_response.aa = 0
                header_response.tc = 0
                header_response.rd = 0
                header_response.ra = 1
                header_response.rcode = 0

                for addr in ipaddrlist:
                    answers.append(
                        ResourceRecord.from_dict({
                            "name": str(hostname),
                            "type": str(Type.A),
                            "class": str(Class.IN),
                            "ttl": 0,
                            "rdata": {
                                "address": str(addr)
                            }
                        }))
                for alias in aliaslist:
                    answers.append(
                        ResourceRecord.from_dict({
                            "name": str(hostname),
                            "type": str(Type.CNAME),
                            "class": str(Class.IN),
                            "ttl": 0,
                            "rdata": {
                                "cname": str(alias)
                            }
                        }))
                response = Message(header_response, questions, answers)
                self.sock.sendto(response.to_bytes(), self.addr)
                break
Esempio n. 21
0
    def gethostbyname(self, hostname, dnsserv='192.112.36.4'):
        """Translate a host name to IPv4 address.

        Currently this method contains an example. You will have to replace
        this example with the algorithm described in section 5.3.3 in RFC 1034.

        Args:
            hostname (str): the hostname to resolve

        Returns:
            (str, [str], [str]): (hostname, aliaslist, ipaddrlist)
        """
        ipaddrlist = []
        cnames = []
        temp = []
        if (self.caching):
            rcache = RecordCache(self.ttl)
            rcord = rcache.lookup(hostname, Type.ANY, Class.IN)
            if (rcord):
                for rec in rcord:
                    if rec.type_ == Type.A:
                        arec = rec.rdata
                        ipaddrlist.append(arec.address)
                    elif rec.type_ == Type.CNAME:
                        crec = rec.rdata
                        cnames.append(crec.cname)
            if ipaddrlist:
                return hostname, cnames, ipaddrlist
            elif cnames:
                return self.gethostbyname(cnames[0], dnsserv)

        sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        sock.settimeout(self.timeout)

        # Create and send query
        question = Question(Name(str(hostname)), Type.A, Class.IN)
        header = Header(9001, 0, 1, 0, 0, 0)
        header.qr = 0
        header.opcode = 0
        header.rd = 1
        query = Message(header, [question])
        sock.sendto(query.to_bytes(), (str(dnsserv), 53))

        # Receive response
        data = sock.recv(2048)
        response = Message.from_bytes(data)
        print("Number of answers: " + str(len(response.answers)))
        print("Number of authorities: " + str(len(response.authorities)))
        print("Number of additionals: " + str(len(response.additionals)))

        # Get data
        aliaslist = cnames
        ipaddrlist = []
        dnslist = []

        while response.answers:
            for answer in response.answers:
                if answer.type_ == Type.A:
                    print("found A RR")
                    if (self.caching):
                        rcache.add_record(answer)
                    ipaddrlist.append(answer.rdata.address)
                if answer.type_ == Type.CNAME:
                    aliaslist.append(answer.rdata.cname)
                if answer.type_ == Type.NS:
                    dnslist.append(answer.rdata.nsdname)
            if ipaddrlist:
                return hostname, aliaslist, ipaddrlist
            elif aliaslist:
                question = Question(Name(aliaslist[0]), Type.A, Class.IN)
                query = Message(header, [question])
                sock.sendto(query.to_bytes(), (dnsserv, 53))
                data = sock.recv(2048)
                response = Message.from_bytes(data)
            elif dnslist:
                nsname = dnslist.pop()
                maybe_dnsserv = self.getnsaddr(nsname, response.additionals)
                if maybe_dnsserv:
                    dnsserv = maybe_dnsserv
                else:
                    pass
                sock.sendto(query.to_bytes(), (dnsserv, 53))
                data = sock.recv(2048)
                response = Message.from_bytes(data)
            else:
                break

        if response.authorities:
            for authority in response.authorities:
                if authority.type_ != Type.NS:
                    pass
                dnslist.append(authority.rdata.nsdname)
            while dnslist:
                nsname = dnslist.pop()
                maybe_next_dnsserv = self.getnsaddr(nsname,
                                                    response.additionals)
                if maybe_next_dnsserv:
                    next_dns_serv = maybe_next_dnsserv
                else:
                    pass
                (hname, aliasl, ipaddrl) = self.gethostbyname(hostname, nsname)
                if ipaddrl:
                    return hname, aliasl, ipaddrl
Esempio n. 22
0
    def gethostbyname(self, hostname):
        """Translate a host name to IPv4 address.

        Currently this method contains an example. You will have to replace
        this example with the algorithm described in section 5.3.3 in RFC 1034.

        Args:
            hostname (str): the hostname to resolve

        Returns:
            (str, [str], [str]): (hostname, aliaslist, ipaddrlist)
        """
        alias_list = []
        a_list = []
        slist = []
        found = False

        acs = self.getRecordsFromCache(hostname, Type.A, Class.IN)
        if acs:
            a_list += acs
            return hostname, alias_list, a_list

        nscs = self.matchByLabel(hostname, Type.NS, Class.IN)
        for ns in nscs:
            glue = self.getRecordsFromCache(str(ns.rdata.nsdname))
            if glue:
                slist += glue
            else:
                slist += [ns]

        id = self._make_id()

        # Create and send query
        question = Question(Name(hostname), Type.A, Class.IN)
        header = Header(id, 0, 1, 0, 0, 0)
        header.qr = 0  # 0 for query
        header.opcode = 0  # standad query
        header.rd = 0  # not recursive
        query = Message(header, [question])

        self.zone.read_master_file('dns/root.zone')

        sbelt = []
        for root in list(self.zone.records.values()):
            sbelt += [r for r in root if r.type_ == Type.A]

        while not found:
            if slist:
                rr = slist.pop()
                if rr.type_ == Type.A:
                    addr = rr.rdata.address
                    self.sock.send((query, addr, 53))
                elif rr.type_ == Type.NS:
                    fqdn = str(rr.rdata.nsdname)
                    _, _, a_rrs = self.gethostbyname(fqdn)
                    slist += a_rrs
                    continue
                elif rr.type_ == Type.CNAME:
                    fqdn = str(rr.rdata.cname)
                    _, cname_rrs, a_rrs = self.gethostbyname(fqdn)
                    a_list += a_rrs
                    alias_list += cname_rrs
                    break

            elif sbelt:
                rr = sbelt.pop()
                addr = rr.rdata.address
                self.sock.send((query, addr, 53))
            else:
                break

            # Receive response
            data = None
            while not data:
                data = self.sock.msgThere(id)
            response, _ = data[0]
            #response = Message.from_bytes(data)

            for answer in response.answers:
                if answer.type_ == Type.A:
                    self.addRecordToCache(answer)
                    a_list.append(answer)
                    found = True
                if answer.type_ == Type.CNAME:
                    self.addRecordToCache(answer)
                    alias_list.append(answer)
                    slist += [answer]
                    continue

            nss = []
            for auth in response.authorities:
                if auth.type_ == Type.NS:
                    nss.append(auth)
                    self.addRecordToCache(auth)

            a_add = {}
            for add in response.additionals:
                if add.type_ == Type.A:
                    name = str(add.name)
                    a_add[name] = add
                    self.addRecordToCache(add)

            for ns in nss:
                name = str(ns.rdata.nsdname)
                if name in a_add:
                    slist += [a_add[name]]
                else:
                    slist += [ns]

        return hostname, alias_list, a_list
Esempio n. 23
0
    def handle_request(self):
        """ Attempts to answer the received query """
        #Check this next to the given algorithm

        #print("Catalog:",self.catalog.zones)
        #for zone in self.catalog.zones:
        #    print("Records:",self.catalog.zones[zone].records)

        if self.message.header.opcode != 0:  #Send a not implemented error, we don't need to support those kinds of queries
            print("[-] - Received a nonstandard query. This is unsupported.")
            header = Header(ident, 0, 1, 0, 0, 0)
            header.qr = 1
            header.rd = self.message.header.rd
            header.ra = 1
            header.rcode = 4
            self.sendResponse(Message(header, self.message.questions, []))
            return

        #print("[*] - Handling request.")
        if len(self.message.questions) != 1:  #Send a format error response
            print("[-] - Invalid request.")
            header = Header(ident, 0, 1, 0, 0, 0)
            header.qr = 1
            header.rd = self.message.header.rd
            header.ra = 1
            header.rcode = 1
            self.sendResponse(Message(header, self.message.questions, []))
            return
        #print("MSG:",self.message)
        #print("RECEIVED QUESTION",self.message.questions[0])
        hname = str(self.message.questions[0].qname)
        #print("Solving",hname,type(hname))
        ident = self.message.header.ident
        #print("Checking zone")
        answer, authority, found = self.check_zone(hname)
        #print("Wat we in de zone hebben gevonden")
        #print("ANS:",answer,"AUTH:",authority,"FOUND:",found)
        #found = False
        if found:
            print("Found in zone")
            header = Header(ident, 0, 1, len(answer), len(authority), 0)
            header.qr = 1
            header.aa = 1
            header.rd = self.message.header.rd
            header.ra = 1

            self.sendResponse(
                Message(header, self.message.questions, answer, authority))

        elif self.message.header.rd == 1:
            h, al, ad = self.resolver.gethostbyname(hname)

            #Make and send th appropriate response
            header = Header(ident, 0, 1, len(al) + len(ad), 0, 0)
            header.qr = 1
            header.rd = self.message.header.rd
            header.ra = 1

            aliases = [
                ResourceRecord(Name(h), Type.CNAME, Class.IN, self.ttl,
                               RecordData.create(Type.CNAME, Name(alias)))
                for alias in al
            ]
            addresses = [
                ResourceRecord(Name(h), Type.A, Class.IN, self.ttl,
                               RecordData.create(Type.A, address))
                for address in ad
            ]

            self.sendResponse(
                Message(header, self.message.questions, aliases + addresses))
        else:  #Send an empty response
            header = Header(ident, 0, 1, 0, 0, 0)
            header.qr = 1
            header.rd = self.message.header.rd
            header.ra = 1
            header.rcode = 0
            self.sendResponse(Message(header, self.message.questions, []))
Esempio n. 24
0
 def test_authority(self):
     data = self.send_query("ns1.ourdomain.com", PORT + 4)
     mess = Message.from_bytes(data)
     ip1 = mess.answers[0].rdata.address
     print(ip1)
     self.assertEqual(ip1, "255.255.255.255")