Parent

Net::DNS::Header

DNS packet header class

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.

Constants

IQUERY

Constant for opCode iquery

OPARR

Array with given strings

QUERY

Constant for opCode query

STATUS

Constant for opCode status

Attributes

anCount[R]

Reader for answer section entries number

arCount[R]

Reader for addictional section entries number

id[R]

Reader for id attribute

nsCount[R]

Reader for authority section entries number

opCode[R]

Reader for the operational code

qdCount[R]

Reader for question section entries number

rCode[R]

Reader for the rCode instance

Public Class Methods

new(arg = {}) click to toggle source

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.

# File lib/net/dns/header.rb, line 214
def initialize(arg = {})
  if arg.kind_of? Hash
    new_from_hash(arg)
  else
    raise ArgumentError, "Wrong argument class `#{arg.class}'"
  end
end
parse(arg) click to toggle source

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
# File lib/net/dns/header.rb, line 234
def self.parse(arg)
  if arg.kind_of? String
    o = allocate
    o.send(:new_from_binary, arg)
    o
  else
    raise ArgumentError, "Wrong argument class `#{arg.class}'"
  end
end

Public Instance Methods

aa=(val) click to toggle source

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.

# File lib/net/dns/header.rb, line 430
def aa=(val)
  case val
  when true
    @aa = 1
  when false
    @aa = 0
  when 0,1
    @aa = val
  else
    raise ArgumentError, ":aa must be true(or 1) or false(or 0)"
  end
end
ad=(val) click to toggle source

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.

# File lib/net/dns/header.rb, line 585
def ad=(val)
  case val
  when true
    @ad = 1
  when false
    @ad = 0
  when 0,1
    @ad = val
  else
    raise ArgumentError, ":ad must be true(or 1) or false(or 0)"
  end
end
anCount=(val) click to toggle source

Sets the number of RRs in an answer section

# File lib/net/dns/header.rb, line 639
def anCount=(val)
  if (0..65535).include? val
    @anCount = val
  else
    raise WrongCountError, "Wrong number of count (#{val}), must be 0-65535"
  end
end
arCount=(val) click to toggle source

Sets the number of RRs in an addictional section

# File lib/net/dns/header.rb, line 659
def arCount=(val)
  if (0..65535).include? val
    @arCount = val
  else
    raise WrongCountError, "Wrong number of count: `#{val}' must be 0-65535"
  end
end
auth?() click to toggle source

Checks whether the response is authoritative

if header.auth?
  puts "Response is authoritative"
else
  puts "Answer is NOT authoritative"
end
# File lib/net/dns/header.rb, line 417
def auth?
  @aa == 1
end
cd=(val) click to toggle source

Set the cd flag (checking disabled) to either true ot false. You can also use 0 or 1.

# File lib/net/dns/header.rb, line 557
def cd=(val)
  case val
  when true
    @cd = 1
  when false
    @cd = 0
  when 0,1
    @cd = val
  else
    raise ArgumentError, ":cd must be true(or 1) or false(or 0)"
  end
end
checking?() click to toggle source

Checks whether checking is enabled or disabled.

Checking is enabled by default.

# File lib/net/dns/header.rb, line 550
def checking?
  @cd == 0
end
data() click to toggle source

Returns the header data in binary format, appropriate for use in a DNS query packet.

hdata = header.data
puts "Header is #{hdata.size} bytes"
# File lib/net/dns/header.rb, line 323
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?() click to toggle source

Checks for errors in the DNS packet

unless header.error?
  puts "No errors in DNS answer packet"
end
# File lib/net/dns/header.rb, line 616
def error?
  @rCode.code > 0
end
format() click to toggle source

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 :)

# File lib/net/dns/header.rb, line 297
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
id=(val) click to toggle source

Set the ID for the current header. Useful when performing security tests.

# File lib/net/dns/header.rb, line 338
def id=(val)
  if (0..65535).include? val
    @id = val
  else
    raise ArgumentError, "ID `#{val}' out of range"
  end
end
inspect() click to toggle source

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.

# File lib/net/dns/header.rb, line 255
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
nsCount=(val) click to toggle source

Sets the number of RRs in an authority section

# File lib/net/dns/header.rb, line 649
def nsCount=(val)
  if (0..65535).include? val
    @nsCount = val
  else
    raise WrongCountError, "Wrong number of count (#{val}), must be 0-65535"
  end
end
opCode=(val) click to toggle source

Set the opCode variable to a new value. This fields indicates the type of the question present in the DNS packet; val can be one of the values QUERY, IQUERY or STATUS.

  • QUERY is the standard DNS query

  • IQUERY is the inverse query

  • STATUS is used to query the nameserver for its status

Example:

include Net::DNS
header = Header.new
header.opCode = Header::STATUS
# File lib/net/dns/header.rb, line 401
def opCode=(val)
  if (0..2).include? val
    @opCode = val
  else
    raise WrongOpcodeError, "Wrong opCode value (#{val}), must be QUERY, IQUERY or STATUS"
  end
end
opCode_str() click to toggle source

Returns a string representation of the opCode

puts "Packet is a #{header.opCode_str}"
#=> Packet is a QUERY
# File lib/net/dns/header.rb, line 383
def opCode_str
  OPARR[@opCode]
end
qdCount=(val) click to toggle source

Sets the number of entries in a question section

# File lib/net/dns/header.rb, line 629
def qdCount=(val)
  if (0..65535).include? val
    @qdCount = val
  else
    raise WrongCountError, "Wrong number of count (#{val}), must be 0-65535"
  end
end
qr=(val) click to toggle source

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.

# File lib/net/dns/header.rb, line 358
def qr=(val)
  case val
  when true
    @qr = 1
  when false
    @qr = 0
  when 0,1
    @qr = val
  else
    raise ArgumentError, ":qr must be true(or 1) or false(or 0)"
  end
end
query?() click to toggle source

Checks whether the header is a query (qr bit set to 0)

# File lib/net/dns/header.rb, line 348
def query?
  @qr == 0
end
rCode=(val) click to toggle source

Set the rCode value. This should only be done in DNS answer packets.

# File lib/net/dns/header.rb, line 623
def rCode=(val)
  @rCode = RCode.new(val)
end
rCode_str() click to toggle source

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
# File lib/net/dns/header.rb, line 606
def rCode_str
  return rCode.type, rCode.explanation
end
r_available?() click to toggle source

Checks whether recursion is available. This flag is usually set by nameservers to indicate that they support recursive-type queries.

# File lib/net/dns/header.rb, line 524
def r_available?
  @ra == 1
end
ra=(val) click to toggle source

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.

# File lib/net/dns/header.rb, line 533
def ra=(val)
  case val
  when true
    @ra = 1
  when false
    @ra = 0
  when 0,1
    @ra = val
  else
    raise ArgumentError, ":ra must be true(or 1) or false(or 0)"
  end
end
rd=(val) click to toggle source

Alias for Header#recursive= to keep compatibility with the Perl version.

# File lib/net/dns/header.rb, line 516
def rd=(val)
  self.recursive = val
end
recursive=(val) click to toggle source

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.

# File lib/net/dns/header.rb, line 498
def recursive=(val)
  case val
  when true
    @rd = 1
  when false
    @rd = 0
  when 1
    @rd = 1
  when 0
    @rd = 0
  else
    raise WrongRecursiveError, "Wrong value (#{val}), please specify true (1) or false (0)"
  end
end
recursive?() click to toggle source

Checks whether the packet has a recursion bit set, meaning that recursion is desired

# File lib/net/dns/header.rb, line 484
def recursive?
  @rd == 1
end
response?() click to toggle source

Checks whether the header is a response (qr bit set to 1)

# File lib/net/dns/header.rb, line 374
def response?
  @qr == 1
end
tc=(val) click to toggle source

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.

# File lib/net/dns/header.rb, line 468
def tc=(val)
  case val
  when true
    @tc = 1
  when false
    @tc = 0
  when 0,1
    @tc = val
  else
    raise ArgumentError, ":tc must be true(or 1) or false(or 0)"
  end
end
truncated?() click to toggle source

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
# File lib/net/dns/header.rb, line 452
def truncated?
  @tc == 1
end
verified?() click to toggle source

Checks whether ad flag has been set.

This flag is only relevant in DNSSEC context.

# File lib/net/dns/header.rb, line 574
def verified?
  @ad == 1
end

[Validate]

Generated with the Darkfish Rdoc Generator 2.