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.



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

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



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

def ancount
  @ancount
end

#arcountObject Also known as: adcount

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



62
63
64
# File 'lib/dnsruby/message/header.rb', line 62

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



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

def nscount
  @nscount
end

#opcodeObject

The header opcode



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

def opcode
  @opcode
end

#qdcountObject Also known as: zocount

The number of records in the question section of the message



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

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



38
39
40
# File 'lib/dnsruby/message/header.rb', line 38

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



121
122
123
124
125
126
127
128
129
130
131
# File 'lib/dnsruby/message/header.rb', line 121

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



93
94
95
96
97
# File 'lib/dnsruby/message/header.rb', line 93

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

Instance Method Details

#==(other) ⇒ Object



133
134
135
136
137
138
139
140
141
142
143
# File 'lib/dnsruby/message/header.rb', line 133

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



99
100
101
# File 'lib/dnsruby/message/header.rb', line 99

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

#decode(msg) ⇒ Object



222
223
224
225
226
227
228
229
230
231
232
233
234
# File 'lib/dnsruby/message/header.rb', line 222

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



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

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.


48
49
50
# File 'lib/dnsruby/message/header.rb', line 48

def get_header_rcode
  @rcode
end

#old_to_sObject



149
150
151
# File 'lib/dnsruby/message/header.rb', line 149

def old_to_s
  old_to_s_with_rcode(@rcode)
end

#old_to_s_with_rcode(rcode) ⇒ Object



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
218
219
220
# File 'lib/dnsruby/message/header.rb', line 189

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



89
90
91
# File 'lib/dnsruby/message/header.rb', line 89

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

#to_sObject



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

def to_s
  to_s_with_rcode(@rcode)
end

#to_s_with_rcode(rcode) ⇒ Object



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
184
185
186
# File 'lib/dnsruby/message/header.rb', line 153

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