133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck# Copyright (C) 2003-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 Reckimport struct 1733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 1833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reckimport dns.exception 1933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reckimport dns.name 2033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reckimport dns.rdata 2133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 2233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reckdef _write_string(file, s): 2333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck l = len(s) 2433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck assert l < 256 2533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck byte = chr(l) 2633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck file.write(byte) 2733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck file.write(s) 2833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 2933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reckclass NAPTR(dns.rdata.Rdata): 3033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck """NAPTR record 3133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 3233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck @ivar order: order 3333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck @type order: int 3433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck @ivar preference: preference 3533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck @type preference: int 3633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck @ivar flags: flags 3733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck @type flags: string 3833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck @ivar service: service 3933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck @type service: string 4033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck @ivar regexp: regular expression 4133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck @type regexp: string 4233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck @ivar replacement: replacement name 4333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck @type replacement: dns.name.Name object 4433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck @see: RFC 3403""" 4533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 4633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck __slots__ = ['order', 'preference', 'flags', 'service', 'regexp', 4733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 'replacement'] 4833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 4933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck def __init__(self, rdclass, rdtype, order, preference, flags, service, 5033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck regexp, replacement): 5133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck super(NAPTR, self).__init__(rdclass, rdtype) 5233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck self.order = order 5333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck self.preference = preference 5433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck self.flags = flags 5533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck self.service = service 5633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck self.regexp = regexp 5733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck self.replacement = replacement 5833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 5933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck def to_text(self, origin=None, relativize=True, **kw): 6033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck replacement = self.replacement.choose_relativity(origin, relativize) 6133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck return '%d %d "%s" "%s" "%s" %s' % \ 6233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck (self.order, self.preference, 6333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck dns.rdata._escapify(self.flags), 6433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck dns.rdata._escapify(self.service), 6533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck dns.rdata._escapify(self.regexp), 6633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck self.replacement) 6733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 6833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True): 6933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck order = tok.get_uint16() 7033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck preference = tok.get_uint16() 7133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck flags = tok.get_string() 7233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck service = tok.get_string() 7333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck regexp = tok.get_string() 7433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck replacement = tok.get_name() 7533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck replacement = replacement.choose_relativity(origin, relativize) 7633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck tok.get_eol() 7733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck return cls(rdclass, rdtype, order, preference, flags, service, 7833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck regexp, replacement) 7933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 8033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck from_text = classmethod(from_text) 8133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 8233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck def to_wire(self, file, compress = None, origin = None): 8333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck two_ints = struct.pack("!HH", self.order, self.preference) 8433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck file.write(two_ints) 8533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck _write_string(file, self.flags) 8633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck _write_string(file, self.service) 8733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck _write_string(file, self.regexp) 8833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck self.replacement.to_wire(file, compress, origin) 8933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 9033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None): 9133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck (order, preference) = struct.unpack('!HH', wire[current : current + 4]) 9233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck current += 4 9333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck rdlen -= 4 9433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck strings = [] 9533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck for i in xrange(3): 9633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck l = ord(wire[current]) 9733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck current += 1 9833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck rdlen -= 1 9933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck if l > rdlen or rdlen < 0: 10033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck raise dns.exception.FormError 10133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck s = wire[current : current + l] 10233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck current += l 10333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck rdlen -= l 10433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck strings.append(s) 10533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck (replacement, cused) = dns.name.from_wire(wire[: current + rdlen], 10633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck current) 10733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck if cused != rdlen: 10833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck raise dns.exception.FormError 10933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck if not origin is None: 11033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck replacement = replacement.relativize(origin) 11133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck return cls(rdclass, rdtype, order, preference, strings[0], strings[1], 11233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck strings[2], replacement) 11333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 11433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck from_wire = classmethod(from_wire) 11533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 11633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck def choose_relativity(self, origin = None, relativize = True): 11733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck self.replacement = self.replacement.choose_relativity(origin, 11833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck relativize) 11933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 12033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck def _cmp(self, other): 12133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck sp = struct.pack("!HH", self.order, self.preference) 12233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck op = struct.pack("!HH", other.order, other.preference) 12333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck v = cmp(sp, op) 12433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck if v == 0: 12533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck v = cmp(self.flags, other.flags) 12633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck if v == 0: 12733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck v = cmp(self.service, other.service) 12833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck if v == 0: 12933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck v = cmp(self.regexp, other.regexp) 13033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck if v == 0: 13133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck v = cmp(self.replacement, other.replacement) 13233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck return v 133