Class Dnsruby::RR::NSEC
In: lib/Dnsruby/resource/NSEC.rb
Parent: RR
Message Update ResolvError EncodeError OtherResolvError ServFail FormErr DecodeError NXRRSet YXDomain NotImp NXDomain VerifyError NotAuth YXRRSet NotZone Refused TsigError CodeMapper Types MetaTypes QTypes Nsec3HashAlgorithms Algorithms OpCode Classes ExtendedRCode Modes RCode Comparable Name RRSet TsigNotSignedResponseError Resolver SingleResolver StandardError TimeoutError ResolvTimeout DNS Dnssec Hosts RR\n[lib/Dnsruby/resource/A.rb\nlib/Dnsruby/resource/AAAA.rb\nlib/Dnsruby/resource/AFSDB.rb\nlib/Dnsruby/resource/CERT.rb\nlib/Dnsruby/resource/DHCID.rb\nlib/Dnsruby/resource/DLV.rb\nlib/Dnsruby/resource/DNSKEY.rb\nlib/Dnsruby/resource/DS.rb\nlib/Dnsruby/resource/HINFO.rb\nlib/Dnsruby/resource/HIP.rb\nlib/Dnsruby/resource/IN.rb\nlib/Dnsruby/resource/IPSECKEY.rb\nlib/Dnsruby/resource/ISDN.rb\nlib/Dnsruby/resource/KX.rb\nlib/Dnsruby/resource/LOC.rb\nlib/Dnsruby/resource/MINFO.rb\nlib/Dnsruby/resource/MX.rb\nlib/Dnsruby/resource/NAPTR.rb\nlib/Dnsruby/resource/NSAP.rb\nlib/Dnsruby/resource/NSEC.rb\nlib/Dnsruby/resource/NSEC3.rb\nlib/Dnsruby/resource/NSEC3PARAM.rb\nlib/Dnsruby/resource/OPT.rb\nlib/Dnsruby/resource/PX.rb\nlib/Dnsruby/resource/RP.rb\nlib/Dnsruby/resource/RRSIG.rb\nlib/Dnsruby/resource/RT.rb\nlib/Dnsruby/resource/SOA.rb\nlib/Dnsruby/resource/SPF.rb\nlib/Dnsruby/resource/SRV.rb\nlib/Dnsruby/resource/SSHFP.rb\nlib/Dnsruby/resource/TKEY.rb\nlib/Dnsruby/resource/TSIG.rb\nlib/Dnsruby/resource/TXT.rb\nlib/Dnsruby/resource/X25.rb\nlib/Dnsruby/resource/domain_name.rb\nlib/Dnsruby/resource/generic.rb\nlib/Dnsruby/resource/resource.rb] Recursor IPv6 IPv4 ZoneTransfer MessageDecoder MessageEncoder Question Header TheLog ValidatorThread PacketSender ResolverRuby Config KeyCache Cache SingleVerifier SelectThread Resolv ZoneReader lib/Dnsruby/DNS.rb lib/Dnsruby/dnssec.rb lib/Dnsruby/Hosts.rb lib/Dnsruby/resource/generic.rb lib/Dnsruby/Recursor.rb lib/Dnsruby/update.rb lib/Dnsruby/ipv6.rb lib/Dnsruby/ipv4.rb lib/Dnsruby/code_mapper.rb lib/Dnsruby/zone_transfer.rb lib/Dnsruby/message.rb lib/Dnsruby/TheLog.rb lib/Dnsruby/resource/resource.rb lib/Dnsruby/validator_thread.rb lib/Dnsruby/PacketSender.rb lib/Dnsruby/Resolver.rb lib/Dnsruby/Config.rb lib/Dnsruby/key_cache.rb lib/Dnsruby/Cache.rb lib/Dnsruby/single_verifier.rb lib/Dnsruby/SingleResolver.rb lib/Dnsruby/select_thread.rb lib/Dnsruby/name.rb lib/dnsruby.rb lib/Dnsruby/resource/TKEY.rb lib/Dnsruby/zone_reader.rb Dnsruby dot/m_61_0.png

RFC4034, section 4 The NSEC resource record lists two separate things: the next owner name (in the canonical ordering of the zone) that contains authoritative data or a delegation point NS RRset, and the set of RR types present at the NSEC RR‘s owner name [RFC3845]. The complete set of NSEC RRs in a zone indicates which authoritative RRsets exist in a zone and also form a chain of authoritative owner names in the zone. This information is used to provide authenticated denial of existence for DNS data, as described in [RFC4035].

Methods

Constants

TypeValue = Types::NSEC #:nodoc: all

Attributes

next_domain  [R]  The next name which exists after this NSEC The Next Domain field contains the next owner name (in the canonical ordering of the zone) that has authoritative data or contains a delegation point NS RRset
types  [R]  The Type Bit Maps field identifies the RRset types that exist at the NSEC RR‘s owner name

Public Class methods

[Source]

     # File lib/Dnsruby/resource/NSEC.rb, line 105
105:       def self.decode_types(bytes)
106:         types = []
107:         #RFC4034 section 4.1.2

108:         #The RR type space is split into 256 window blocks, each representing

109:         #the low-order 8 bits of the 16-bit RR type space.  Each block that

110:         #has at least one active RR type is encoded using a single octet

111:         #window number (from 0 to 255), a single octet bitmap length (from 1

112:         #to 32) indicating the number of octets used for the window block's

113:         #bitmap, and up to 32 octets (256 bits) of bitmap.

114: 
115:         #Blocks are present in the NSEC RR RDATA in increasing numerical

116:         #order.

117: 
118:         #  Type Bit Maps Field = ( Window Block # | Bitmap Length | Bitmap )+

119: 
120:         #  where "|" denotes concatenation.

121:        
122:         pos = 0
123:         while (pos < bytes.length)
124:           #So, read the first two octets

125:           if (bytes.length-pos < 2)
126:             raise DecodeError.new("NSEC : Expected window number and bitmap length octets")
127:           end
128:           window_number = bytes[pos]
129:           bitmap_length = bytes[pos+1]
130:           if (window_number.class == String) # Ruby 1.9

131:             window_number = window_number.getbyte(0)
132:             bitmap_length = bitmap_length.getbyte(0)
133:           end
134:           pos += 2
135:           bitmap = bytes[pos,bitmap_length]
136:           pos += bitmap_length
137:           #Each bitmap encodes the low-order 8 bits of RR types within the

138:           #window block, in network bit order.  The first bit is bit 0.  For

139:           #window block 0, bit 1 corresponds to RR type 1 (A), bit 2 corresponds

140:           #to RR type 2 (NS), and so forth.  For window block 1, bit 1

141:           #corresponds to RR type 257, and bit 2 to RR type 258.  If a bit is

142:           #set, it indicates that an RRset of that type is present for the NSEC

143:           #RR's owner name.  If a bit is clear, it indicates that no RRset of

144:           #that type is present for the NSEC RR's owner name.

145:           index = 0
146:           bitmap.each_byte do |char|
147:             if char.to_i != 0
148:               # decode these RR types

149:               0..8.times do |i|
150:                 if (((1 << (7-i)) & char) == (1 << (7-i)))
151:                   type = Types.new((256 * window_number) + (8 * index) + i)
152:                   #Bits representing pseudo-types MUST be clear, as they do not appear

153:                   #in zone data.  If encountered, they MUST be ignored upon being read.

154:                   if (!([Types::OPT, Types::TSIG].include?(type)))
155:                     types.push(type)
156:                   end
157:                 end               
158:               end
159:             end
160:             index += 1
161:           end
162:         end
163:         return types
164:       end

[Source]

     # File lib/Dnsruby/resource/NSEC.rb, line 170
170:       def self.encode_types(nsec)
171:         output=""
172:         #types represents all 65536 possible RR types.

173:         #Split up types into sets of 256 different types.

174:         type_codes = []
175:         nsec.types.each do |type|
176:           type_codes.push(type.code)
177:         end
178:         type_codes.sort!
179:         window = -1
180:         0.step(65536,256) { |step|
181:           # Gather up the RR types for this set of 256

182:           types_to_go = []
183:           while (!type_codes.empty? && type_codes[0] < step)
184:             types_to_go.push(type_codes[0])
185:             # And delete them from type_codes

186:             type_codes=type_codes.last(type_codes.length-1)
187:             break if (type_codes.empty?)
188:           end
189:           
190:           if (!types_to_go.empty?)
191:             # Then create the bitmap for them

192:             bitmap=""
193:             # keep on adding them until there's none left

194:             pos = 0
195:             bitmap_pos = 0
196:             while (!types_to_go.empty?)
197:               
198:               # Check the next eight

199:               byte = 0
200:               pos += 8
201:               while (types_to_go[0] < pos + step-256)
202:                 byte = byte | (1 << (pos-1-(types_to_go[0] - (step-256) )))
203:                 # Add it to the list

204:                 # And remove it from the to_go queue

205:                 types_to_go =types_to_go.last(types_to_go.length-1)
206:                 break if (types_to_go.empty?)
207:               end
208:               bitmap += " "
209:               if (bitmap[bitmap_pos].class == String)
210:                 bitmap.setbyte(bitmap_pos, byte) # Ruby 1.9

211:               else
212:                 bitmap[bitmap_pos]=byte              
213:               end
214:               bitmap_pos+=1
215:             end
216:             
217:             # Now add data to output bytes

218:             start = output.length
219:             (2+bitmap.length).times do 
220:               output += " "
221:             end
222:           
223:             if (output[start].class == String)
224:               output.setbyte(start, window)
225:               output.setbyte(start+1, bitmap.length)
226:               bitmap.length.times do |i|
227:                 output.setbyte(start+2+i, bitmap[i].getbyte(0))
228:               end
229:             else
230:               output[start] = window
231:               output[start+1] = bitmap.length
232:               bitmap.length.times do |i|
233:                 output[start+2+i] = bitmap[i]
234:               end
235:             end
236:           end
237:           window += 1
238:           
239:           # Are there any more types after this?

240:           if (type_codes.empty?)
241:             # If not, then break (so we don't add more zeros)

242:             break
243:           end
244:         }
245:         if (output[0].class == String)
246:           output = output.force_encoding("ascii-8bit")
247:         end
248:         return output
249:       end

[Source]

    # File lib/Dnsruby/resource/NSEC.rb, line 76
76:       def self.get_types(t)
77:         types = nil
78:         if (t.instance_of?Array)
79:           # from the wire, already decoded

80:           types =t
81:         elsif (t.instance_of?String)
82:           if (index = t.index";")
83:             t = t[0, index]
84:           end
85:           if (index = t.index")")
86:             t = t[0, index]
87:           end
88:           # List of mnemonics

89:           types=[]
90:           mnemonics = t.split(" ")
91:           mnemonics.each do |m|
92:             type = Types.new(m)
93:             types.push(type)
94:           end
95:         else
96:           raise DecodeError.new("Unknown format of types for Dnsruby::RR::NSEC")
97:         end
98:         return types
99:       end

Public Instance methods

[Source]

     # File lib/Dnsruby/resource/NSEC.rb, line 101
101:       def add_type(t)
102:         self.types=(@types + [t])
103:       end

[Source]

    # File lib/Dnsruby/resource/NSEC.rb, line 45
45:       def check_name_in_range(n)
46:         # Check if the name is covered by this record

47:         if (@name.wild?)
48:           return check_name_in_wildcard_range(n)
49:         end
50:         if (name.canonically_before(n) && (n.canonically_before(next_domain)))
51:           return true
52:         end
53:         return false
54:       end

[Source]

    # File lib/Dnsruby/resource/NSEC.rb, line 56
56:       def check_name_in_wildcard_range(n)
57:         #  Check if the name is covered by this record

58:         return false if !@name.wild?
59:         return false if @next_domain.canonically_before(n)
60:         # Now just check that the wildcard is *before* the name

61:         # Strip the first label ("*") and then compare

62:         n2 = Name.create(@name)
63:         n2.labels.delete_at(0)
64:         return false if n.canonically_before(n2)
65:         return true
66:       end

[Source]

     # File lib/Dnsruby/resource/NSEC.rb, line 166
166:       def encode_types
167:         NSEC.encode_types(self)
168:       end

[Source]

     # File lib/Dnsruby/resource/NSEC.rb, line 257
257:       def from_string(input)
258:         if (input.length > 0)
259:           data = input.split(" ")
260:           self.next_domain=(data[0])
261:           len = data[0].length+ 1
262:           if (data[1] == "(")
263:             len = len + data[1].length
264:           end
265:           self.types=(input[len, input.length-len])
266:           @types = NSEC.get_types(input[len, input.length-len])
267:         end
268:       end

[Source]

    # File lib/Dnsruby/resource/NSEC.rb, line 40
40:       def next_domain=(n)
41:         nxt = Name.create(n)
42:         @next_domain = nxt
43:       end

[Source]

    # File lib/Dnsruby/resource/NSEC.rb, line 68
68:       def types=(t)
69:         if (t && t.length > 0)
70:         @types = NSEC.get_types(t)
71:         else
72:           @types = []
73:         end
74:       end

[Validate]