Class: Net::DNS::Header
- Inherits:
-
Object
- Object
- Net::DNS::Header
- Defined in:
- lib/net/dns/header.rb
Overview
Name
Net::DNS::Header - DNS packet header class
Synopsis
require 'net/dns/header'
Description
The Net::DNS::Header class represents the header portion of a DNS packet. An Header object is created whenever a new packet is parsed or as user request.
header = Net::DNS::Header.new
# ;; id = 18123
# ;; qr = 0 opCode: 0 aa = 0 tc = 0 rd = 1
# ;; ra = 0 ad = 0 cd = 0 rcode = 0
# ;; qdCount = 1 anCount = 0 nsCount = 0 arCount = 0
header.format
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
# | 18123 |
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
# |0| 0 |0|0|1|0|0| 0 | 0 |
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
# | 1 |
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
# | 0 |
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
# | 0 |
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
# | 0 |
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
# packet is an instance of Net::DNS::Packet
header = packet.header
puts "Answer is #{header.auth? ? '' : 'non'} authoritative"
A lot of methods were written to keep a compatibility layer with the Perl version of the library, as long as methods name which are more or less the same.
Error classes
Some error classes has been defined for the Net::DNS::Header class, which are listed here to keep a light and browsable main documentation. We have:
-
HeaderArgumentError: canonical argument error
-
HeaderWrongCount: a wrong
count
parameter has been passed -
HeaderWrongRecursive: a wrong
recursive
parameter has been passed -
HeaderWrongOpcode: a not valid
opCode
has been specified -
HeaderDuplicateID: the requested ID is already in use
Copyright
Copyright © 2006 Marco Ceresa
All rights reserved. This program is free software; you may redistribute it and/or modify it under the same terms as Ruby itself.
Defined Under Namespace
Classes: RCode
Constant Summary collapse
- QUERY =
Constant for
opCode
query 0
- IQUERY =
Constant for
opCode
iquery 1
- STATUS =
Constant for
opCode
status 2
- OPARR =
Array with given strings
%w[QUERY IQUERY STATUS]
- @@id_arr =
[]
Instance Attribute Summary collapse
-
#anCount ⇒ Object
Reader for answer section entries number.
-
#arCount ⇒ Object
Reader for addictional section entries number.
-
#id ⇒ Object
Reader for
id
attribute. -
#nsCount ⇒ Object
Reader for authority section entries number.
-
#opCode ⇒ Object
Reader for the operational code.
-
#qdCount ⇒ Object
Reader for question section entries number.
-
#rCode ⇒ Object
Reader for the rCode instance.
Class Method Summary collapse
-
.parse(arg) ⇒ Object
Creates a new Net::DNS::Header object from binary data, which is passed as a string object as argument.
Instance Method Summary collapse
-
#aa=(val) ⇒ Object
Set the
aa
flag (authoritative answer) to eithertrue
orfalse
. -
#ad=(val) ⇒ Object
Set the
ad
flag to eithertrue
otfalse
. -
#auth? ⇒ Boolean
Checks whether the response is authoritative.
-
#cd=(val) ⇒ Object
Set the
cd
flag (checking disabled) to eithertrue
otfalse
. -
#checking? ⇒ Boolean
Checks whether checking is enabled or disabled.
-
#data ⇒ Object
Returns the header data in binary format, appropriate for use in a DNS query packet.
-
#error? ⇒ Boolean
Checks for errors in the DNS packet.
-
#format ⇒ Object
The Net::DNS::Header#format method prints out the header in a special ascii representation of data, in a way similar to those often found on RFCs.
-
#initialize(arg = {}) ⇒ Header
constructor
Creates a new Net::DNS::Header object with the desired values, which can be specified as an Hash argument.
-
#inspect ⇒ Object
Inspect method, prints out all the options and relative values.
-
#opCode_str ⇒ Object
Returns a string representation of the
opCode
. -
#qr=(val) ⇒ Object
Set the
qr
query response flag to be eithertrue
orfalse
. -
#query? ⇒ Boolean
Checks whether the header is a query (
qr
bit set to 0). -
#r_available? ⇒ Boolean
Checks whether recursion is available.
-
#ra=(val) ⇒ Object
Set the
ra
flag (recursion available) to eithertrue
orfalse
. -
#rCode_str ⇒ Object
Returns an error array for the header response code, or
nil
if no error is generated. -
#rd=(val) ⇒ Object
Alias for Header#recursive= to keep compatibility with the Perl version.
-
#recursive=(val) ⇒ Object
Sets the recursion desidered bit.
-
#recursive? ⇒ Boolean
Checks whether the packet has a recursion bit set, meaning that recursion is desired.
-
#response? ⇒ Boolean
Checks whether the header is a response (
qr
bit set to 1). -
#tc=(val) ⇒ Object
Set the
tc
flag (truncated packet) to eithertrue
otfalse
. -
#truncated? ⇒ Boolean
Checks whether the packet was truncated.
-
#verified? ⇒ Boolean
Checks whether
ad
flag has been set.
Constructor Details
#initialize(arg = {}) ⇒ Header
Creates a new Net::DNS::Header object with the desired values, which can be specified as an Hash argument. When called without arguments, defaults are used. If a data string is passed, values are taken from parsing the string.
Examples:
# Create a new Net::DNS::Header object
header = Net::DNS::Header.new
# Create a new Net::DNS::Header object passing values
header = Net::DNS::Header.new(:opCode => 1, :rd => 0)
# Create a new Net::DNS::Header object with binary data
header = Net::DNS::Header.new(data)
Default values are:
:id => auto generated
:qr => 0 # Query response flag
:aa => 0 # Authoritative answer flag
:tc => 0 # Truncated packet flag
:ra => 0 # Recursiond available flag
:rCode => 0 # Response code (status of the query)
:opCode => 0 # Operational code (purpose of the query)
:cd => 0 # Checking disable flag
:ad => 0 # Only relevant in DNSSEC context
:rd => 1 # Recursion desired flag
:qdCount => 1 # Number of questions in the dns packet
:anCount => 0 # Number of answer RRs in the dns packet
:nsCount => 0 # Number of authoritative RRs in the dns packet
:arCount => 0 # Number of additional RRs in the dns packet
See also each option for a detailed explanation of usage.
239 240 241 242 243 244 245 |
# File 'lib/net/dns/header.rb', line 239 def initialize(arg = {}) if arg.kind_of? Hash new_from_hash(arg) else raise HeaderArgumentError, "Wrong argument class: #{arg.class}" end end |
Instance Attribute Details
#anCount ⇒ Object
Reader for answer section entries number
198 199 200 |
# File 'lib/net/dns/header.rb', line 198 def anCount @anCount end |
#arCount ⇒ Object
Reader for addictional section entries number
202 203 204 |
# File 'lib/net/dns/header.rb', line 202 def arCount @arCount end |
#id ⇒ Object
Reader for id
attribute
190 191 192 |
# File 'lib/net/dns/header.rb', line 190 def id @id end |
#nsCount ⇒ Object
Reader for authority section entries number
200 201 202 |
# File 'lib/net/dns/header.rb', line 200 def nsCount @nsCount end |
#opCode ⇒ Object
Reader for the operational code
192 193 194 |
# File 'lib/net/dns/header.rb', line 192 def opCode @opCode end |
#qdCount ⇒ Object
Reader for question section entries number
196 197 198 |
# File 'lib/net/dns/header.rb', line 196 def qdCount @qdCount end |
#rCode ⇒ Object
Reader for the rCode instance
194 195 196 |
# File 'lib/net/dns/header.rb', line 194 def rCode @rCode end |
Class Method Details
.parse(arg) ⇒ Object
Creates a new Net::DNS::Header object from binary data, which is passed as a string object as argument. The configurations parameters are taken from parsing the string.
Example:
# Create a new Net::DNS::Header object with binary data
header = Net::DNS::Header.new(data)
header.auth?
#=> "true" if it comes from authoritative name server
259 260 261 262 263 264 265 266 267 |
# File 'lib/net/dns/header.rb', line 259 def self.parse(arg) if arg.kind_of? String o = allocate o.send(:new_from_binary, arg) o else raise HeaderArgumentError, "Wrong argument class: #{arg.class}" end end |
Instance Method Details
#aa=(val) ⇒ Object
Set the aa
flag (authoritative answer) to either true
or false
. You can also use 0 or 1.
This flag indicates whether a DNS answer packet contains authoritative data, meaning that is was generated by a nameserver authoritative for the domain of the question.
Must only be set to true
in DNS answer packets.
459 460 461 462 463 464 465 466 467 468 469 470 |
# File 'lib/net/dns/header.rb', line 459 def aa=(val) case val when true @aa = 1 when false @aa = 0 when 0,1 @aa = val else raise HeaderArgumentError, ":aa must be true(or 1) or false(or 0)" end end |
#ad=(val) ⇒ Object
Set the ad
flag to either true
ot false
. You can also use 0 or 1.
The AD bit is only set on answers where signatures have been cryptographically verified or the server is authoritative for the data and is allowed to set the bit by policy.
614 615 616 617 618 619 620 621 622 623 624 625 |
# File 'lib/net/dns/header.rb', line 614 def ad=(val) case val when true @ad = 1 when false @ad = 0 when 0,1 @ad = val else raise HeaderArgumentError, ":ad must be true(or 1) or false(or 0)" end end |
#auth? ⇒ Boolean
Checks whether the response is authoritative
if header.auth?
puts "Response is authoritative"
else
puts "Answer is NOT authoritative"
end
446 447 448 |
# File 'lib/net/dns/header.rb', line 446 def auth? @aa == 1 end |
#cd=(val) ⇒ Object
Set the cd
flag (checking disabled) to either true
ot false
. You can also use 0 or 1.
586 587 588 589 590 591 592 593 594 595 596 597 |
# File 'lib/net/dns/header.rb', line 586 def cd=(val) case val when true @cd = 1 when false @cd = 0 when 0,1 @cd = val else raise HeaderArgumentError, ":cd must be true(or 1) or false(or 0)" end end |
#checking? ⇒ Boolean
Checks whether checking is enabled or disabled.
Checking is enabled by default.
579 580 581 |
# File 'lib/net/dns/header.rb', line 579 def checking? @cd == 0 end |
#data ⇒ Object
Returns the header data in binary format, appropriate for use in a DNS query packet.
hdata = header.data
puts "Header is #{hdata.size} bytes"
348 349 350 351 352 353 354 355 356 357 358 |
# File 'lib/net/dns/header.rb', line 348 def data arr = [] arr.push(@id) arr.push((@qr<<7)|(@opCode<<3)|(@aa<<2)|(@tc<<1)|@rd) arr.push((@ra<<7)|(@ad<<5)|(@cd<<4)|@rCode.code) arr.push(@qdCount) arr.push(@anCount) arr.push(@nsCount) arr.push(@arCount) arr.pack("n C2 n4") end |
#error? ⇒ Boolean
Checks for errors in the DNS packet
unless header.error?
puts "No errors in DNS answer packet"
end
645 646 647 |
# File 'lib/net/dns/header.rb', line 645 def error? @rCode.code > 0 end |
#format ⇒ Object
The Net::DNS::Header#format method prints out the header in a special ascii representation of data, in a way similar to those often found on RFCs.
p Net::DNS::Header.new.format
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
# | 18123 |
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
# |0| 0 |0|0|1|0|0| 0 | 0 |
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
# | 1 |
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
# | 0 |
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
# | 0 |
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
# | 0 |
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
This can be very usefull for didactical purpouses :)
322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 |
# File 'lib/net/dns/header.rb', line 322 def format del = ("+-" * 16) + "+\n" len = del.length str = del + "|" + @id.to_s.center(len-3) + "|\n" str += del + "|" + @qr.to_s str += "|" + @opCode.to_s.center(7) str += "|" + @aa.to_s str += "|" + @tc.to_s str += "|" + @rd.to_s str += "|" + @ra.to_s str += "|" + @ad.to_s str += "|" + @cd.to_s.center(3) str += "|" + @rCode.to_s.center(7) + "|\n" str += del + "|" + @qdCount.to_s.center(len-3) + "|\n" str += del + "|" + @anCount.to_s.center(len-3) + "|\n" str += del + "|" + @nsCount.to_s.center(len-3) + "|\n" str += del + "|" + @arCount.to_s.center(len-3) + "|\n" + del str end |
#inspect ⇒ Object
Inspect method, prints out all the options and relative values.
p Net::DNS::Header.new
# ;; id = 18123
# ;; qr = 0 opCode: 0 aa = 0 tc = 0 rd = 1
# ;; ra = 0 ad = 0 cd = 0 rcode = 0
# ;; qdCount = 1 anCount = 0 nsCount = 0 arCount = 0
This method will maybe be changed in the future to a more pretty way of display output.
280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 |
# File 'lib/net/dns/header.rb', line 280 def inspect ";; id = #@id\n" + if false # @opCode == "UPDATE" #do stuff else ";; qr = #@qr\t" + "opCode: #{opCode_str}\t" + "aa = #@aa\t" + "tc = #@tc\t" + "rd = #@rd\n" + ";; ra = #@ra\t" + "ad = #@ad\t" + "cd = #@cd\t" + "rcode = #{@rCode.type}\n" + ";; qdCount = #@qdCount\t"+ "anCount = #@anCount\t"+ "nsCount = #@nsCount\t"+ "arCount = #@arCount\n" end end |
#opCode_str ⇒ Object
Returns a string representation of the opCode
puts "Packet is a #{header.opCode_str}"
#=> Packet is a QUERY
412 413 414 |
# File 'lib/net/dns/header.rb', line 412 def opCode_str OPARR[@opCode] end |
#qr=(val) ⇒ Object
Set the qr
query response flag to be either true
or false
. You can also use the values 0 and 1. This flag indicates if the DNS packet contains a query or an answer, so it should be set to true
in DNS answer packets. If qr
is true
, the packet is a response.
387 388 389 390 391 392 393 394 395 396 397 398 |
# File 'lib/net/dns/header.rb', line 387 def qr=(val) case val when true @qr = 1 when false @qr = 0 when 0,1 @qr = val else raise HeaderArgumentError, ":qr must be true(or 1) or false(or 0)" end end |
#query? ⇒ Boolean
Checks whether the header is a query (qr
bit set to 0)
377 378 379 |
# File 'lib/net/dns/header.rb', line 377 def query? @qr == 0 end |
#r_available? ⇒ Boolean
Checks whether recursion is available. This flag is usually set by nameservers to indicate that they support recursive-type queries.
553 554 555 |
# File 'lib/net/dns/header.rb', line 553 def r_available? @ra == 1 end |
#ra=(val) ⇒ Object
Set the ra
flag (recursion available) to either true
or false
. You can also use 0 and 1.
This flag must only be set in DNS answer packets.
562 563 564 565 566 567 568 569 570 571 572 573 |
# File 'lib/net/dns/header.rb', line 562 def ra=(val) case val when true @ra = 1 when false @ra = 0 when 0,1 @ra = val else raise HeaderArgumentError, ":ra must be true(or 1) or false(or 0)" end end |
#rCode_str ⇒ Object
Returns an error array for the header response code, or nil
if no error is generated.
error, cause = header.rCode_str
puts "Error #{error} cause by: #{cause}" if error
#=> Error ForErr caused by: The name server
#=> was unable to interpret the query
635 636 637 |
# File 'lib/net/dns/header.rb', line 635 def rCode_str return rCode.type, rCode.explanation end |
#rd=(val) ⇒ Object
Alias for Header#recursive= to keep compatibility with the Perl version.
545 546 547 |
# File 'lib/net/dns/header.rb', line 545 def rd=(val) self.recursive = val end |
#recursive=(val) ⇒ Object
Sets the recursion desidered bit. Remember that recursion query support is optional.
header.recursive = true
hdata = header.data # suitable for sending
Consult RFC1034 and RFC1035 for a detailed explanation of how recursion works.
527 528 529 530 531 532 533 534 535 536 537 538 539 540 |
# File 'lib/net/dns/header.rb', line 527 def recursive=(val) case val when true @rd = 1 when false @rd = 0 when 1 @rd = 1 when 0 @rd = 0 else raise HeaderWrongRecursive, "Wrong value (#{val}), please specify true (1) or false (0)" end end |
#recursive? ⇒ Boolean
Checks whether the packet has a recursion bit set, meaning that recursion is desired
513 514 515 |
# File 'lib/net/dns/header.rb', line 513 def recursive? @rd == 1 end |
#response? ⇒ Boolean
Checks whether the header is a response (qr
bit set to 1)
403 404 405 |
# File 'lib/net/dns/header.rb', line 403 def response? @qr == 1 end |
#tc=(val) ⇒ Object
Set the tc
flag (truncated packet) to either true
ot false
. You can also use 0 or 1.
The truncated flag is used in response packets to indicate that the amount of data to be trasmitted exceedes the maximum allowed by the protocol in use, tipically UDP, and that the data present in the packet has been truncated. A different protocol (such has TCP) need to be used to retrieve full data.
Must only be set in DNS answer packets.
497 498 499 500 501 502 503 504 505 506 507 508 |
# File 'lib/net/dns/header.rb', line 497 def tc=(val) case val when true @tc = 1 when false @tc = 0 when 0,1 @tc = val else raise HeaderArgumentError, ":tc must be true(or 1) or false(or 0)" end end |
#truncated? ⇒ Boolean
Checks whether the packet was truncated
# Sending packet using UDP
if header.truncated?
puts "Warning, packet has been truncated!"
# Sending packet using TCP
end
# Do something with the answer
481 482 483 |
# File 'lib/net/dns/header.rb', line 481 def truncated? @tc == 1 end |
#verified? ⇒ Boolean
Checks whether ad
flag has been set.
This flag is only relevant in DNSSEC context.
603 604 605 |
# File 'lib/net/dns/header.rb', line 603 def verified? @ad == 1 end |