diff options
Diffstat (limited to 'lib/dnspython/dns/rdtypes/IN')
-rw-r--r-- | lib/dnspython/dns/rdtypes/IN/A.py | 57 | ||||
-rw-r--r-- | lib/dnspython/dns/rdtypes/IN/AAAA.py | 58 | ||||
-rw-r--r-- | lib/dnspython/dns/rdtypes/IN/APL.py | 170 | ||||
-rw-r--r-- | lib/dnspython/dns/rdtypes/IN/DHCID.py | 60 | ||||
-rw-r--r-- | lib/dnspython/dns/rdtypes/IN/IPSECKEY.py | 159 | ||||
-rw-r--r-- | lib/dnspython/dns/rdtypes/IN/KX.py | 20 | ||||
-rw-r--r-- | lib/dnspython/dns/rdtypes/IN/NAPTR.py | 132 | ||||
-rw-r--r-- | lib/dnspython/dns/rdtypes/IN/NSAP.py | 59 | ||||
-rw-r--r-- | lib/dnspython/dns/rdtypes/IN/NSAP_PTR.py | 20 | ||||
-rw-r--r-- | lib/dnspython/dns/rdtypes/IN/PX.py | 97 | ||||
-rw-r--r-- | lib/dnspython/dns/rdtypes/IN/SRV.py | 89 | ||||
-rw-r--r-- | lib/dnspython/dns/rdtypes/IN/WKS.py | 113 | ||||
-rw-r--r-- | lib/dnspython/dns/rdtypes/IN/__init__.py | 30 |
13 files changed, 1064 insertions, 0 deletions
diff --git a/lib/dnspython/dns/rdtypes/IN/A.py b/lib/dnspython/dns/rdtypes/IN/A.py new file mode 100644 index 0000000000..e05f204a2f --- /dev/null +++ b/lib/dnspython/dns/rdtypes/IN/A.py @@ -0,0 +1,57 @@ +# Copyright (C) 2003-2007, 2009, 2010 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +import dns.exception +import dns.ipv4 +import dns.rdata +import dns.tokenizer + +class A(dns.rdata.Rdata): + """A record. + + @ivar address: an IPv4 address + @type address: string (in the standard "dotted quad" format)""" + + __slots__ = ['address'] + + def __init__(self, rdclass, rdtype, address): + super(A, self).__init__(rdclass, rdtype) + # check that it's OK + junk = dns.ipv4.inet_aton(address) + self.address = address + + def to_text(self, origin=None, relativize=True, **kw): + return self.address + + def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True): + address = tok.get_identifier() + tok.get_eol() + return cls(rdclass, rdtype, address) + + from_text = classmethod(from_text) + + def to_wire(self, file, compress = None, origin = None): + file.write(dns.ipv4.inet_aton(self.address)) + + def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None): + address = dns.ipv4.inet_ntoa(wire[current : current + rdlen]) + return cls(rdclass, rdtype, address) + + from_wire = classmethod(from_wire) + + def _cmp(self, other): + sa = dns.ipv4.inet_aton(self.address) + oa = dns.ipv4.inet_aton(other.address) + return cmp(sa, oa) diff --git a/lib/dnspython/dns/rdtypes/IN/AAAA.py b/lib/dnspython/dns/rdtypes/IN/AAAA.py new file mode 100644 index 0000000000..2d812d39eb --- /dev/null +++ b/lib/dnspython/dns/rdtypes/IN/AAAA.py @@ -0,0 +1,58 @@ +# Copyright (C) 2003-2007, 2009, 2010 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +import dns.exception +import dns.inet +import dns.rdata +import dns.tokenizer + +class AAAA(dns.rdata.Rdata): + """AAAA record. + + @ivar address: an IPv6 address + @type address: string (in the standard IPv6 format)""" + + __slots__ = ['address'] + + def __init__(self, rdclass, rdtype, address): + super(AAAA, self).__init__(rdclass, rdtype) + # check that it's OK + junk = dns.inet.inet_pton(dns.inet.AF_INET6, address) + self.address = address + + def to_text(self, origin=None, relativize=True, **kw): + return self.address + + def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True): + address = tok.get_identifier() + tok.get_eol() + return cls(rdclass, rdtype, address) + + from_text = classmethod(from_text) + + def to_wire(self, file, compress = None, origin = None): + file.write(dns.inet.inet_pton(dns.inet.AF_INET6, self.address)) + + def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None): + address = dns.inet.inet_ntop(dns.inet.AF_INET6, + wire[current : current + rdlen]) + return cls(rdclass, rdtype, address) + + from_wire = classmethod(from_wire) + + def _cmp(self, other): + sa = dns.inet.inet_pton(dns.inet.AF_INET6, self.address) + oa = dns.inet.inet_pton(dns.inet.AF_INET6, other.address) + return cmp(sa, oa) diff --git a/lib/dnspython/dns/rdtypes/IN/APL.py b/lib/dnspython/dns/rdtypes/IN/APL.py new file mode 100644 index 0000000000..7412c02d30 --- /dev/null +++ b/lib/dnspython/dns/rdtypes/IN/APL.py @@ -0,0 +1,170 @@ +# Copyright (C) 2003-2007, 2009, 2010 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +import cStringIO +import struct + +import dns.exception +import dns.inet +import dns.rdata +import dns.tokenizer + +class APLItem(object): + """An APL list item. + + @ivar family: the address family (IANA address family registry) + @type family: int + @ivar negation: is this item negated? + @type negation: bool + @ivar address: the address + @type address: string + @ivar prefix: the prefix length + @type prefix: int + """ + + __slots__ = ['family', 'negation', 'address', 'prefix'] + + def __init__(self, family, negation, address, prefix): + self.family = family + self.negation = negation + self.address = address + self.prefix = prefix + + def __str__(self): + if self.negation: + return "!%d:%s/%s" % (self.family, self.address, self.prefix) + else: + return "%d:%s/%s" % (self.family, self.address, self.prefix) + + def to_wire(self, file): + if self.family == 1: + address = dns.inet.inet_pton(dns.inet.AF_INET, self.address) + elif self.family == 2: + address = dns.inet.inet_pton(dns.inet.AF_INET6, self.address) + else: + address = self.address.decode('hex_codec') + # + # Truncate least significant zero bytes. + # + last = 0 + for i in xrange(len(address) - 1, -1, -1): + if address[i] != chr(0): + last = i + 1 + break + address = address[0 : last] + l = len(address) + assert l < 128 + if self.negation: + l |= 0x80 + header = struct.pack('!HBB', self.family, self.prefix, l) + file.write(header) + file.write(address) + +class APL(dns.rdata.Rdata): + """APL record. + + @ivar items: a list of APL items + @type items: list of APL_Item + @see: RFC 3123""" + + __slots__ = ['items'] + + def __init__(self, rdclass, rdtype, items): + super(APL, self).__init__(rdclass, rdtype) + self.items = items + + def to_text(self, origin=None, relativize=True, **kw): + return ' '.join(map(lambda x: str(x), self.items)) + + def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True): + items = [] + while 1: + token = tok.get().unescape() + if token.is_eol_or_eof(): + break + item = token.value + if item[0] == '!': + negation = True + item = item[1:] + else: + negation = False + (family, rest) = item.split(':', 1) + family = int(family) + (address, prefix) = rest.split('/', 1) + prefix = int(prefix) + item = APLItem(family, negation, address, prefix) + items.append(item) + + return cls(rdclass, rdtype, items) + + from_text = classmethod(from_text) + + def to_wire(self, file, compress = None, origin = None): + for item in self.items: + item.to_wire(file) + + def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None): + items = [] + while 1: + if rdlen < 4: + raise dns.exception.FormError + header = struct.unpack('!HBB', wire[current : current + 4]) + afdlen = header[2] + if afdlen > 127: + negation = True + afdlen -= 128 + else: + negation = False + current += 4 + rdlen -= 4 + if rdlen < afdlen: + raise dns.exception.FormError + address = wire[current : current + afdlen] + l = len(address) + if header[0] == 1: + if l < 4: + address += '\x00' * (4 - l) + address = dns.inet.inet_ntop(dns.inet.AF_INET, address) + elif header[0] == 2: + if l < 16: + address += '\x00' * (16 - l) + address = dns.inet.inet_ntop(dns.inet.AF_INET6, address) + else: + # + # This isn't really right according to the RFC, but it + # seems better than throwing an exception + # + address = address.encode('hex_codec') + current += afdlen + rdlen -= afdlen + item = APLItem(header[0], negation, address, header[1]) + items.append(item) + if rdlen == 0: + break + return cls(rdclass, rdtype, items) + + from_wire = classmethod(from_wire) + + def _cmp(self, other): + f = cStringIO.StringIO() + self.to_wire(f) + wire1 = f.getvalue() + f.seek(0) + f.truncate() + other.to_wire(f) + wire2 = f.getvalue() + f.close() + + return cmp(wire1, wire2) diff --git a/lib/dnspython/dns/rdtypes/IN/DHCID.py b/lib/dnspython/dns/rdtypes/IN/DHCID.py new file mode 100644 index 0000000000..2d35234bf0 --- /dev/null +++ b/lib/dnspython/dns/rdtypes/IN/DHCID.py @@ -0,0 +1,60 @@ +# Copyright (C) 2006, 2007, 2009, 2010 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +import dns.exception + +class DHCID(dns.rdata.Rdata): + """DHCID record + + @ivar data: the data (the content of the RR is opaque as far as the + DNS is concerned) + @type data: string + @see: RFC 4701""" + + __slots__ = ['data'] + + def __init__(self, rdclass, rdtype, data): + super(DHCID, self).__init__(rdclass, rdtype) + self.data = data + + def to_text(self, origin=None, relativize=True, **kw): + return dns.rdata._base64ify(self.data) + + def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True): + chunks = [] + while 1: + t = tok.get().unescape() + if t.is_eol_or_eof(): + break + if not t.is_identifier(): + raise dns.exception.SyntaxError + chunks.append(t.value) + b64 = ''.join(chunks) + data = b64.decode('base64_codec') + return cls(rdclass, rdtype, data) + + from_text = classmethod(from_text) + + def to_wire(self, file, compress = None, origin = None): + file.write(self.data) + + def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None): + data = wire[current : current + rdlen] + return cls(rdclass, rdtype, data) + + from_wire = classmethod(from_wire) + + def _cmp(self, other): + return cmp(self.data, other.data) diff --git a/lib/dnspython/dns/rdtypes/IN/IPSECKEY.py b/lib/dnspython/dns/rdtypes/IN/IPSECKEY.py new file mode 100644 index 0000000000..9ab08d881c --- /dev/null +++ b/lib/dnspython/dns/rdtypes/IN/IPSECKEY.py @@ -0,0 +1,159 @@ +# Copyright (C) 2006, 2007, 2009, 2010 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +import cStringIO +import struct + +import dns.exception +import dns.inet +import dns.name + +class IPSECKEY(dns.rdata.Rdata): + """IPSECKEY record + + @ivar precedence: the precedence for this key data + @type precedence: int + @ivar gateway_type: the gateway type + @type gateway_type: int + @ivar algorithm: the algorithm to use + @type algorithm: int + @ivar gateway: the public key + @type gateway: None, IPv4 address, IPV6 address, or domain name + @ivar key: the public key + @type key: string + @see: RFC 4025""" + + __slots__ = ['precedence', 'gateway_type', 'algorithm', 'gateway', 'key'] + + def __init__(self, rdclass, rdtype, precedence, gateway_type, algorithm, + gateway, key): + super(IPSECKEY, self).__init__(rdclass, rdtype) + if gateway_type == 0: + if gateway != '.' and not gateway is None: + raise SyntaxError('invalid gateway for gateway type 0') + gateway = None + elif gateway_type == 1: + # check that it's OK + junk = dns.inet.inet_pton(dns.inet.AF_INET, gateway) + elif gateway_type == 2: + # check that it's OK + junk = dns.inet.inet_pton(dns.inet.AF_INET6, gateway) + elif gateway_type == 3: + pass + else: + raise SyntaxError('invalid IPSECKEY gateway type: %d' % gateway_type) + self.precedence = precedence + self.gateway_type = gateway_type + self.algorithm = algorithm + self.gateway = gateway + self.key = key + + def to_text(self, origin=None, relativize=True, **kw): + if self.gateway_type == 0: + gateway = '.' + elif self.gateway_type == 1: + gateway = self.gateway + elif self.gateway_type == 2: + gateway = self.gateway + elif self.gateway_type == 3: + gateway = str(self.gateway.choose_relativity(origin, relativize)) + else: + raise ValueError('invalid gateway type') + return '%d %d %d %s %s' % (self.precedence, self.gateway_type, + self.algorithm, gateway, + dns.rdata._base64ify(self.key)) + + def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True): + precedence = tok.get_uint8() + gateway_type = tok.get_uint8() + algorithm = tok.get_uint8() + if gateway_type == 3: + gateway = tok.get_name().choose_relativity(origin, relativize) + else: + gateway = tok.get_string() + chunks = [] + while 1: + t = tok.get().unescape() + if t.is_eol_or_eof(): + break + if not t.is_identifier(): + raise dns.exception.SyntaxError + chunks.append(t.value) + b64 = ''.join(chunks) + key = b64.decode('base64_codec') + return cls(rdclass, rdtype, precedence, gateway_type, algorithm, + gateway, key) + + from_text = classmethod(from_text) + + def to_wire(self, file, compress = None, origin = None): + header = struct.pack("!BBB", self.precedence, self.gateway_type, + self.algorithm) + file.write(header) + if self.gateway_type == 0: + pass + elif self.gateway_type == 1: + file.write(dns.inet.inet_pton(dns.inet.AF_INET, self.gateway)) + elif self.gateway_type == 2: + file.write(dns.inet.inet_pton(dns.inet.AF_INET6, self.gateway)) + elif self.gateway_type == 3: + self.gateway.to_wire(file, None, origin) + else: + raise ValueError('invalid gateway type') + file.write(self.key) + + def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None): + if rdlen < 3: + raise dns.exception.FormError + header = struct.unpack('!BBB', wire[current : current + 3]) + gateway_type = header[1] + current += 3 + rdlen -= 3 + if gateway_type == 0: + gateway = None + elif gateway_type == 1: + gateway = dns.inet.inet_ntop(dns.inet.AF_INET, + wire[current : current + 4]) + current += 4 + rdlen -= 4 + elif gateway_type == 2: + gateway = dns.inet.inet_ntop(dns.inet.AF_INET6, + wire[current : current + 16]) + current += 16 + rdlen -= 16 + elif gateway_type == 3: + (gateway, cused) = dns.name.from_wire(wire[: current + rdlen], + current) + current += cused + rdlen -= cused + else: + raise dns.exception.FormError('invalid IPSECKEY gateway type') + key = wire[current : current + rdlen] + return cls(rdclass, rdtype, header[0], gateway_type, header[2], + gateway, key) + + from_wire = classmethod(from_wire) + + def _cmp(self, other): + f = cStringIO.StringIO() + self.to_wire(f) + wire1 = f.getvalue() + f.seek(0) + f.truncate() + other.to_wire(f) + wire2 = f.getvalue() + f.close() + + return cmp(wire1, wire2) diff --git a/lib/dnspython/dns/rdtypes/IN/KX.py b/lib/dnspython/dns/rdtypes/IN/KX.py new file mode 100644 index 0000000000..4d8a3a7d6b --- /dev/null +++ b/lib/dnspython/dns/rdtypes/IN/KX.py @@ -0,0 +1,20 @@ +# Copyright (C) 2003-2007, 2009, 2010 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +import dns.rdtypes.mxbase + +class KX(dns.rdtypes.mxbase.UncompressedMX): + """KX record""" + pass diff --git a/lib/dnspython/dns/rdtypes/IN/NAPTR.py b/lib/dnspython/dns/rdtypes/IN/NAPTR.py new file mode 100644 index 0000000000..3a30d16d7b --- /dev/null +++ b/lib/dnspython/dns/rdtypes/IN/NAPTR.py @@ -0,0 +1,132 @@ +# Copyright (C) 2003-2007, 2009, 2010 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +import struct + +import dns.exception +import dns.name +import dns.rdata + +def _write_string(file, s): + l = len(s) + assert l < 256 + byte = chr(l) + file.write(byte) + file.write(s) + +class NAPTR(dns.rdata.Rdata): + """NAPTR record + + @ivar order: order + @type order: int + @ivar preference: preference + @type preference: int + @ivar flags: flags + @type flags: string + @ivar service: service + @type service: string + @ivar regexp: regular expression + @type regexp: string + @ivar replacement: replacement name + @type replacement: dns.name.Name object + @see: RFC 3403""" + + __slots__ = ['order', 'preference', 'flags', 'service', 'regexp', + 'replacement'] + + def __init__(self, rdclass, rdtype, order, preference, flags, service, + regexp, replacement): + super(NAPTR, self).__init__(rdclass, rdtype) + self.order = order + self.preference = preference + self.flags = flags + self.service = service + self.regexp = regexp + self.replacement = replacement + + def to_text(self, origin=None, relativize=True, **kw): + replacement = self.replacement.choose_relativity(origin, relativize) + return '%d %d "%s" "%s" "%s" %s' % \ + (self.order, self.preference, + dns.rdata._escapify(self.flags), + dns.rdata._escapify(self.service), + dns.rdata._escapify(self.regexp), + self.replacement) + + def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True): + order = tok.get_uint16() + preference = tok.get_uint16() + flags = tok.get_string() + service = tok.get_string() + regexp = tok.get_string() + replacement = tok.get_name() + replacement = replacement.choose_relativity(origin, relativize) + tok.get_eol() + return cls(rdclass, rdtype, order, preference, flags, service, + regexp, replacement) + + from_text = classmethod(from_text) + + def to_wire(self, file, compress = None, origin = None): + two_ints = struct.pack("!HH", self.order, self.preference) + file.write(two_ints) + _write_string(file, self.flags) + _write_string(file, self.service) + _write_string(file, self.regexp) + self.replacement.to_wire(file, compress, origin) + + def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None): + (order, preference) = struct.unpack('!HH', wire[current : current + 4]) + current += 4 + rdlen -= 4 + strings = [] + for i in xrange(3): + l = ord(wire[current]) + current += 1 + rdlen -= 1 + if l > rdlen or rdlen < 0: + raise dns.exception.FormError + s = wire[current : current + l] + current += l + rdlen -= l + strings.append(s) + (replacement, cused) = dns.name.from_wire(wire[: current + rdlen], + current) + if cused != rdlen: + raise dns.exception.FormError + if not origin is None: + replacement = replacement.relativize(origin) + return cls(rdclass, rdtype, order, preference, strings[0], strings[1], + strings[2], replacement) + + from_wire = classmethod(from_wire) + + def choose_relativity(self, origin = None, relativize = True): + self.replacement = self.replacement.choose_relativity(origin, + relativize) + + def _cmp(self, other): + sp = struct.pack("!HH", self.order, self.preference) + op = struct.pack("!HH", other.order, other.preference) + v = cmp(sp, op) + if v == 0: + v = cmp(self.flags, other.flags) + if v == 0: + v = cmp(self.service, other.service) + if v == 0: + v = cmp(self.regexp, other.regexp) + if v == 0: + v = cmp(self.replacement, other.replacement) + return v diff --git a/lib/dnspython/dns/rdtypes/IN/NSAP.py b/lib/dnspython/dns/rdtypes/IN/NSAP.py new file mode 100644 index 0000000000..22b9131ccf --- /dev/null +++ b/lib/dnspython/dns/rdtypes/IN/NSAP.py @@ -0,0 +1,59 @@ +# Copyright (C) 2003-2007, 2009, 2010 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +import dns.exception +import dns.rdata +import dns.tokenizer + +class NSAP(dns.rdata.Rdata): + """NSAP record. + + @ivar address: a NASP + @type address: string + @see: RFC 1706""" + + __slots__ = ['address'] + + def __init__(self, rdclass, rdtype, address): + super(NSAP, self).__init__(rdclass, rdtype) + self.address = address + + def to_text(self, origin=None, relativize=True, **kw): + return "0x%s" % self.address.encode('hex_codec') + + def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True): + address = tok.get_string() + t = tok.get_eol() + if address[0:2] != '0x': + raise dns.exception.SyntaxError('string does not start with 0x') + address = address[2:].replace('.', '') + if len(address) % 2 != 0: + raise dns.exception.SyntaxError('hexstring has odd length') + address = address.decode('hex_codec') + return cls(rdclass, rdtype, address) + + from_text = classmethod(from_text) + + def to_wire(self, file, compress = None, origin = None): + file.write(self.address) + + def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None): + address = wire[current : current + rdlen] + return cls(rdclass, rdtype, address) + + from_wire = classmethod(from_wire) + + def _cmp(self, other): + return cmp(self.address, other.address) diff --git a/lib/dnspython/dns/rdtypes/IN/NSAP_PTR.py b/lib/dnspython/dns/rdtypes/IN/NSAP_PTR.py new file mode 100644 index 0000000000..6f591f4ec0 --- /dev/null +++ b/lib/dnspython/dns/rdtypes/IN/NSAP_PTR.py @@ -0,0 +1,20 @@ +# Copyright (C) 2003-2007, 2009, 2010 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +import dns.rdtypes.nsbase + +class NSAP_PTR(dns.rdtypes.nsbase.UncompressedNS): + """NSAP-PTR record""" + pass diff --git a/lib/dnspython/dns/rdtypes/IN/PX.py b/lib/dnspython/dns/rdtypes/IN/PX.py new file mode 100644 index 0000000000..4718944ff4 --- /dev/null +++ b/lib/dnspython/dns/rdtypes/IN/PX.py @@ -0,0 +1,97 @@ +# Copyright (C) 2003-2007, 2009, 2010 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +import struct + +import dns.exception +import dns.rdata +import dns.name + +class PX(dns.rdata.Rdata): + """PX record. + + @ivar preference: the preference value + @type preference: int + @ivar map822: the map822 name + @type map822: dns.name.Name object + @ivar mapx400: the mapx400 name + @type mapx400: dns.name.Name object + @see: RFC 2163""" + + __slots__ = ['preference', 'map822', 'mapx400'] + + def __init__(self, rdclass, rdtype, preference, map822, mapx400): + super(PX, self).__init__(rdclass, rdtype) + self.preference = preference + self.map822 = map822 + self.mapx400 = mapx400 + + def to_text(self, origin=None, relativize=True, **kw): + map822 = self.map822.choose_relativity(origin, relativize) + mapx400 = self.mapx400.choose_relativity(origin, relativize) + return '%d %s %s' % (self.preference, map822, mapx400) + + def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True): + preference = tok.get_uint16() + map822 = tok.get_name() + map822 = map822.choose_relativity(origin, relativize) + mapx400 = tok.get_name(None) + mapx400 = mapx400.choose_relativity(origin, relativize) + tok.get_eol() + return cls(rdclass, rdtype, preference, map822, mapx400) + + from_text = classmethod(from_text) + + def to_wire(self, file, compress = None, origin = None): + pref = struct.pack("!H", self.preference) + file.write(pref) + self.map822.to_wire(file, None, origin) + self.mapx400.to_wire(file, None, origin) + + def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None): + (preference, ) = struct.unpack('!H', wire[current : current + 2]) + current += 2 + rdlen -= 2 + (map822, cused) = dns.name.from_wire(wire[: current + rdlen], + current) + if cused > rdlen: + raise dns.exception.FormError + current += cused + rdlen -= cused + if not origin is None: + map822 = map822.relativize(origin) + (mapx400, cused) = dns.name.from_wire(wire[: current + rdlen], + current) + if cused != rdlen: + raise dns.exception.FormError + if not origin is None: + mapx400 = mapx400.relativize(origin) + return cls(rdclass, rdtype, preference, map822, mapx400) + + from_wire = classmethod(from_wire) + + def choose_relativity(self, origin = None, relativize = True): + self.map822 = self.map822.choose_relativity(origin, relativize) + self.mapx400 = self.mapx400.choose_relativity(origin, relativize) + + def _cmp(self, other): + sp = struct.pack("!H", self.preference) + op = struct.pack("!H", other.preference) + v = cmp(sp, op) + if v == 0: + v = cmp(self.map822, other.map822) + if v == 0: + v = cmp(self.mapx400, other.mapx400) + return v diff --git a/lib/dnspython/dns/rdtypes/IN/SRV.py b/lib/dnspython/dns/rdtypes/IN/SRV.py new file mode 100644 index 0000000000..c9c5823381 --- /dev/null +++ b/lib/dnspython/dns/rdtypes/IN/SRV.py @@ -0,0 +1,89 @@ +# Copyright (C) 2003-2007, 2009, 2010 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +import struct + +import dns.exception +import dns.rdata +import dns.name + +class SRV(dns.rdata.Rdata): + """SRV record + + @ivar priority: the priority + @type priority: int + @ivar weight: the weight + @type weight: int + @ivar port: the port of the service + @type port: int + @ivar target: the target host + @type target: dns.name.Name object + @see: RFC 2782""" + + __slots__ = ['priority', 'weight', 'port', 'target'] + + def __init__(self, rdclass, rdtype, priority, weight, port, target): + super(SRV, self).__init__(rdclass, rdtype) + self.priority = priority + self.weight = weight + self.port = port + self.target = target + + def to_text(self, origin=None, relativize=True, **kw): + target = self.target.choose_relativity(origin, relativize) + return '%d %d %d %s' % (self.priority, self.weight, self.port, + target) + + def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True): + priority = tok.get_uint16() + weight = tok.get_uint16() + port = tok.get_uint16() + target = tok.get_name(None) + target = target.choose_relativity(origin, relativize) + tok.get_eol() + return cls(rdclass, rdtype, priority, weight, port, target) + + from_text = classmethod(from_text) + + def to_wire(self, file, compress = None, origin = None): + three_ints = struct.pack("!HHH", self.priority, self.weight, self.port) + file.write(three_ints) + self.target.to_wire(file, compress, origin) + + def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None): + (priority, weight, port) = struct.unpack('!HHH', + wire[current : current + 6]) + current += 6 + rdlen -= 6 + (target, cused) = dns.name.from_wire(wire[: current + rdlen], + current) + if cused != rdlen: + raise dns.exception.FormError + if not origin is None: + target = target.relativize(origin) + return cls(rdclass, rdtype, priority, weight, port, target) + + from_wire = classmethod(from_wire) + + def choose_relativity(self, origin = None, relativize = True): + self.target = self.target.choose_relativity(origin, relativize) + + def _cmp(self, other): + sp = struct.pack("!HHH", self.priority, self.weight, self.port) + op = struct.pack("!HHH", other.priority, other.weight, other.port) + v = cmp(sp, op) + if v == 0: + v = cmp(self.target, other.target) + return v diff --git a/lib/dnspython/dns/rdtypes/IN/WKS.py b/lib/dnspython/dns/rdtypes/IN/WKS.py new file mode 100644 index 0000000000..85aafb3d23 --- /dev/null +++ b/lib/dnspython/dns/rdtypes/IN/WKS.py @@ -0,0 +1,113 @@ +# Copyright (C) 2003-2007, 2009, 2010 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +import socket +import struct + +import dns.ipv4 +import dns.rdata + +_proto_tcp = socket.getprotobyname('tcp') +_proto_udp = socket.getprotobyname('udp') + +class WKS(dns.rdata.Rdata): + """WKS record + + @ivar address: the address + @type address: string + @ivar protocol: the protocol + @type protocol: int + @ivar bitmap: the bitmap + @type bitmap: string + @see: RFC 1035""" + + __slots__ = ['address', 'protocol', 'bitmap'] + + def __init__(self, rdclass, rdtype, address, protocol, bitmap): + super(WKS, self).__init__(rdclass, rdtype) + self.address = address + self.protocol = protocol + self.bitmap = bitmap + + def to_text(self, origin=None, relativize=True, **kw): + bits = [] + for i in xrange(0, len(self.bitmap)): + byte = ord(self.bitmap[i]) + for j in xrange(0, 8): + if byte & (0x80 >> j): + bits.append(str(i * 8 + j)) + text = ' '.join(bits) + return '%s %d %s' % (self.address, self.protocol, text) + + def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True): + address = tok.get_string() + protocol = tok.get_string() + if protocol.isdigit(): + protocol = int(protocol) + else: + protocol = socket.getprotobyname(protocol) + bitmap = [] + while 1: + token = tok.get().unescape() + if token.is_eol_or_eof(): + break + if token.value.isdigit(): + serv = int(token.value) + else: + if protocol != _proto_udp and protocol != _proto_tcp: + raise NotImplementedError("protocol must be TCP or UDP") + if protocol == _proto_udp: + protocol_text = "udp" + else: + protocol_text = "tcp" + serv = socket.getservbyname(token.value, protocol_text) + i = serv // 8 + l = len(bitmap) + if l < i + 1: + for j in xrange(l, i + 1): + bitmap.append('\x00') + bitmap[i] = chr(ord(bitmap[i]) | (0x80 >> (serv % 8))) + bitmap = dns.rdata._truncate_bitmap(bitmap) + return cls(rdclass, rdtype, address, protocol, bitmap) + + from_text = classmethod(from_text) + + def to_wire(self, file, compress = None, origin = None): + file.write(dns.ipv4.inet_aton(self.address)) + protocol = struct.pack('!B', self.protocol) + file.write(protocol) + file.write(self.bitmap) + + def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None): + address = dns.ipv4.inet_ntoa(wire[current : current + 4]) + protocol, = struct.unpack('!B', wire[current + 4 : current + 5]) + current += 5 + rdlen -= 5 + bitmap = wire[current : current + rdlen] + return cls(rdclass, rdtype, address, protocol, bitmap) + + from_wire = classmethod(from_wire) + + def _cmp(self, other): + sa = dns.ipv4.inet_aton(self.address) + oa = dns.ipv4.inet_aton(other.address) + v = cmp(sa, oa) + if v == 0: + sp = struct.pack('!B', self.protocol) + op = struct.pack('!B', other.protocol) + v = cmp(sp, op) + if v == 0: + v = cmp(self.bitmap, other.bitmap) + return v diff --git a/lib/dnspython/dns/rdtypes/IN/__init__.py b/lib/dnspython/dns/rdtypes/IN/__init__.py new file mode 100644 index 0000000000..ab931296ec --- /dev/null +++ b/lib/dnspython/dns/rdtypes/IN/__init__.py @@ -0,0 +1,30 @@ +# Copyright (C) 2003-2007, 2009, 2010 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +"""Class IN rdata type classes.""" + +__all__ = [ + 'A', + 'AAAA', + 'APL', + 'DHCID', + 'KX', + 'NAPTR', + 'NSAP', + 'NSAP_PTR', + 'PX', + 'SRV', + 'WKS', +] |