Class: PacketGen::Header::DNS

Inherits:
Base show all
Defined in:
lib/packetgen/header/dns.rb,
lib/packetgen/header/dns.rb,
lib/packetgen/header/dns/rr.rb,
lib/packetgen/header/dns/opt.rb,
lib/packetgen/header/dns/name.rb,
lib/packetgen/header/dns/option.rb,
lib/packetgen/header/dns/question.rb,
lib/packetgen/header/dns/qdsection.rb,
lib/packetgen/header/dns/rrsection.rb

Overview

DNS: Domain Name Service

A DNS packet consists of a header:

                                1  1  1  1  1  1
  0  1  2  3  4  5  6  7  8  9  0  1  2  3  4  5
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|                      ID                       |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|QR|   Opcode  |AA|TC|RD|RA|   Z    |   RCODE   |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|                    QDCOUNT                    |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|                    ANCOUNT                    |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|                    NSCOUNT                    |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|                    ARCOUNT                    |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+

A DNS packet also contains up to 4 sections:

  • #qd, question section,

  • #an, answer section,

  • #ns, authoritary section,

  • #ar, additional information section.

Create a DNS header

# standalone
dns = PacketGen::Header::DNS.new
# in a IP packet
pkt = PacketGen.gen('IP').add('DNS')
# access to DNS header
pkt.dns   # => PacketGen::Header::DNS

DNS attributes

dns.id = 0x1234
dns.qr = false
# opcode may be set as an Integer (all values are possible)
# or as a String (only keys from PacketGen::Header::DNS::OPCODES)
dns.opcode = 0xe       # set as integer, value not defined in standard
dns.opcode = 'query'   # set as string
dns.aa = dns.tc = dns.rd = dns.ra = false
# rcode may be set as an Integer (all values are possible)
# or as a String (only keys from PacketGen::Header::DNS::RCODES)
dns.rcode = 11
dns.rcode = 'refused'
dns.qdcount = 123
dns.ancount = 0x1234
dns.nscount = 1
dns.arcount = 0

One can also access to DNS sections:

dns.qd   # => PacketGen::Header::DNS::QDSection
dns.an   # => PacketGen::Header::DNS::RRSection
dns.ns   # => PacketGen::Header::DNS::RRSection
dns.ar   # => PacketGen::Header::DNS::RRSection

Add a question to DNS question section

Adding a Question with QDSection#<< automagically increments #qdcount. To not modify qdcount, use QDSection#push.

# add a question about example.net IP address. Increment qdcount
dns.qd << PacketGen::Header::DNS::Question.new(dns, name: 'example.net')
# or
dns.qd << { rtype: 'Question', name: 'example.net' }
# add a question about example.net IPv6 address. Dot not modify qdcount
dns.qd.push PacketGen::Header::DNS::Question.new(dns, name: 'example.net', type: 'AAAA')
# or
dns.qd.push({ rtype: 'Question', name: 'example.net', type: 'AAAA' })

Add a ressource record to a DNS section

Adding a RR with RRSection#<< automagically increments section counter. To not modify it, use RRSection#push

# add a RR to answer section. Increment ancount
dns.an << PacketGen::Header::DNS::RR.new(dns, name: 'example.net', rdata: IPAddr.new('1.2.3.4').hton)
# or
dns.an << { rtype: 'RR', name: 'example.net', rdata: IPAddr.new('1.2.3.4').hton }
# add a RR to NS section. Dot not modify nscount
rdata = PacketGen::Header::DNS::Name.new(dns).parse('dns.net')
dns.ns.push PacketGen::Header::DNS::RR.new(dns, name: 'example.net', type: 'NS', rdata: rdata)
# or
dns.ns.push(rtype: 'RR', name: 'example.net', type: 'NS', rdata: rdata)

Extended DNS EDNS(0)

# Add an OPT to ar section
dns.ar << PacketGen::Header::DNS::OPT.new(dns, udp_size: 4096, ext_rcode: 43)
# or
dns.ar << { rtype: 'OPT', udp_size: 4096, ext_rcode: 43 }
# add an option to OPT record
dns.ar.last.options << PacketGen::Header::DNS::Option.new(code: 48, data: '12')
# or
dns.ar.last.options << { code: 48, data: '12' }

Author:

  • Sylvain Daubert

Since:

  • 1.3.0

Direct Known Subclasses

MDNS

Defined Under Namespace

Classes: ArrayOfOptions, Name, OPT, Option, QDSection, Question, RR, RRSection

Constant Summary collapse

UDP_PORT =

Port number for DNS over UDP

Since:

  • 1.3.0

53
TCP_PORT =

Port number for DNS over TCP

Since:

  • 1.3.0

UDP_PORT
OPCODES =

DNS opcodes

Since:

  • 1.3.0

{
  'query' => 0,
  'iquery' => 1,
  'status' => 2,
  'notify' => 4,
  'update' => 5
}.freeze
RCODES =

DNS Response codes

Since:

  • 1.3.0

{
  'ok' => 0,
  'no-error' => 0,
  'format-error' => 1,
  'server-failure' => 2,
  'name-error' => 3,
  'not-implemented' => 4,
  'refused' => 5
}.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods inherited from Base

bind, calculate_and_set_length, #header_id, inherited, #initialize, #ip_header, #ll_header

Methods included from PacketGen::Headerable

#added_to_packet, included, #method_name, #packet, #packet=, #parse?, #protocol_name, #read

Methods inherited from Types::Fields

#[], #[]=, #bits_on, define_bit_fields_on, define_field, define_field_after, define_field_before, #fields, fields, inherited, #initialize, #offset_of, #optional?, #optional_fields, #present?, #read, remove_bit_fields_on, remove_field, #sz, #to_h, #to_s, update_field

Constructor Details

This class inherits a constructor from PacketGen::Header::Base

Instance Attribute Details

#aaBoolean

Returns Authoritative answer.

Returns:

  • (Boolean)

    Authoritative answer



190
191
# File 'lib/packetgen/header/dns.rb', line 190

define_bit_fields_on :u16, :qr, :opcode, 4, :aa, :tc, :rd, :ra, :z,
:ad, :cd, :rcode, 4

#adBoolean

Returns Authentic Data.

Returns:

  • (Boolean)

    Authentic Data



190
191
# File 'lib/packetgen/header/dns.rb', line 190

define_bit_fields_on :u16, :qr, :opcode, 4, :aa, :tc, :rd, :ra, :z,
:ad, :cd, :rcode, 4

#anRRSection

Returns:



164
# File 'lib/packetgen/header/dns.rb', line 164

define_field :an, RRSection, builder: ->(h, t) { t.new(h, h[:ancount]) }

#ancountInteger

Returns:

  • (Integer)


152
# File 'lib/packetgen/header/dns.rb', line 152

define_field :ancount, Types::Int16

#arRRSection

Returns:



170
# File 'lib/packetgen/header/dns.rb', line 170

define_field :ar, RRSection, builder: ->(h, t) { t.new(h, h[:arcount]) }

#arcountInteger

Returns:

  • (Integer)


158
# File 'lib/packetgen/header/dns.rb', line 158

define_field :arcount, Types::Int16

#cdBoolean

Returns Checking Disabled.

Returns:

  • (Boolean)

    Checking Disabled



190
191
# File 'lib/packetgen/header/dns.rb', line 190

define_bit_fields_on :u16, :qr, :opcode, 4, :aa, :tc, :rd, :ra, :z,
:ad, :cd, :rcode, 4

#idInteger

Returns:

  • (Integer)


143
# File 'lib/packetgen/header/dns.rb', line 143

define_field :id, Types::Int16

#nsRRSection

Returns:



167
# File 'lib/packetgen/header/dns.rb', line 167

define_field :ns, RRSection, builder: ->(h, t) { t.new(h, h[:nscount]) }

#nscountInteger

Returns:

  • (Integer)


155
# File 'lib/packetgen/header/dns.rb', line 155

define_field :nscount, Types::Int16

#opcodeInteger

Returns Kind of query. See OPCODES.

Returns:

  • (Integer)

    Kind of query. See OPCODES.



190
191
# File 'lib/packetgen/header/dns.rb', line 190

define_bit_fields_on :u16, :qr, :opcode, 4, :aa, :tc, :rd, :ra, :z,
:ad, :cd, :rcode, 4

#qdQDSection

Returns:



161
# File 'lib/packetgen/header/dns.rb', line 161

define_field :qd, QDSection, builder: ->(h, t) { t.new(h, h[:qdcount]) }

#qdcountInteger

Returns:

  • (Integer)


149
# File 'lib/packetgen/header/dns.rb', line 149

define_field :qdcount, Types::Int16

#qrBoolean

Returns query (false) or response (true).

Returns:

  • (Boolean)

    query (false) or response (true)



190
191
# File 'lib/packetgen/header/dns.rb', line 190

define_bit_fields_on :u16, :qr, :opcode, 4, :aa, :tc, :rd, :ra, :z,
:ad, :cd, :rcode, 4

#raBoolean

Returns Recursion Available.

Returns:

  • (Boolean)

    Recursion Available



190
191
# File 'lib/packetgen/header/dns.rb', line 190

define_bit_fields_on :u16, :qr, :opcode, 4, :aa, :tc, :rd, :ra, :z,
:ad, :cd, :rcode, 4

#rcodeInteger

Returns Response code. See RCODES.

Returns:

  • (Integer)

    Response code. See RCODES.



190
191
# File 'lib/packetgen/header/dns.rb', line 190

define_bit_fields_on :u16, :qr, :opcode, 4, :aa, :tc, :rd, :ra, :z,
:ad, :cd, :rcode, 4

#rdBoolean

Returns Recursion Desired.

Returns:

  • (Boolean)

    Recursion Desired



190
191
# File 'lib/packetgen/header/dns.rb', line 190

define_bit_fields_on :u16, :qr, :opcode, 4, :aa, :tc, :rd, :ra, :z,
:ad, :cd, :rcode, 4

#tcBoolean

Returns Truncation.

Returns:

  • (Boolean)

    Truncation



190
191
# File 'lib/packetgen/header/dns.rb', line 190

define_bit_fields_on :u16, :qr, :opcode, 4, :aa, :tc, :rd, :ra, :z,
:ad, :cd, :rcode, 4

#u16Integer

Returns:

  • (Integer)


146
# File 'lib/packetgen/header/dns.rb', line 146

define_field :u16, Types::Int16

Instance Method Details

#inspectString

Returns:

  • (String)

Since:

  • 1.3.0



240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
# File 'lib/packetgen/header/dns.rb', line 240

def inspect
  super do |attr|
    next unless attr == :u16

    str = inspect_flags

    str << Inspect.shift_level
    opcode = '%-16s (%u)' % [OPCODES.key(self.opcode), self.opcode]
    str << Inspect::FMT_ATTR % ['Integer', 'opcode', opcode]

    str << Inspect.shift_level
    rcode = '%-16s (%u)' % [RCODES.key(self.rcode), self.rcode]
    str << Inspect::FMT_ATTR % ['Integer', 'rcode', rcode]
  end
end

#query?Boolean

Is message a query

Returns:

  • (Boolean)

Since:

  • 1.3.0



235
236
237
# File 'lib/packetgen/header/dns.rb', line 235

def query?
  !qr?
end

#response?Boolean

Is message a response

Returns:

  • (Boolean)

Since:

  • 1.3.0



229
230
231
# File 'lib/packetgen/header/dns.rb', line 229

def response?
  qr?
end