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):
    126          self.next = self.next.choose_relativity(origin, relativize)
    127