Class: Dnsruby::Message
- Inherits:
-
Object
- Object
- Dnsruby::Message
- Defined in:
- lib/Dnsruby/message.rb
Overview
Defines a DNS packet.
RFC 1035 Section 4.1, RFC 2136 Section 2, RFC 2845
Sections
Message objects have five sections:
-
The header section, a Dnsruby::Header object.
msg.header=Header.new(...) header = msg.header -
The question section, an array of Dnsruby::Question objects.
msg.add_question(Question.new(domain, type, klass)) msg.each_question do |question| .... end -
The answer section, an array of Dnsruby::RR objects.
msg.add_answer(RR.create({:name => "a2.example.com",
:type => “A”, :address => “10.0.0.2”}))
msg.each_answer {|answer| ... }
-
The authority section, an array of Dnsruby::RR objects.
msg.add_authority(rr) msg.each_authority {|rr| ... } -
The additional section, an array of Dnsruby::RR objects.
msg.add_additional(rr) msg.each_additional {|rr| ... }
In addition, each_resource iterates the answer, additional and authority sections :
msg.each_resource {|rr| ... }
Packet format encoding
Dnsruby::Message#encode
Dnsruby::Message::decode(data)
Direct Known Subclasses
Instance Attribute Summary collapse
-
#additional ⇒ Object
readonly
The additional section, an array of Dnsruby::RR objects.
-
#answer ⇒ Object
(also: #pre)
readonly
The answer section, an array of Dnsruby::RR objects.
-
#answerfrom ⇒ Object
If this Message is a response from a server, then answerfrom contains the address of the server.
-
#answersize ⇒ Object
If this Message is a response from a server, then answersize contains the size of the response.
-
#authority ⇒ Object
(also: #update)
readonly
The authority section, an array of Dnsruby::RR objects.
-
#header ⇒ Object
The header section, a Dnsruby::Header object.
-
#querytsig ⇒ Object
readonly
Returns the value of attribute querytsig.
-
#question ⇒ Object
(also: #zone)
readonly
The question section, an array of Dnsruby::Question objects.
-
#tsigerror ⇒ Object
readonly
Returns the value of attribute tsigerror.
-
#tsigkey ⇒ Object
Returns the value of attribute tsigkey.
-
#tsigstart ⇒ Object
Returns the value of attribute tsigstart.
-
#tsigstate ⇒ Object
Returns the value of attribute tsigstate.
Class Method Summary collapse
-
.decode(m) ⇒ Object
Decode the encoded message.
Instance Method Summary collapse
- #==(other) ⇒ Object
-
#add_additional(rr) ⇒ Object
:nodoc: all.
-
#add_answer(rr) ⇒ Object
(also: #add_pre)
:nodoc: all.
-
#add_authority(rr) ⇒ Object
(also: #add_update)
:nodoc: all.
-
#add_question(question, type = Types.A, klass = Classes.IN) ⇒ Object
(also: #add_zone)
Add a new Question to the Message.
- #each_additional ⇒ Object
- #each_answer ⇒ Object (also: #each_pre)
- #each_authority ⇒ Object (also: #each_update)
- #each_question ⇒ Object (also: #each_zone)
-
#each_resource ⇒ Object
Calls each_answer, each_authority, each_additional.
-
#encode ⇒ Object
Return the encoded form of the message.
-
#initialize(*args) ⇒ Message
constructor
Create a new Message.
-
#is_signed ⇒ Object
Was this message signed by a TSIG?.
-
#is_verified ⇒ Object
If this message was signed by a TSIG, was the TSIG verified?.
- #to_s ⇒ Object
-
#tsig ⇒ Object
Returns the TSIG record from the ADDITIONAL section, if one is present.
Constructor Details
#initialize(*args) ⇒ Message
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
# File 'lib/Dnsruby/message.rb', line 70 def initialize(*args) @header = Header.new() @question = [] @answer = [] @authority = [] @additional = [] type = Types.A klass = Classes.IN if (args.length > 0) name = args[0] if (args.length > 1) type = Types.new(args[1]) if (args.length > 2) klass = Classes.new(args[2]) end end add_question(name, type, klass) end end |
Instance Attribute Details
#additional ⇒ Object (readonly)
The additional section, an array of Dnsruby::RR objects.
98 99 100 |
# File 'lib/Dnsruby/message.rb', line 98 def additional @additional end |
#answer ⇒ Object (readonly) Also known as: pre
The answer section, an array of Dnsruby::RR objects.
94 95 96 |
# File 'lib/Dnsruby/message.rb', line 94 def answer @answer end |
#answerfrom ⇒ Object
If this Message is a response from a server, then answerfrom contains the address of the server
103 104 105 |
# File 'lib/Dnsruby/message.rb', line 103 def answerfrom @answerfrom end |
#answersize ⇒ Object
If this Message is a response from a server, then answersize contains the size of the response
106 107 108 |
# File 'lib/Dnsruby/message.rb', line 106 def answersize @answersize end |
#authority ⇒ Object (readonly) Also known as: update
The authority section, an array of Dnsruby::RR objects.
96 97 98 |
# File 'lib/Dnsruby/message.rb', line 96 def @authority end |
#header ⇒ Object
The header section, a Dnsruby::Header object.
100 101 102 |
# File 'lib/Dnsruby/message.rb', line 100 def header @header end |
#querytsig ⇒ Object (readonly)
Returns the value of attribute querytsig.
109 110 111 |
# File 'lib/Dnsruby/message.rb', line 109 def querytsig @querytsig end |
#question ⇒ Object (readonly) Also known as: zone
The question section, an array of Dnsruby::Question objects.
91 92 93 |
# File 'lib/Dnsruby/message.rb', line 91 def question @question end |
#tsigerror ⇒ Object (readonly)
Returns the value of attribute tsigerror.
110 111 112 |
# File 'lib/Dnsruby/message.rb', line 110 def tsigerror @tsigerror end |
#tsigkey ⇒ Object
Returns the value of attribute tsigkey.
108 109 110 |
# File 'lib/Dnsruby/message.rb', line 108 def tsigkey @tsigkey end |
#tsigstart ⇒ Object
Returns the value of attribute tsigstart.
112 113 114 |
# File 'lib/Dnsruby/message.rb', line 112 def tsigstart @tsigstart end |
#tsigstate ⇒ Object
Returns the value of attribute tsigstate.
113 114 115 |
# File 'lib/Dnsruby/message.rb', line 113 def tsigstate @tsigstate end |
Class Method Details
.decode(m) ⇒ Object
Decode the encoded message
284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 |
# File 'lib/Dnsruby/message.rb', line 284 def Message.decode(m) o = Message.new() MessageDecoder.new(m) {|msg| o.header = Header.new(msg) o.header.qdcount.times { question = msg.get_question o.question << question } o.header.ancount.times { rr = msg.get_rr o.answer << rr } o.header.nscount.times { rr = msg.get_rr o. << rr } o.header.arcount.times { |count| rr = msg.get_rr if (rr.type == Types.TSIG) if (count!=o.header.arcount-1) TheLog.Error("Incoming message has TSIG record before last record") end # @TODO@ Sort TSIG stuff out! # o.tsigstart = pos end o.additional << rr } } return o end |
Instance Method Details
#==(other) ⇒ Object
115 116 117 118 119 120 121 122 123 124 125 |
# File 'lib/Dnsruby/message.rb', line 115 def ==(other) ret = false if (other.kind_of?Message) ret = @header == other.header && @question == other.question && @answer == other.answer && @authority == other. && @additional == other.additional end return ret end |
#add_additional(rr) ⇒ Object
:nodoc: all
174 175 176 177 178 179 |
# File 'lib/Dnsruby/message.rb', line 174 def add_additional(rr) #:nodoc: all if (!@additional.include?rr) @additional << rr @header.arcount = @additional.length end end |
#add_answer(rr) ⇒ Object Also known as: add_pre
:nodoc: all
148 149 150 151 152 153 |
# File 'lib/Dnsruby/message.rb', line 148 def add_answer(rr) #:nodoc: all if (!@answer.include?rr) @answer << rr @header.ancount = @answer.length end end |
#add_authority(rr) ⇒ Object Also known as: add_update
:nodoc: all
161 162 163 164 165 166 |
# File 'lib/Dnsruby/message.rb', line 161 def (rr) #:nodoc: all if (!@authority.include?rr) @authority << rr @header.nscount = @authority.length end end |
#add_question(question, type = Types.A, klass = Classes.IN) ⇒ Object Also known as: add_zone
Add a new Question to the Message. Takes either a Question, or a name, and an optional type and class.
msg.add_question(Question.new(“example.com”, ‘MX’)) msg.add_question(“example.com”) # defaults to Types.A, Classes.IN msg.add_question(“example.com”, Types.LOC)
133 134 135 136 137 138 139 |
# File 'lib/Dnsruby/message.rb', line 133 def add_question(question, type=Types.A, klass=Classes.IN) if (!question.kind_of?Question) question = Question.new(question, type, klass) end @question << question @header.qdcount = @question.length end |
#each_additional ⇒ Object
181 182 183 184 185 |
# File 'lib/Dnsruby/message.rb', line 181 def each_additional @additional.each {|rec| yield rec } end |
#each_answer ⇒ Object Also known as: each_pre
155 156 157 158 159 |
# File 'lib/Dnsruby/message.rb', line 155 def each_answer @answer.each {|rec| yield rec } end |
#each_authority ⇒ Object Also known as: each_update
168 169 170 171 172 |
# File 'lib/Dnsruby/message.rb', line 168 def @authority.each {|rec| yield rec } end |
#each_question ⇒ Object Also known as: each_zone
141 142 143 144 145 |
# File 'lib/Dnsruby/message.rb', line 141 def each_question @question.each {|rec| yield rec } end |
#each_resource ⇒ Object
Calls each_answer, each_authority, each_additional
188 189 190 191 192 |
# File 'lib/Dnsruby/message.rb', line 188 def each_resource each_answer {|rec| yield rec} {|rec| yield rec} each_additional {|rec| yield rec} end |
#encode ⇒ Object
Return the encoded form of the message
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 |
# File 'lib/Dnsruby/message.rb', line 255 def encode return MessageEncoder.new {|msg| header = @header if (@tsigkey) header.arcount += 1 end header.encode(msg) @question.each {|q| msg.put_name(q.qname) msg.put_pack('nn', q.qtype.code, q.qclass.code) } [@answer, @authority, @additional].each {|rr| rr.each {|r| # name, ttl, data = r name = r.name ttl = r.ttl msg.put_name(name) msg.put_pack('nnN', r.type.code, r.klass.code, ttl) msg.put_length16 {r.encode_rdata(msg)} } } if (@tsigkey) tsigrec = @tsigkey.generate(this, msg, tsigerror, querytsig) tsigrec.encode(msg, Section.ADDITIONAL, c) end }.to_s end |
#is_signed ⇒ Object
Was this message signed by a TSIG?
203 204 205 206 207 |
# File 'lib/Dnsruby/message.rb', line 203 def is_signed return (tsigstate == :Signed || tsigstate == :Verified || tsigstate == :Failed) end |
#is_verified ⇒ Object
If this message was signed by a TSIG, was the TSIG verified?
210 211 212 |
# File 'lib/Dnsruby/message.rb', line 210 def is_verified return (tsigstate == :Verified) end |
#to_s ⇒ Object
214 215 216 217 218 219 220 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 |
# File 'lib/Dnsruby/message.rb', line 214 def to_s retval = ""; if (@answerfrom != nil && @answerfrom != "") retval = retval + ";; Answer received from #{@answerfrom} (#{@answersize} bytes)\n;;\n"; end retval = retval + ";; HEADER SECTION\n"; retval = retval + @header.to_s; retval = retval + "\n"; section = (@header.opcode == OpCode.UPDATE) ? "ZONE" : "QUESTION"; retval = retval + ";; #{section} SECTION (#{@header.qdcount} record#{@header.qdcount == 1 ? '' : 's'})\n"; each_question { |qr| retval = retval + ";; #{qr.to_s}\n"; } retval = retval + "\n"; section = (@header.opcode == OpCode.UPDATE) ? "PREREQUISITE" : "ANSWER"; retval = retval + ";; #{section} SECTION (#{@header.ancount} record#{@header.ancount == 1 ? '' : 's'})\n"; each_answer { |rr| retval = retval + rr.to_s + "\n"; } retval = retval + "\n"; section = (@header.opcode == OpCode.UPDATE) ? "UPDATE" : "AUTHORITY"; retval = retval + ";; #{section} SECTION (#{@header.nscount} record#{@header.nscount == 1 ? '' : 's'})\n"; { |rr| retval = retval + rr.to_s + "\n"; } retval = retval + "\n"; retval = retval + ";; ADDITIONAL SECTION (#{@header.arcount} record#{@header.arcount == 1 ? '' : 's'})\n"; each_additional { |rr| retval = retval + rr.to_s+ "\n"; } return retval; end |
#tsig ⇒ Object
Returns the TSIG record from the ADDITIONAL section, if one is present.
195 196 197 198 199 200 |
# File 'lib/Dnsruby/message.rb', line 195 def tsig if (@additional.last.type == Types.TSIG) return @additional.last end return nil end |