1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 import io
17
18 import dns.exception
19 import dns.rdata
20 import dns.rdatatype
21 import dns.name
22 import dns.util
23
24 -class NSEC(dns.rdata.Rdata):
25 """NSEC record
26
27 @ivar next: the next name
28 @type next: dns.name.Name object
29 @ivar windows: the windowed bitmap list
30 @type windows: list of (window number, bytes) tuples"""
31
32 __slots__ = ['next', 'windows']
33
34 - def __init__(self, rdclass, rdtype, next, windows):
38
39 - def to_text(self, origin=None, relativize=True, **kw):
40 next = self.next.choose_relativity(origin, relativize)
41 text = ''
42 for (window, bitmap) in self.windows:
43 bits = []
44 for i in range(0, len(bitmap)):
45 byte = bitmap[i]
46 for j in range(0, 8):
47 if byte & (0x80 >> j):
48 bits.append(dns.rdatatype.to_text(window * 256 + \
49 i * 8 + j))
50 text += (' ' + ' '.join(bits))
51 return '%s%s' % (next, text)
52
53 - def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True):
54 next = tok.get_name()
55 next = next.choose_relativity(origin, relativize)
56 rdtypes = []
57 while 1:
58 token = tok.get().unescape()
59 if token.is_eol_or_eof():
60 break
61 nrdtype = dns.rdatatype.from_text(token.value)
62 if nrdtype == 0:
63 raise dns.exception.SyntaxError("NSEC with bit 0")
64 if nrdtype > 65535:
65 raise dns.exception.SyntaxError("NSEC with bit > 65535")
66 rdtypes.append(nrdtype)
67 rdtypes.sort()
68 window = 0
69 octets = 0
70 prior_rdtype = 0
71 bitmap = bytearray(32)
72 windows = []
73 for nrdtype in rdtypes:
74 if nrdtype == prior_rdtype:
75 continue
76 prior_rdtype = nrdtype
77 new_window = nrdtype // 256
78 if new_window != window:
79 windows.append((window, bytes(bitmap[0:octets])))
80 bitmap = bytearray(32)
81 window = new_window
82 offset = nrdtype % 256
83 byte = offset // 8
84 bit = offset % 8
85 octets = byte + 1
86 bitmap[byte] = bitmap[byte] | (0x80 >> bit)
87 windows.append((window, bytes(bitmap[0:octets])))
88 return cls(rdclass, rdtype, next, windows)
89
90 from_text = classmethod(from_text)
91
92 - def to_wire(self, file, compress = None, origin = None):
98
99 - def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None):
122
123 from_wire = classmethod(from_wire)
124
127
128 - def _cmp(self, other):
130