Ejemplo n.º 1
0
 def from_bytes(cls, packet, offset):
     """Convert ResourceRecord from bytes."""
     name, offset = Name.from_bytes(packet, offset)
     type_ = Type(struct.unpack_from("!H", packet, offset)[0])
     class_ = Class(struct.unpack_from("!H", packet, offset + 2)[0])
     ttl, rdlength = struct.unpack_from("!iH", packet, offset + 4)
     offset += 10
     rdata = RecordData.create_from_bytes(type_, packet, offset, rdlength)
     offset += rdlength
     return cls(name, type_, class_, ttl, rdata), offset
Ejemplo n.º 2
0
 def default(self, obj):
     if isinstance(obj, ResourceRecord):
         return {
             "name": obj.name,
             "type": Type.to_string(obj.type_),
             "class": Class.to_string(obj.class_),
             "ttl": obj.ttl,
             "rdata": obj.rdata.data
         }
     return json.JSONEncoder.default(self, obj)
Ejemplo n.º 3
0
 def default(self, obj):
     if isinstance(obj, ResourceRecord):
         return {
             "name": obj.name,
             "type": Type.to_string(obj.type_),
             "class": Class.to_string(obj.class_),
             "ttl": obj.ttl,
             "rdata": obj.rdata.data,
             "time": obj.time
         }
     return json.JSONEncoder.default(self, obj)
Ejemplo n.º 4
0
def resource_from_json(dct):
    """ Convert JSON object to ResourceRecord
    
    Usage:
        records = json.loads(string, object_hook=resource_from_json)
    """
    name = dct["name"]
    type_ = Type.from_string(dct["type"])
    class_ = Class.from_string(dct["class"])
    ttl = dct["ttl"]
    rdata = RecordData.create(type_, dct["rdata"])
    return ResourceRecord(name, type_, class_, ttl, rdata)
Ejemplo n.º 5
0
    def resource_from_json(dct):
        """ Convert JSON object to ResourceRecord

        Usage:
            records = json.loads(string, object_hook=resource_from_json)
        """
        name = dct["name"]
        type_ = Type.from_string(dct["type"])
        class_ = Class.from_string(dct["class"])
        ttl = dct["ttl"]
        rdata = RecordData.create(type_, dct["rdata"])
        t = dct["time"]
        return ResourceRecord(name, type_, class_, ttl, rdata, t)
Ejemplo n.º 6
0
 def test_single_lookup(self):
     """Ask for a single existing hostname"""
     dnsID = randint(0, 65535)
     header = dns.message.Header(dnsID, 0, 1, 0, 0, 0)
     header.qr = 0
     header.opcode = 0
     header.aa = 0
     header.tc = 0
     header.rd = 1
     header.ra = 0
     header.z = 0
     header.rcode = 0
     qname = "www.funnygames.com"
     qtype = Type.ANY         	# request for all records
     qclass = Class.IN		# ANY
     question = dns.message.Question(qname, qtype, qclass)
     request = dns.message.Message(header, [question], [], [], [])
     requestByte = request.to_bytes()
     self.client_socket.sendto(requestByte, (server, portnr))
     print Type.to_string(question.qtype) + Class.to_string(question.qclass)
     responseData = self.client_socket.recv(512)
     response = dns.message.Message.from_bytes(responseData)
     self.assertNotEquals(response.answers, [])
Ejemplo n.º 7
0
    def add_record(self, record):
        """ Add a new Record to the cache
        
        Args:
            record (ResourceRecord): the record added to the cache
        """
        if record.ttl == 0:
            raise CacheException(
                'RRs with a ttl of 0 may not be cached')  # see rfc 1035 p.11
        elif record.ttl < 0:
            raise CacheException('ttl smaller than 0')
        elif record.type_ not in [Type.A, Type.CNAME, Type.NS]:
            raise CacheException(
                'Only A, CNAME and NS-Resource Records may be cached, actual type is '
                + Type.to_string(record.type_))

        self.records = set([
            r for r in self.records if not (
                r.name == record.name and r.rdata.data == record.rdata.data)
        ])
        self.records.add(record)
 def from_bytes(cls, packet, offset):
     """Convert Question from bytes."""
     qname, offset = Name.from_bytes(packet, offset)
     qtype = Type(struct.unpack_from("!H", packet, offset)[0])
     qclass = Class(struct.unpack_from("!H", packet, offset + 2)[0])
     return cls(qname, qtype, qclass), offset + 4
Ejemplo n.º 9
0
    def add_record(self, record):
        """ Add a new Record to the cache
        
        Args:
            record (ResourceRecord): the record added to the cache
        """
        if record.ttl == 0:
            raise CacheException('RRs with a ttl of 0 may not be cached')  # see rfc 1035 p.11
        elif record.ttl < 0:
            raise CacheException('ttl smaller than 0')
        elif record.type_ not in [Type.A, Type.CNAME, Type.NS]:
            raise CacheException('Only A, CNAME and NS-Resource Records may be cached, actual type is ' + Type.to_string(record.type_))

        self.records = set([r for r in self.records
                            if not (r.name == record.name and r.rdata.data == record.rdata.data)])
        self.records.add(record)
Ejemplo n.º 10
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 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)
        """
        if self.caching:
            #self.cache.update() This was meant for TTL but it ended up not working.
            alternatives = self.cache.lookup(hostname, Type.CNAME, Class.IN)
            ips = self.cache.lookup(hostname, Type.A, Class.IN)
            if ips is not None:
                print("pulled from cache:")
                return hostname, alternatives, [ips.rdata.data]
	
        # Rootservers
        hints = [
        '198.41.0.4',
        '192.228.79.201',
        '192.33.4.12',
        '199.7.91.13',
        '192.203.230.10',
        '192.5.5.241',
        '192.112.36.4',
        '198.97.190.53',
        '192.36.148.17',
        '192.58.128.30',
        '193.0.14.129',
        '199.7.83.42',
        '202.12.27.33'
        ]
        
        timeout = 2 # Time waited for a response
        sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        sock.settimeout(timeout)
        
        # Create query
        question = dns.message.Question(hostname, Type.ANY, Class.IN)
        header = dns.message.Header(9001, 0, 1, 0, 0, 0)
        header.qr = 0
        header.opcode = 0
        header.rd = 0
        query = dns.message.Message(header, [question])
        
        targetfound = False
        hintindex = 0
        
        while hintindex < len(hints) and not targetfound:
            currenthint = hints[hintindex]
            
            try:
                # Send query
                sock.sendto(query.to_bytes(), (currenthint, 53))
                
                # Receive response
                data = sock.recv(512)
                response = dns.message.Message.from_bytes(data)
                
                if response is not None:
                    if self.caching:
                        for record in response.answers + response.authorities + response.additionals:
							self.cache.add_record(record)
                    print "\nanswers:"
                    for answer in response.answers:
                        if answer.type_ in [1,2,5]:
                            print Type.to_string(answer.type_)
                            print answer.name
                            print answer.rdata.data
                            print "Answer found.\n"
                            targetfound = True
                    print "\nauthorities:"
                    for authority in response.authorities:
                        if authority.type_ in [1,2,5]:
                            print Type.to_string(authority.type_)
                            print authority.name
                            print authority.rdata.data
                    print "\nadditionals:"
                    for additional in response.additionals:
                        if additional.type_ in [1,2,5]:
                            print Type.to_string(additional.type_)
                            print additional.name
                            print additional.rdata.data
                            if additional.rdata.data is not None and additional.rdata.data not in hints:
                                hints.append(additional.rdata.data)
            except socket.timeout:
                print "Server timed out"
            hintindex += 1
        
        if self.caching:
            self.cache.write_cache_file()
        if targetfound:
            # Get data
            aliases = []
            for additional in response.additionals:
                if additional.type_ == Type.CNAME:
                    aliases.append(additional.rdata.data)
            addresses = []
            for answer in response.answers:
                if answer.type_ == Type.A:
                    addresses.append(answer.rdata.data)

            return hostname, aliases, addresses
        return hostname, [], []