Class: Dnsruby::Header

Inherits:
Object
  • Object
show all
Defined in:
lib/dnsruby/message/header.rb

Overview

The header portion of a DNS packet

RFC 1035 Section 4.1.1

Constant Summary collapse

MAX_ID =
65535

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(*args) ⇒ Header

Returns a new instance of Header.



61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/dnsruby/message/header.rb', line 61

def initialize(*args)
  if (args.length == 0)
    @id = rand(MAX_ID)
    @qr = false
    @opcode = OpCode.Query
    @aa = false
    @ad = false
    @tc = false
    @rd = false # recursion desired
    @ra = false # recursion available
    @cd = false
    @rcode = RCode.NoError
    @qdcount = 0
    @nscount = 0
    @ancount = 0
    @arcount = 0
  elsif args.length == 1
    decode(args[0])
  end
end

Instance Attribute Details

#aaObject

Authoritative answer flag



16
17
18
# File 'lib/dnsruby/message/header.rb', line 16

def aa
  @aa
end

#adObject

The Authenticated Data flag

Relevant in DNSSEC context.
(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.)


32
33
34
# File 'lib/dnsruby/message/header.rb', line 32

def ad
  @ad
end

#ancountObject Also known as: prcount

The number of records in the answer section of the message



57
58
59
# File 'lib/dnsruby/message/header.rb', line 57

def ancount
  @ancount
end

#arcountObject Also known as: adcount

The number of records in the additional record section og the message



59
60
61
# File 'lib/dnsruby/message/header.rb', line 59

def arcount
  @arcount
end

#cdObject

The Checking Disabled flag



25
26
27
# File 'lib/dnsruby/message/header.rb', line 25

def cd
  @cd
end

#idObject

The header ID



10
11
12
# File 'lib/dnsruby/message/header.rb', line 10

def id
  @id
end

#nscountObject Also known as: upcount

The number of records in the authoriy section of the message



55
56
57
# File 'lib/dnsruby/message/header.rb', line 55

def nscount
  @nscount
end

#opcodeObject

The header opcode



50
51
52
# File 'lib/dnsruby/message/header.rb', line 50

def opcode
  @opcode
end

#qdcountObject Also known as: zocount

The number of records in the question section of the message



53
54
55
# File 'lib/dnsruby/message/header.rb', line 53

def qdcount
  @qdcount
end

#qrObject

The query response flag



13
14
15
# File 'lib/dnsruby/message/header.rb', line 13

def qr
  @qr
end

#raObject

Recursion available flag



35
36
37
# File 'lib/dnsruby/message/header.rb', line 35

def ra
  @ra
end

#rdObject

Recursion Desired flag



22
23
24
# File 'lib/dnsruby/message/header.rb', line 22

def rd
  @rd
end

#tcObject

Truncated flag



19
20
21
# File 'lib/dnsruby/message/header.rb', line 19

def tc
  @tc
end

Class Method Details

.decrement_arcount_encoded(bytes) ⇒ Object



118
119
120
121
122
123
124
125
126
127
128
# File 'lib/dnsruby/message/header.rb', line 118

def Header.decrement_arcount_encoded(bytes)
  header = Header.new
  header_end = 0
  MessageDecoder.new(bytes) do |msg|
    header.decode(msg)
    header_end = msg.index
  end
  header.arcount -= 1
  bytes[0, header_end] = MessageEncoder.new { |msg| header.encode(msg) }.to_s
  bytes
end

.new_from_data(data) ⇒ Object



90
91
92
93
94
# File 'lib/dnsruby/message/header.rb', line 90

def Header.new_from_data(data)
  header = Header.new
  MessageDecoder.new(data) { |msg| header.decode(msg) }
  header
end

Instance Method Details

#==(other) ⇒ Object



130
131
132
133
134
135
136
137
138
139
140
# File 'lib/dnsruby/message/header.rb', line 130

def ==(other)
  @qr == other.qr &&
      @opcode == other.opcode &&
      @aa == other.aa &&
      @tc == other.tc &&
      @rd == other.rd &&
      @ra == other.ra &&
      @cd == other.cd &&
      @ad == other.ad &&
      @rcode == other.get_header_rcode
end

#dataObject



96
97
98
# File 'lib/dnsruby/message/header.rb', line 96

def data
  MessageEncoder.new { |msg| self.encode(msg) }.to_s
end

#decode(msg) ⇒ Object



219
220
221
222
223
224
225
226
227
228
229
230
231
# File 'lib/dnsruby/message/header.rb', line 219

def decode(msg)
  @id, flag, @qdcount, @ancount, @nscount, @arcount =
      msg.get_unpack('nnnnnn')
  @qr = ((flag >> 15) & 1) == 1
  @opcode = OpCode.new((flag >> 11) & 15)
  @aa = ((flag >> 10) & 1) == 1
  @tc = ((flag >> 9)  & 1) == 1
  @rd = ((flag >> 8)  & 1) == 1
  @ra = ((flag >> 7)  & 1) == 1
  @ad = ((flag >> 5)  & 1) == 1
  @cd = ((flag >> 4)  & 1) == 1
  @rcode = RCode.new(flag & 15)
end

#encode(msg) ⇒ Object



100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/dnsruby/message/header.rb', line 100

def encode(msg)
  msg.put_pack('nnnnnn',
               @id,
               (@qr ? 1:0) << 15 |
                   (@opcode.code & 15) << 11 |
                   (@aa ? 1:0) << 10 |
                   (@tc ? 1:0) << 9 |
                   (@rd ? 1:0) << 8 |
                   (@ra ? 1:0) << 7 |
                   (@ad ? 1:0) << 5 |
                   (@cd ? 1:0) << 4 |
                   (@rcode.code & 15),
               @qdcount,
               @ancount,
               @nscount,
               @arcount)
end

#get_header_rcodeObject

This new get_header_rcode method is intended for use only by the Message class.

This is because the Message OPT section may contain an extended rcode (see
RFC 2671 section 4.6). Using the header rcode only ignores this extension, and
is not recommended.


45
46
47
# File 'lib/dnsruby/message/header.rb', line 45

def get_header_rcode
  @rcode
end

#old_to_sObject



146
147
148
# File 'lib/dnsruby/message/header.rb', line 146

def old_to_s
  old_to_s_with_rcode(@rcode)
end

#old_to_s_with_rcode(rcode) ⇒ Object



186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
# File 'lib/dnsruby/message/header.rb', line 186

def old_to_s_with_rcode(rcode)
  retval = ";; id = #{@id}\n"

  if (@opcode == OpCode::Update)
    retval += ";; qr = #{@qr}    " \
      "opcode = #{@opcode.string}    "\
      "rcode = #{@rcode.string}\n"

    retval += ";; zocount = #{@qdcount}  "\
      "prcount = #{@ancount}  " \
      "upcount = #{@nscount}  "  \
      "adcount = #{@arcount}\n"
  else
    retval += ";; qr = #{@qr}    "  \
      "opcode = #{@opcode.string}    " \
      "aa = #{@aa}    "  \
      "tc = #{@tc}    " \
      "rd = #{@rd}\n"

    retval += ";; ra = #{@ra}    " \
      "ad = #{@ad}    "  \
      "cd = #{@cd}    "  \
      "rcode  = #{rcode.string}\n"

    retval += ";; qdcount = #{@qdcount}  " \
      "ancount = #{@ancount}  " \
      "nscount = #{@nscount}  " \
      "arcount = #{@arcount}\n"
  end

  retval
end

#rcode=(rcode) ⇒ Object



86
87
88
# File 'lib/dnsruby/message/header.rb', line 86

def rcode=(rcode)
  @rcode = RCode.new(rcode)
end

#to_sObject



142
143
144
# File 'lib/dnsruby/message/header.rb', line 142

def to_s
  to_s_with_rcode(@rcode)
end

#to_s_with_rcode(rcode) ⇒ Object



150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
# File 'lib/dnsruby/message/header.rb', line 150

def to_s_with_rcode(rcode)

  if @opcode == OpCode::Update
    s = ";; id = #{@id}\n"
    s << ";; qr = #{@qr}    opcode = #{@opcode.string}    rcode = #{@rcode.string}\n"
    s << ";; zocount = #{@qdcount}  "
    s <<  "prcount = #{@ancount}  "
    s <<  "upcount = #{@nscount}  "
    s <<  "adcount = #{@arcount}\n"
    s
  else

    flags_str = begin
      flags = []
      flags << 'qr' if @qr
      flags << 'aa' if @aa
      flags << 'tc' if @tc
      flags << 'rd' if @rd
      flags << 'ra' if @ra
      flags << 'ad' if @ad
      flags << 'cd' if @cd

      ";; flags: #{flags.join(' ')}; "
    end

    head_line_str =
        ";; ->>HEADER<<- opcode: #{opcode.string.upcase}, status: #{@rcode.string}, id: #{@id}\n"

    section_counts_str =
        "QUERY: #{@qdcount}, ANSWER: #{@ancount}, AUTHORITY: #{@nscount}, ADDITIONAL: #{@arcount}\n"

    head_line_str + flags_str + section_counts_str
  end
end