133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck# Copyright (C) 2001-2007, 2009, 2010 Nominum, Inc. 233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck# 333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck# Permission to use, copy, modify, and distribute this software and its 433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck# documentation for any purpose with or without fee is hereby granted, 533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck# provided that the above copyright notice and this permission notice 633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck# appear in all copies. 733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck# 833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES 933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 1033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR 1133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 1233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 1333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 1433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 1533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 1633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck"""DNS rdata. 1733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 1833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck@var _rdata_modules: A dictionary mapping a (rdclass, rdtype) tuple to 1933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reckthe module which implements that type. 2033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck@type _rdata_modules: dict 2133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck@var _module_prefix: The prefix to use when forming modules names. The 2233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reckdefault is 'dns.rdtypes'. Changing this value will break the library. 2333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck@type _module_prefix: string 2433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck@var _hex_chunk: At most this many octets that will be represented in each 2533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reckchunk of hexstring that _hexify() produces before whitespace occurs. 2633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck@type _hex_chunk: int""" 2733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 2833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reckimport cStringIO 2933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 3033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reckimport dns.exception 3133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reckimport dns.rdataclass 3233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reckimport dns.rdatatype 3333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reckimport dns.tokenizer 3433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 3533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck_hex_chunksize = 32 3633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 3733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reckdef _hexify(data, chunksize=None): 3833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck """Convert a binary string into its hex encoding, broken up into chunks 3933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck of I{chunksize} characters separated by a space. 4033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 4133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck @param data: the binary string 4233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck @type data: string 4333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck @param chunksize: the chunk size. Default is L{dns.rdata._hex_chunksize} 4433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck @rtype: string 4533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck """ 4633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 4733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck if chunksize is None: 4833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck chunksize = _hex_chunksize 4933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck hex = data.encode('hex_codec') 5033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck l = len(hex) 5133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck if l > chunksize: 5233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck chunks = [] 5333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck i = 0 5433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck while i < l: 5533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck chunks.append(hex[i : i + chunksize]) 5633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck i += chunksize 5733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck hex = ' '.join(chunks) 5833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck return hex 5933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 6033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck_base64_chunksize = 32 6133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 6233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reckdef _base64ify(data, chunksize=None): 6333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck """Convert a binary string into its base64 encoding, broken up into chunks 6433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck of I{chunksize} characters separated by a space. 6533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 6633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck @param data: the binary string 6733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck @type data: string 6833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck @param chunksize: the chunk size. Default is 6933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck L{dns.rdata._base64_chunksize} 7033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck @rtype: string 7133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck """ 7233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 7333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck if chunksize is None: 7433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck chunksize = _base64_chunksize 7533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck b64 = data.encode('base64_codec') 7633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck b64 = b64.replace('\n', '') 7733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck l = len(b64) 7833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck if l > chunksize: 7933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck chunks = [] 8033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck i = 0 8133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck while i < l: 8233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck chunks.append(b64[i : i + chunksize]) 8333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck i += chunksize 8433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck b64 = ' '.join(chunks) 8533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck return b64 8633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 8733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck__escaped = { 8833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck '"' : True, 8933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck '\\' : True, 9033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck } 9133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 9233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reckdef _escapify(qstring): 9333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck """Escape the characters in a quoted string which need it. 9433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 9533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck @param qstring: the string 9633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck @type qstring: string 9733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck @returns: the escaped string 9833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck @rtype: string 9933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck """ 10033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 10133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck text = '' 10233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck for c in qstring: 10333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck if c in __escaped: 10433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck text += '\\' + c 10533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck elif ord(c) >= 0x20 and ord(c) < 0x7F: 10633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck text += c 10733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck else: 10833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck text += '\\%03d' % ord(c) 10933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck return text 11033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 11133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reckdef _truncate_bitmap(what): 11233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck """Determine the index of greatest byte that isn't all zeros, and 11333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck return the bitmap that contains all the bytes less than that index. 11433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 11533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck @param what: a string of octets representing a bitmap. 11633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck @type what: string 11733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck @rtype: string 11833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck """ 11933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 12033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck for i in xrange(len(what) - 1, -1, -1): 12133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck if what[i] != '\x00': 12233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck break 12333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck return ''.join(what[0 : i + 1]) 12433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 12533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reckclass Rdata(object): 12633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck """Base class for all DNS rdata types. 12733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck """ 12833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 12933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck __slots__ = ['rdclass', 'rdtype'] 13033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 13133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck def __init__(self, rdclass, rdtype): 13233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck """Initialize an rdata. 13333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck @param rdclass: The rdata class 13433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck @type rdclass: int 13533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck @param rdtype: The rdata type 13633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck @type rdtype: int 13733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck """ 13833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 13933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck self.rdclass = rdclass 14033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck self.rdtype = rdtype 14133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 14233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck def covers(self): 14333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck """DNS SIG/RRSIG rdatas apply to a specific type; this type is 14433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck returned by the covers() function. If the rdata type is not 14533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck SIG or RRSIG, dns.rdatatype.NONE is returned. This is useful when 14633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck creating rdatasets, allowing the rdataset to contain only RRSIGs 14733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck of a particular type, e.g. RRSIG(NS). 14833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck @rtype: int 14933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck """ 15033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 15133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck return dns.rdatatype.NONE 15233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 15333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck def extended_rdatatype(self): 15433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck """Return a 32-bit type value, the least significant 16 bits of 15533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck which are the ordinary DNS type, and the upper 16 bits of which are 15633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck the "covered" type, if any. 15733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck @rtype: int 15833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck """ 15933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 16033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck return self.covers() << 16 | self.rdtype 16133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 16233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck def to_text(self, origin=None, relativize=True, **kw): 16333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck """Convert an rdata to text format. 16433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck @rtype: string 16533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck """ 16633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck raise NotImplementedError 16733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 16833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck def to_wire(self, file, compress = None, origin = None): 16933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck """Convert an rdata to wire format. 17033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck @rtype: string 17133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck """ 17233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 17333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck raise NotImplementedError 17433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 17533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck def to_digestable(self, origin = None): 17633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck """Convert rdata to a format suitable for digesting in hashes. This 17733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck is also the DNSSEC canonical form.""" 17833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck f = cStringIO.StringIO() 17933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck self.to_wire(f, None, origin) 18033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck return f.getvalue() 18133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 18233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck def validate(self): 18333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck """Check that the current contents of the rdata's fields are 18433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck valid. If you change an rdata by assigning to its fields, 18533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck it is a good idea to call validate() when you are done making 18633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck changes. 18733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck """ 18833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck dns.rdata.from_text(self.rdclass, self.rdtype, self.to_text()) 18933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 19033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck def __repr__(self): 19133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck covers = self.covers() 19233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck if covers == dns.rdatatype.NONE: 19333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck ctext = '' 19433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck else: 19533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck ctext = '(' + dns.rdatatype.to_text(covers) + ')' 19633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck return '<DNS ' + dns.rdataclass.to_text(self.rdclass) + ' ' + \ 19733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck dns.rdatatype.to_text(self.rdtype) + ctext + ' rdata: ' + \ 19833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck str(self) + '>' 19933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 20033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck def __str__(self): 20133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck return self.to_text() 20233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 20333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck def _cmp(self, other): 20433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck """Compare an rdata with another rdata of the same rdtype and 20533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck rdclass. Return < 0 if self < other in the DNSSEC ordering, 20633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 0 if self == other, and > 0 if self > other. 20733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck """ 20833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 20933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck raise NotImplementedError 21033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 21133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck def __eq__(self, other): 21233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck if not isinstance(other, Rdata): 21333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck return False 21433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck if self.rdclass != other.rdclass or \ 21533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck self.rdtype != other.rdtype: 21633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck return False 21733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck return self._cmp(other) == 0 21833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 21933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck def __ne__(self, other): 22033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck if not isinstance(other, Rdata): 22133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck return True 22233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck if self.rdclass != other.rdclass or \ 22333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck self.rdtype != other.rdtype: 22433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck return True 22533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck return self._cmp(other) != 0 22633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 22733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck def __lt__(self, other): 22833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck if not isinstance(other, Rdata) or \ 22933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck self.rdclass != other.rdclass or \ 23033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck self.rdtype != other.rdtype: 23133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck return NotImplemented 23233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck return self._cmp(other) < 0 23333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 23433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck def __le__(self, other): 23533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck if not isinstance(other, Rdata) or \ 23633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck self.rdclass != other.rdclass or \ 23733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck self.rdtype != other.rdtype: 23833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck return NotImplemented 23933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck return self._cmp(other) <= 0 24033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 24133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck def __ge__(self, other): 24233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck if not isinstance(other, Rdata) or \ 24333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck self.rdclass != other.rdclass or \ 24433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck self.rdtype != other.rdtype: 24533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck return NotImplemented 24633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck return self._cmp(other) >= 0 24733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 24833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck def __gt__(self, other): 24933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck if not isinstance(other, Rdata) or \ 25033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck self.rdclass != other.rdclass or \ 25133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck self.rdtype != other.rdtype: 25233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck return NotImplemented 25333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck return self._cmp(other) > 0 25433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 25533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True): 25633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck """Build an rdata object from text format. 25733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 25833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck @param rdclass: The rdata class 25933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck @type rdclass: int 26033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck @param rdtype: The rdata type 26133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck @type rdtype: int 26233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck @param tok: The tokenizer 26333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck @type tok: dns.tokenizer.Tokenizer 26433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck @param origin: The origin to use for relative names 26533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck @type origin: dns.name.Name 26633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck @param relativize: should names be relativized? 26733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck @type relativize: bool 26833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck @rtype: dns.rdata.Rdata instance 26933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck """ 27033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 27133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck raise NotImplementedError 27233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 27333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck from_text = classmethod(from_text) 27433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 27533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None): 27633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck """Build an rdata object from wire format 27733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 27833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck @param rdclass: The rdata class 27933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck @type rdclass: int 28033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck @param rdtype: The rdata type 28133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck @type rdtype: int 28233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck @param wire: The wire-format message 28333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck @type wire: string 28433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck @param current: The offet in wire of the beginning of the rdata. 28533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck @type current: int 28633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck @param rdlen: The length of the wire-format rdata 28733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck @type rdlen: int 28833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck @param origin: The origin to use for relative names 28933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck @type origin: dns.name.Name 29033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck @rtype: dns.rdata.Rdata instance 29133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck """ 29233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 29333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck raise NotImplementedError 29433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 29533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck from_wire = classmethod(from_wire) 29633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 29733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck def choose_relativity(self, origin = None, relativize = True): 29833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck """Convert any domain names in the rdata to the specified 29933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck relativization. 30033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck """ 30133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 30233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck pass 30333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 30433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 30533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reckclass GenericRdata(Rdata): 30633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck """Generate Rdata Class 30733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 30833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck This class is used for rdata types for which we have no better 30933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck implementation. It implements the DNS "unknown RRs" scheme. 31033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck """ 31133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 31233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck __slots__ = ['data'] 31333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 31433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck def __init__(self, rdclass, rdtype, data): 31533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck super(GenericRdata, self).__init__(rdclass, rdtype) 31633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck self.data = data 31733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 31833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck def to_text(self, origin=None, relativize=True, **kw): 31933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck return r'\# %d ' % len(self.data) + _hexify(self.data) 32033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 32133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True): 32233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck token = tok.get() 32333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck if not token.is_identifier() or token.value != '\#': 32433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck raise dns.exception.SyntaxError(r'generic rdata does not start with \#') 32533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck length = tok.get_int() 32633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck chunks = [] 32733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck while 1: 32833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck token = tok.get() 32933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck if token.is_eol_or_eof(): 33033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck break 33133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck chunks.append(token.value) 33233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck hex = ''.join(chunks) 33333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck data = hex.decode('hex_codec') 33433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck if len(data) != length: 33533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck raise dns.exception.SyntaxError('generic rdata hex data has wrong length') 33633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck return cls(rdclass, rdtype, data) 33733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 33833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck from_text = classmethod(from_text) 33933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 34033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck def to_wire(self, file, compress = None, origin = None): 34133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck file.write(self.data) 34233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 34333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None): 34433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck return cls(rdclass, rdtype, wire[current : current + rdlen]) 34533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 34633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck from_wire = classmethod(from_wire) 34733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 34833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck def _cmp(self, other): 34933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck return cmp(self.data, other.data) 35033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 35133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck_rdata_modules = {} 35233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck_module_prefix = 'dns.rdtypes' 35333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 35433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reckdef get_rdata_class(rdclass, rdtype): 35533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 35633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck def import_module(name): 35733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck mod = __import__(name) 35833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck components = name.split('.') 35933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck for comp in components[1:]: 36033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck mod = getattr(mod, comp) 36133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck return mod 36233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 36333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck mod = _rdata_modules.get((rdclass, rdtype)) 36433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck rdclass_text = dns.rdataclass.to_text(rdclass) 36533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck rdtype_text = dns.rdatatype.to_text(rdtype) 36633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck rdtype_text = rdtype_text.replace('-', '_') 36733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck if not mod: 36833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck mod = _rdata_modules.get((dns.rdatatype.ANY, rdtype)) 36933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck if not mod: 37033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck try: 37133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck mod = import_module('.'.join([_module_prefix, 37233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck rdclass_text, rdtype_text])) 37333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck _rdata_modules[(rdclass, rdtype)] = mod 37433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck except ImportError: 37533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck try: 37633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck mod = import_module('.'.join([_module_prefix, 37733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 'ANY', rdtype_text])) 37833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck _rdata_modules[(dns.rdataclass.ANY, rdtype)] = mod 37933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck except ImportError: 38033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck mod = None 38133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck if mod: 38233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck cls = getattr(mod, rdtype_text) 38333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck else: 38433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck cls = GenericRdata 38533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck return cls 38633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 38733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reckdef from_text(rdclass, rdtype, tok, origin = None, relativize = True): 38833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck """Build an rdata object from text format. 38933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 39033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck This function attempts to dynamically load a class which 39133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck implements the specified rdata class and type. If there is no 39233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck class-and-type-specific implementation, the GenericRdata class 39333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck is used. 39433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 39533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck Once a class is chosen, its from_text() class method is called 39633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck with the parameters to this function. 39733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 39833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck @param rdclass: The rdata class 39933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck @type rdclass: int 40033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck @param rdtype: The rdata type 40133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck @type rdtype: int 40233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck @param tok: The tokenizer 40333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck @type tok: dns.tokenizer.Tokenizer 40433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck @param origin: The origin to use for relative names 40533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck @type origin: dns.name.Name 40633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck @param relativize: Should names be relativized? 40733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck @type relativize: bool 40833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck @rtype: dns.rdata.Rdata instance""" 40933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 41033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck if isinstance(tok, str): 41133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck tok = dns.tokenizer.Tokenizer(tok) 41233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck cls = get_rdata_class(rdclass, rdtype) 41333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck if cls != GenericRdata: 41433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck # peek at first token 41533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck token = tok.get() 41633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck tok.unget(token) 41733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck if token.is_identifier() and \ 41833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck token.value == r'\#': 41933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck # 42033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck # Known type using the generic syntax. Extract the 42133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck # wire form from the generic syntax, and then run 42233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck # from_wire on it. 42333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck # 42433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck rdata = GenericRdata.from_text(rdclass, rdtype, tok, origin, 42533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck relativize) 42633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck return from_wire(rdclass, rdtype, rdata.data, 0, len(rdata.data), 42733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck origin) 42833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck return cls.from_text(rdclass, rdtype, tok, origin, relativize) 42933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 43033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reckdef from_wire(rdclass, rdtype, wire, current, rdlen, origin = None): 43133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck """Build an rdata object from wire format 43233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 43333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck This function attempts to dynamically load a class which 43433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck implements the specified rdata class and type. If there is no 43533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck class-and-type-specific implementation, the GenericRdata class 43633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck is used. 43733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 43833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck Once a class is chosen, its from_wire() class method is called 43933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck with the parameters to this function. 44033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 44133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck @param rdclass: The rdata class 44233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck @type rdclass: int 44333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck @param rdtype: The rdata type 44433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck @type rdtype: int 44533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck @param wire: The wire-format message 44633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck @type wire: string 44733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck @param current: The offet in wire of the beginning of the rdata. 44833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck @type current: int 44933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck @param rdlen: The length of the wire-format rdata 45033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck @type rdlen: int 45133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck @param origin: The origin to use for relative names 45233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck @type origin: dns.name.Name 45333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck @rtype: dns.rdata.Rdata instance""" 45433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 45533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck cls = get_rdata_class(rdclass, rdtype) 45633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck return cls.from_wire(rdclass, rdtype, wire, current, rdlen, origin) 457