Пример #1
0
 def test_question_to_bytes(self):
     #name = MagicMock()
     #name.to_bytes.return_value = b"\x07example\x03com\x00"
     #/\This stuff doesn't work because an error in the framework as it was given
     name = "example.com"
     question = Question(name, Type.NS, Class.IN)
     self.assertEqual(question.to_bytes(0, {}),
                      b"\x07example\x03com\x00\x00\x02\x00\x01")
 def test_question_from_bytes(self, MockName):
     packet = b"\x07example\x03com\x00\x00\x02\x00\x01"
     MockName.from_bytes.return_value = (Name("example.com"), 13)
     question1, offset = Question.from_bytes(packet, 0)
     question2 = Question(Name("example.com"), Type.NS, Class.IN)
     self.assertEqual(question1, question2)
     self.assertEqual(offset, 17)
     MockName.from_bytes.assert_called_with(packet, 0)
 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])
 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"),
         ),
     ])
Пример #5
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
Пример #6
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())
Пример #7
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_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")),
     ])
Пример #9
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
Пример #10
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_question_to_bytes(self):
     name = MagicMock()
     name.to_bytes.return_value = b"\x07example\x03com\x00"
     question = Question(name, Type.NS, Class.IN)
     self.assertEqual(question.to_bytes(0, {}),
                      b"\x07example\x03com\x00\x00\x02\x00\x01")
Пример #12
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
Пример #13
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