Package dns :: Package rdtypes :: Package ANY :: Module NSEC
[hide private]
[frames] | no frames]

Source Code for Module dns.rdtypes.ANY.NSEC

  1  # Copyright (C) 2004-2007, 2009-2011 Nominum, Inc. 
  2  # 
  3  # Permission to use, copy, modify, and distribute this software and its 
  4  # documentation for any purpose with or without fee is hereby granted, 
  5  # provided that the above copyright notice and this permission notice 
  6  # appear in all copies. 
  7  # 
  8  # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES 
  9  # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 
 10  # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR 
 11  # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 
 12  # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 
 13  # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 
 14  # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 
 15   
 16  import struct 
 17   
 18  import dns.exception 
 19  import dns.rdata 
 20  import dns.rdatatype 
 21  import dns.name 
 22  from dns._compat import xrange 
23 24 25 -class NSEC(dns.rdata.Rdata):
26 27 """NSEC record 28 29 @ivar next: the next name 30 @type next: dns.name.Name object 31 @ivar windows: the windowed bitmap list 32 @type windows: list of (window number, string) tuples""" 33 34 __slots__ = ['next', 'windows'] 35
36 - def __init__(self, rdclass, rdtype, next, windows):
37 super(NSEC, self).__init__(rdclass, rdtype) 38 self.next = next 39 self.windows = windows
40
41 - def to_text(self, origin=None, relativize=True, **kw):
42 next = self.next.choose_relativity(origin, relativize) 43 text = '' 44 for (window, bitmap) in self.windows: 45 bits = [] 46 for i in xrange(0, len(bitmap)): 47 byte = bitmap[i] 48 for j in xrange(0, 8): 49 if byte & (0x80 >> j): 50 bits.append(dns.rdatatype.to_text(window * 256 + 51 i * 8 + j)) 52 text += (' ' + ' '.join(bits)) 53 return '%s%s' % (next, text)
54 55 @classmethod
56 - def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True):
57 next = tok.get_name() 58 next = next.choose_relativity(origin, relativize) 59 rdtypes = [] 60 while 1: 61 token = tok.get().unescape() 62 if token.is_eol_or_eof(): 63 break 64 nrdtype = dns.rdatatype.from_text(token.value) 65 if nrdtype == 0: 66 raise dns.exception.SyntaxError("NSEC with bit 0") 67 if nrdtype > 65535: 68 raise dns.exception.SyntaxError("NSEC with bit > 65535") 69 rdtypes.append(nrdtype) 70 rdtypes.sort() 71 window = 0 72 octets = 0 73 prior_rdtype = 0 74 bitmap = bytearray(b'\0' * 32) 75 windows = [] 76 for nrdtype in rdtypes: 77 if nrdtype == prior_rdtype: 78 continue 79 prior_rdtype = nrdtype 80 new_window = nrdtype // 256 81 if new_window != window: 82 windows.append((window, bitmap[0:octets])) 83 bitmap = bytearray(b'\0' * 32) 84 window = new_window 85 offset = nrdtype % 256 86 byte = offset // 8 87 bit = offset % 8 88 octets = byte + 1 89 bitmap[byte] = bitmap[byte] | (0x80 >> bit) 90 91 windows.append((window, bitmap[0:octets])) 92 return cls(rdclass, rdtype, next, windows)
93
94 - def to_wire(self, file, compress=None, origin=None):
95 self.next.to_wire(file, None, origin) 96 for (window, bitmap) in self.windows: 97 file.write(struct.pack('!BB', window, len(bitmap))) 98 file.write(bitmap)
99 100 @classmethod
101 - def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None):
102 (next, cused) = dns.name.from_wire(wire[: current + rdlen], current) 103 current += cused 104 rdlen -= cused 105 windows = [] 106 while rdlen > 0: 107 if rdlen < 3: 108 raise dns.exception.FormError("NSEC too short") 109 window = wire[current] 110 octets = wire[current + 1] 111 if octets == 0 or octets > 32: 112 raise dns.exception.FormError("bad NSEC octets") 113 current += 2 114 rdlen -= 2 115 if rdlen < octets: 116 raise dns.exception.FormError("bad NSEC bitmap length") 117 bitmap = bytearray(wire[current: current + octets].unwrap()) 118 current += octets 119 rdlen -= octets 120 windows.append((window, bitmap)) 121 if origin is not None: 122 next = next.relativize(origin) 123 return cls(rdclass, rdtype, next, windows)
124
125 - def choose_relativity(self, origin=None, relativize=True):
127