Class: Dnsruby::RR
- Inherits:
-
Object
- Object
- Dnsruby::RR
- Defined in:
- lib/Dnsruby/resource/resource.rb,
lib/Dnsruby/resource/A.rb,
lib/Dnsruby/resource/IN.rb,
lib/Dnsruby/resource/MX.rb,
lib/Dnsruby/resource/PX.rb,
lib/Dnsruby/resource/RP.rb,
lib/Dnsruby/resource/RT.rb,
lib/Dnsruby/resource/LOC.rb,
lib/Dnsruby/resource/OPT.rb,
lib/Dnsruby/resource/SOA.rb,
lib/Dnsruby/resource/SPF.rb,
lib/Dnsruby/resource/SRV.rb,
lib/Dnsruby/resource/TXT.rb,
lib/Dnsruby/resource/X25.rb,
lib/Dnsruby/resource/AAAA.rb,
lib/Dnsruby/resource/CERT.rb,
lib/Dnsruby/resource/ISDN.rb,
lib/Dnsruby/resource/NSAP.rb,
lib/Dnsruby/resource/TKEY.rb,
lib/Dnsruby/resource/TSIG.rb,
lib/Dnsruby/resource/AFSDB.rb,
lib/Dnsruby/resource/HINFO.rb,
lib/Dnsruby/resource/MINFO.rb,
lib/Dnsruby/resource/NAPTR.rb,
lib/Dnsruby/resource/generic.rb,
lib/Dnsruby/resource/domain_name.rb
Overview
Superclass for all Dnsruby resource records.
Represents a DNS RR (resource record) [RFC1035, section 3.2]
Use Dnsruby::RR::create(…) to create a new RR record.
mx = Dnsruby::RR.create("example.com. 7200 MX 10 mailhost.example.com.")
rr = Dnsruby::RR.create({:name => "example.com", :type => "MX", :ttl => 7200,
:preference => 10, :exchange => "mailhost.example.com"})
s = rr.to_s # Get a String representation of the RR (in zone file format)
rr_again = Dnsruby::RR.create(s)
Direct Known Subclasses
ANY, CERT, DomainName, Generic, HINFO, IN::A, IN::AAAA, IN::AFSDB, IN::PX, IN::SRV, IN::WKS, ISDN, LOC, MINFO, MX, NAPTR, NSAP, OPT, RP, RT, SOA, TKEY, TSIG, TXT, X25
Defined Under Namespace
Modules: IN Classes: ANY, CERT, CNAME, DNAME, DomainName, Generic, HINFO, ISDN, LOC, MB, MG, MINFO, MR, MX, NAPTR, NS, NSAP, OPT, PTR, RP, RT, SOA, SPF, TKEY, TSIG, TXT, X25
Constant Summary collapse
- ClassInsensitiveTypes =
[ NS, CNAME, DNAME, SOA, PTR, HINFO, MINFO, MX, TXT, ISDN, MB, MG, MR, NAPTR, NSAP, OPT, RP, RT, X25, SPF, CERT, LOC, TSIG, TKEY, ANY ]
- @@RR_REGEX =
A regular expression which catches any valid resource record.
Regexp.new("^\\s*(\\S+)\\s*(\\d+)?\\s*(#{Classes.regexp + "|CLASS\\d+"})?\\s*(#{Types.regexp + '|TYPE\\d+'})?\\s*([\\s\\S]*)\$")
Instance Attribute Summary collapse
-
#klass ⇒ Object
The Resource class.
-
#name ⇒ Object
The Resource’s domain name.
-
#rdata ⇒ Object
The Resource data section.
-
#ttl ⇒ Object
The Resource Time-To-Live.
-
#type ⇒ Object
(also: #rr_type)
The Resource type.
Class Method Summary collapse
-
.create(*args) ⇒ Object
Create a new RR from the arguments, which can be either a String or a Hash.
-
.decode_rdata(msg) ⇒ Object
:nodoc: all.
-
.get_class(type_value, class_value) ⇒ Object
Get an RR of the specified type and class.
-
.implemented_rrs ⇒ Object
Return an array of all the currently implemented RR types.
-
.new_from_data(*args) ⇒ Object
:nodoc: all.
-
.new_from_hash(inhash) ⇒ Object
Create a new RR from the hash.
-
.new_from_string(rrstring) ⇒ Object
Returns a Dnsruby::RR object of the appropriate type and initialized from the string passed by the user.
Instance Method Summary collapse
- #==(other) ⇒ Object
-
#encode_rdata(msg) ⇒ Object
:nodoc: all.
-
#eql?(other) ⇒ Boolean
:nodoc:.
-
#from_data(data) ⇒ Object
:nodoc: all.
-
#from_hash(hash) ⇒ Object
:nodoc: all.
-
#from_string(input) ⇒ Object
:nodoc: all.
-
#hash ⇒ Object
:nodoc:.
- #init_defaults ⇒ Object
-
#rdata_to_string ⇒ Object
Get a string representation of the data section of the RR (in zone file format).
- #rdlength ⇒ Object
-
#sameRRset(rec) ⇒ Object
Determines if two Records could be part of the same RRset.
-
#to_s ⇒ Object
Returns a string representation of the RR in zone file format.
Instance Attribute Details
#klass ⇒ Object
The Resource class
106 107 108 |
# File 'lib/Dnsruby/resource/resource.rb', line 106 def klass @klass end |
#name ⇒ Object
The Resource’s domain name
102 103 104 |
# File 'lib/Dnsruby/resource/resource.rb', line 102 def name @name end |
#rdata ⇒ Object
The Resource data section
110 111 112 |
# File 'lib/Dnsruby/resource/resource.rb', line 110 def rdata @rdata end |
#ttl ⇒ Object
The Resource Time-To-Live
108 109 110 |
# File 'lib/Dnsruby/resource/resource.rb', line 108 def ttl @ttl end |
#type ⇒ Object Also known as: rr_type
The Resource type
104 105 106 |
# File 'lib/Dnsruby/resource/resource.rb', line 104 def type @type end |
Class Method Details
.create(*args) ⇒ Object
Create a new RR from the arguments, which can be either a String or a Hash. See new_from_string and new_from_hash for details
a = Dnsruby::RR.create("foo.example.com. 86400 A 10.1.2.3")
mx = Dnsruby::RR.create("example.com. 7200 MX 10 mailhost.example.com.")
cname = Dnsruby::RR.create("www.example.com 300 IN CNAME www1.example.com")
txt = Dnsruby::RR.create('baz.example.com 3600 HS TXT "text record"')
rr = Dnsruby::RR.create({:name => "example.com"})
rr = Dnsruby::RR.create({:name => "example.com", :type => "MX", :ttl => 10,
:preference => 5, :exchange => "mx1.example.com"})
448 449 450 451 452 453 454 455 456 |
# File 'lib/Dnsruby/resource/resource.rb', line 448 def RR.create(*args) if (args.length == 1) && (args[0].class == String) return new_from_string(args[0]) elsif (args.length == 1) && (args[0].class == Hash) return new_from_hash(args[0]) else return new_from_data(args) end end |
.decode_rdata(msg) ⇒ Object
:nodoc: all
375 376 377 378 |
# File 'lib/Dnsruby/resource/resource.rb', line 375 def self.decode_rdata(msg) #:nodoc: all # to be implemented by subclasses raise DecodeError.new("#{self.class} is RR.") end |
.get_class(type_value, class_value) ⇒ Object
Get an RR of the specified type and class
410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 |
# File 'lib/Dnsruby/resource/resource.rb', line 410 def self.get_class(type_value, class_value) #:nodoc: all # if (type_value == Types.OPT) # return Class.new(OPT) # end if (type_value.class == Class) type_value = type_value.const_get(:TypeValue) return ClassHash[[type_value, Classes.to_code(class_value)]] || Generic.create(type_value, Classes.to_code(class_value)) else if (type_value.class == Types) type_value = type_value.code else type_value = Types.new(type_value).code end if (class_value.class == Classes) class_value = class_value.code else class_value = Classes.new(class_value).code end return ClassHash[[type_value, class_value]] || Generic.create(type_value, class_value) end return ret end |
.implemented_rrs ⇒ Object
Return an array of all the currently implemented RR types
330 331 332 |
# File 'lib/Dnsruby/resource/resource.rb', line 330 def RR.implemented_rrs return ClassHash.keys.map {|k| Dnsruby::Types.to_string(k[0])} end |
.new_from_data(*args) ⇒ Object
:nodoc: all
307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 |
# File 'lib/Dnsruby/resource/resource.rb', line 307 def RR.new_from_data(*args) #:nodoc: all name = args[0] rrtype = args[1] rrclass = args[2] ttl = args[3] rdlength = args[4] data = args[5] offset = args[6] rdata = data[offset, rdlength] record = nil MessageDecoder.new(rdata) {|msg| record = get_class(rrtype, rrclass).decode_rdata(msg) } record.name = name record.ttl = ttl record.type = rrtype record.klass = rrclass return record end |
.new_from_hash(inhash) ⇒ Object
Create a new RR from the hash. The name is required; all other fields are optional. Type defaults to ANY and the Class defaults to IN. The TTL defaults to 0.
If the type is specified, then it is necessary to provide ALL of the resource record fields which are specific to that record; i.e. for an MX record, you would need to specify the exchange and the preference
require 'Dnsruby'
rr = Dnsruby::RR.new_from_hash({:name => "example.com"})
rr = Dnsruby::RR.new_from_hash({:name => "example.com", :type => Types.MX, :ttl => 10, :preference => 5, :exchange => "mx1.example.com"})
182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 |
# File 'lib/Dnsruby/resource/resource.rb', line 182 def RR.new_from_hash(inhash) hash = inhash.clone type = hash[:type] || Types::ANY klass = hash[:klass] || Classes::IN ttl = hash[:ttl] || 0 recordclass = get_class(type, klass) record = recordclass.new record.name=hash[:name] if !(record.name.kind_of?Name) record.name = Name.create(record.name) end record.ttl=ttl record.type = type record.klass = klass hash.delete(:name) hash.delete(:type) hash.delete(:ttl) hash.delete(:klass) record.from_hash(hash) return record end |
.new_from_string(rrstring) ⇒ Object
Returns a Dnsruby::RR object of the appropriate type and initialized from the string passed by the user. The format of the string is that used in zone files, and is compatible with the string returned by Net::DNS::RR.inspect
The name and RR type are required; all other information is optional. If omitted, the TTL defaults to 0 and the RR class defaults to IN.
All names must be fully qualified. The trailing dot (.) is optional.
a = Dnsruby::RR.new_from_string("foo.example.com. 86400 A 10.1.2.3")
mx = Dnsruby::RR.new_from_string("example.com. 7200 MX 10 mailhost.example.com.")
cname = Dnsruby::RR.new_from_string("www.example.com 300 IN CNAME www1.example.com")
txt = Dnsruby::RR.new_from_string('baz.example.com 3600 HS TXT "text record"')
221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 |
# File 'lib/Dnsruby/resource/resource.rb', line 221 def RR.new_from_string(rrstring) # strip out comments # Test for non escaped ";" by means of the look-behind assertion # (the backslash is escaped) rrstring.gsub!(/(\?<!\\);.*/o, ""); if ((rrstring =~/#{@@RR_REGEX}/xo) == nil) raise Exception, "#{rrstring} did not match RR pat.\nPlease report this to the author!\n" end name = $1; ttl = $2.to_i || 0; rrclass = $3 || ''; rrtype = $4 || ''; rdata = $5 || ''; if rdata rdata.gsub!(/\s+$/o, "") end if name name.gsub!(/\.$/o, ""); end # RFC3597 tweaks # This converts to known class and type if specified as TYPE### if rrtype =~/^TYPE\d+/o rrtype = Dnsruby::Types.typesbyval(Dnsruby::Types::typesbyname(rrtype)) end if rrclass =~/^CLASS\d+/o rrclass = Dnsruby::Classes.classesbyval(Dnsruby::Classes::classesbyname(rrclass)) end if (rrtype=='' && rrclass && rrclass == 'ANY') rrtype = 'ANY'; rrclass = 'IN'; elsif (rrclass=='') rrclass = 'IN'; end if (rrtype == '') rrtype = 'ANY'; end if (implemented_rrs.include?(rrtype) && rdata !~/^\s*\\#/o ) subclass = _get_subclass(name, rrtype, rrclass, ttl, rdata) return subclass elsif (implemented_rrs.include?(rrtype)) # A known RR type starting with \# rdata =~ /\\\#\s+(\d+)\s+(.*)$/o; rdlength = $1.to_i; hexdump = $2; hexdump.gsub!(/\s*/, ""); if hexdump.length() != rdlength*2 raise Exception, "#{rdata} is inconsistent; length does not match content" end rdata = [hexdump].pack('H*'); return new_from_data(name, rrtype, rrclass, ttl, rdlength, rdata, 0) # rdata.length() - rdlength); elsif (rdata=~/\s*\\\#\s+\d+\s+/o) #We are now dealing with the truly unknown. raise Exception, 'Expected RFC3597 representation of RDATA' unless rdata =~/\\\#\s+(\d+)\s+(.*)$/o; rdlength = $1.to_i; hexdump = $2; hexdump.gsub!(/\s*/o, ""); if hexdump.length() != rdlength*2 raise Exception, "#{rdata} is inconsistent; length does not match content" ; end rdata = [hexdump].pack('H*'); return new_from_data(name,rrtype,rrclass,ttl,rdlength,rdata,0) # rdata.length() - rdlength); else #God knows how to handle these... subclass = _get_subclass(name, rrtype, rrclass, ttl, "") return subclass end end |
Instance Method Details
#==(other) ⇒ Object
380 381 382 383 384 385 386 387 388 389 390 391 392 393 |
# File 'lib/Dnsruby/resource/resource.rb', line 380 def ==(other) return false unless self.class == other.class s_ivars = self.instance_variables s_ivars.sort! s_ivars.delete "@ttl" # RFC 2136 section 1.1 o_ivars = other.instance_variables o_ivars.sort! o_ivars.delete "@ttl" # RFC 2136 section 1.1 return s_ivars == o_ivars && s_ivars.collect {|name| self.instance_variable_get name} == o_ivars.collect {|name| other.instance_variable_get name} end |
#encode_rdata(msg) ⇒ Object
:nodoc: all
370 371 372 373 |
# File 'lib/Dnsruby/resource/resource.rb', line 370 def encode_rdata(msg) #:nodoc: all # to be implemented by subclasses raise EncodeError.new("#{self.class} is RR.") end |
#eql?(other) ⇒ Boolean
:nodoc:
395 396 397 |
# File 'lib/Dnsruby/resource/resource.rb', line 395 def eql?(other) #:nodoc: return self == other end |
#from_data(data) ⇒ Object
:nodoc: all
360 361 362 363 |
# File 'lib/Dnsruby/resource/resource.rb', line 360 def from_data(data) #:nodoc: all # to be implemented by subclasses raise NotImplementedError.new end |
#from_hash(hash) ⇒ Object
:nodoc: all
166 167 168 169 170 |
# File 'lib/Dnsruby/resource/resource.rb', line 166 def from_hash(hash) #:nodoc: all hash.keys.each do |param| send(param.to_s+"=", hash[param]) end end |
#from_string(input) ⇒ Object
:nodoc: all
365 366 367 368 |
# File 'lib/Dnsruby/resource/resource.rb', line 365 def from_string(input) #:nodoc: all # to be implemented by subclasses # raise NotImplementedError.new end |
#hash ⇒ Object
:nodoc:
399 400 401 402 403 404 405 406 407 |
# File 'lib/Dnsruby/resource/resource.rb', line 399 def hash # :nodoc: h = 0 vars = self.instance_variables vars.delete "@ttl" vars.each {|name| h ^= self.instance_variable_get(name).hash } return h end |
#init_defaults ⇒ Object
140 141 142 |
# File 'lib/Dnsruby/resource/resource.rb', line 140 def init_defaults # Default to do nothing end |
#rdata_to_string ⇒ Object
Get a string representation of the data section of the RR (in zone file format)
352 353 354 355 356 357 358 |
# File 'lib/Dnsruby/resource/resource.rb', line 352 def rdata_to_string if (@rdata && @rdata.length > 0) return @rdata else return "no rdata" end end |
#rdlength ⇒ Object
112 113 114 |
# File 'lib/Dnsruby/resource/resource.rb', line 112 def rdlength return rdata.length end |
#sameRRset(rec) ⇒ Object
Determines if two Records could be part of the same RRset. This compares the name, type, and class of the Records; the ttl and rdata are not compared.
136 137 138 |
# File 'lib/Dnsruby/resource/resource.rb', line 136 def sameRRset(rec) return (@type == rec.type && @klass == rec.klass && @name== rec.name) end |
#to_s ⇒ Object
Returns a string representation of the RR in zone file format
347 348 349 |
# File 'lib/Dnsruby/resource/resource.rb', line 347 def to_s return (@name?@name.to_s():"") + ".\t" +(@ttl?@ttl.to_s():"") + "\t" + (klass()?klass.to_s():"") + "\t" + (type()?type.to_s():"") + "\t" + rdata_to_string end |