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