Class Dnsruby::RR::NSEC
In: lib/Dnsruby/resource/NSEC.rb
Parent: RR
ResolvError EncodeError OtherResolvError ServFail FormErr DecodeError NXRRSet YXDomain NotImp NXDomain VerifyError NotAuth YXRRSet NotZone Refused TsigError Message Update CodeMapper Types MetaTypes QTypes Nsec3HashAlgorithms Algorithms OpCode Classes ExtendedRCode RCode Modes Comparable Name RRSet Resolver SingleResolver StandardError TimeoutError ResolvTimeout DNS Dnssec Hosts SelectThread\n[lib/Dnsruby/select_thread.rb\nlib/Dnsruby/select_thread.rb.michael.rb] Recursor IPv6 IPv4 ZoneTransfer MessageDecoder MessageEncoder Question Header TheLog 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/DLV.rb\nlib/Dnsruby/resource/DNSKEY.rb\nlib/Dnsruby/resource/DS.rb\nlib/Dnsruby/resource/HINFO.rb\nlib/Dnsruby/resource/IN.rb\nlib/Dnsruby/resource/ISDN.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/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] ValidatorThread PacketSender ResolverRuby Config KeyCache Cache SingleVerifier Resolv Iana lib/Dnsruby/DNS.rb lib/Dnsruby/dnssec.rb lib/Dnsruby/Hosts.rb lib/Dnsruby/select_thread.rb.michael.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/name.rb lib/dnsruby.rb lib/Dnsruby/resource/TKEY.rb lib/Dnsruby/iana_ports.rb Dnsruby dot/m_56_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 99
 99:       def self.decode_types(bytes)
100:         types = []
101:         #RFC4034 section 4.1.2

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

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

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

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

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

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

108: 
109:         #Blocks are present in the NSEC RR RDATA in increasing numerical

110:         #order.

111: 
112:         #  Type Bit Maps Field = ( Window Block # | Bitmap Length | Bitmap )+

113: 
114:         #  where "|" denotes concatenation.

115:        
116:         pos = 0
117:         while (pos < bytes.length)
118:           #So, read the first two octets

119:           if (bytes.length-pos < 2)
120:             raise DecodeError.new("NSEC : Expected window number and bitmap length octets")
121:           end
122:           window_number = bytes[pos]
123:           bitmap_length = bytes[pos+1]
124:           if (window_number.class == String) # Ruby 1.9

125:             window_number = window_number.getbyte(0)
126:             bitmap_length = bitmap_length.getbyte(0)
127:           end
128:           pos += 2
129:           bitmap = bytes[pos,bitmap_length]
130:           pos += bitmap_length
131:           #Each bitmap encodes the low-order 8 bits of RR types within the

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

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

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

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

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

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

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

139:           index = 0
140:           bitmap.each_byte do |char|
141:             if char.to_i != 0
142:               # decode these RR types

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

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

148:                   if (!([Types::OPT, Types::TSIG].include?(type)))
149:                     types.push(type)
150:                   end
151:                 end               
152:               end
153:             end
154:             index += 1
155:           end
156:         end
157:         return types
158:       end

[Source]

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

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

168:         type_codes = []
169:         nsec.types.each do |type|
170:           type_codes.push(type.code)
171:         end
172:         type_codes.sort!
173:         window = -1
174:         0.step(65536,256) { |step|
175:           # Gather up the RR types for this set of 256

176:           types_to_go = []
177:           while (!type_codes.empty? && type_codes[0] < step)
178:             types_to_go.push(type_codes[0])
179:             # And delete them from type_codes

180:             type_codes=type_codes.last(type_codes.length-1)
181:             break if (type_codes.empty?)
182:           end
183:           
184:           if (!types_to_go.empty?)
185:             # Then create the bitmap for them

186:             bitmap=""
187:             # keep on adding them until there's none left

188:             pos = 0
189:             bitmap_pos = 0
190:             while (!types_to_go.empty?)
191:               
192:               # Check the next eight

193:               byte = 0
194:               pos += 8
195:               while (types_to_go[0] < pos + step-256)
196:                 byte = byte | (1 << (pos-1-(types_to_go[0] - (step-256) )))
197:                 # Add it to the list

198:                 # And remove it from the to_go queue

199:                 types_to_go =types_to_go.last(types_to_go.length-1)
200:                 break if (types_to_go.empty?)
201:               end
202:               bitmap += " "
203:               if (bitmap[bitmap_pos].class == String)
204:                 bitmap.setbyte(bitmap_pos, byte) # Ruby 1.9

205:               else
206:                 bitmap[bitmap_pos]=byte              
207:               end
208:               bitmap_pos+=1
209:             end
210:             
211:             # Now add data to output bytes

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

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

236:             break
237:           end
238:         }
239:         if (output[0].class == String)
240:           output = output.force_encoding("ascii-8bit")
241:         end
242:         return output
243:       end

[Source]

    # File lib/Dnsruby/resource/NSEC.rb, line 72
72:       def self.get_types(t)
73:         types = nil
74:         if (t.instance_of?Array)
75:           # from the wire, already decoded

76:           types =t
77:         elsif (t.instance_of?String)
78:           if t[t.length-1, t.length]!=")"
79:             t = t + " )"
80:           end
81:           # List of mnemonics

82:           types=[]
83:           mnemonics = t.split(" ")
84:           mnemonics.pop
85:           mnemonics.each do |m|
86:             type = Types.new(m)
87:             types.push(type)
88:           end
89:         else
90:           raise DecodeError.new("Unknown format of types for Dnsruby::RR::NSEC")
91:         end
92:         return types
93:       end

Public Instance methods

[Source]

    # File lib/Dnsruby/resource/NSEC.rb, line 95
95:       def add_type(t)
96:         self.types=(@types + [t])
97:       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 160
160:       def encode_types
161:         NSEC.encode_types(self)
162:       end

[Source]

     # File lib/Dnsruby/resource/NSEC.rb, line 251
251:       def from_string(input)
252:         if (input.length > 0)
253:           data = input.split(" ")
254:           self.next_domain=(data[0])
255:           len = data[0].length+ 1
256:           if (data[1] == "(")
257:             len = len + data[1].length
258:           end
259:           self.types=(input[len, input.length-len])
260:         end
261:       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:         @types = NSEC.get_types(t)
70:       end

[Validate]