dnsruby 1.55 → 1.56.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (158) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +96 -0
  3. data/Rakefile +30 -29
  4. data/demo/axfr.rb +93 -93
  5. data/demo/check_soa.rb +99 -99
  6. data/demo/check_zone.rb +59 -59
  7. data/demo/digdlv.rb +43 -43
  8. data/demo/digroot.rb +34 -34
  9. data/demo/example_recurse.rb +14 -14
  10. data/demo/mresolv.rb +30 -30
  11. data/demo/mx.rb +31 -31
  12. data/demo/rubydig.rb +37 -37
  13. data/demo/to_resolve.txt +3088 -3088
  14. data/demo/trace_dns.rb +46 -46
  15. data/lib/dnsruby.rb +161 -526
  16. data/lib/dnsruby/DNS.rb +305 -0
  17. data/lib/{Dnsruby/Cache.rb → dnsruby/cache.rb} +152 -152
  18. data/lib/{Dnsruby → dnsruby}/code_mapper.rb +48 -52
  19. data/lib/dnsruby/code_mappers.rb +295 -0
  20. data/lib/{Dnsruby/Config.rb → dnsruby/config.rb} +454 -454
  21. data/lib/{Dnsruby → dnsruby}/dnssec.rb +91 -91
  22. data/lib/{Dnsruby/Hosts.rb → dnsruby/hosts.rb} +125 -125
  23. data/lib/{Dnsruby → dnsruby}/ipv4.rb +26 -26
  24. data/lib/{Dnsruby → dnsruby}/ipv6.rb +42 -42
  25. data/lib/{Dnsruby → dnsruby}/key_cache.rb +29 -29
  26. data/lib/dnsruby/message/decoder.rb +164 -0
  27. data/lib/dnsruby/message/encoder.rb +75 -0
  28. data/lib/dnsruby/message/header.rb +249 -0
  29. data/lib/dnsruby/message/message.rb +629 -0
  30. data/lib/dnsruby/message/question.rb +86 -0
  31. data/lib/dnsruby/message/section.rb +96 -0
  32. data/lib/{Dnsruby → dnsruby}/name.rb +141 -141
  33. data/lib/dnsruby/packet_sender.rb +661 -0
  34. data/lib/{Dnsruby/Recursor.rb → dnsruby/recursor.rb} +235 -233
  35. data/lib/dnsruby/resolv.rb +113 -0
  36. data/lib/dnsruby/resolver.rb +1192 -0
  37. data/lib/dnsruby/resource/A.rb +56 -0
  38. data/lib/dnsruby/resource/AAAA.rb +54 -0
  39. data/lib/{Dnsruby → dnsruby}/resource/AFSDB.rb +68 -68
  40. data/lib/{Dnsruby → dnsruby}/resource/CERT.rb +105 -105
  41. data/lib/{Dnsruby → dnsruby}/resource/DHCID.rb +54 -54
  42. data/lib/dnsruby/resource/DLV.rb +27 -0
  43. data/lib/{Dnsruby → dnsruby}/resource/DNSKEY.rb +372 -372
  44. data/lib/{Dnsruby → dnsruby}/resource/DS.rb +255 -255
  45. data/lib/{Dnsruby → dnsruby}/resource/HINFO.rb +71 -71
  46. data/lib/{Dnsruby → dnsruby}/resource/HIP.rb +29 -29
  47. data/lib/{Dnsruby → dnsruby}/resource/IN.rb +30 -30
  48. data/lib/{Dnsruby → dnsruby}/resource/IPSECKEY.rb +31 -31
  49. data/lib/{Dnsruby → dnsruby}/resource/ISDN.rb +62 -62
  50. data/lib/{Dnsruby → dnsruby}/resource/KX.rb +65 -65
  51. data/lib/{Dnsruby → dnsruby}/resource/LOC.rb +263 -263
  52. data/lib/{Dnsruby → dnsruby}/resource/MINFO.rb +69 -69
  53. data/lib/{Dnsruby → dnsruby}/resource/MX.rb +65 -65
  54. data/lib/{Dnsruby → dnsruby}/resource/NAPTR.rb +98 -98
  55. data/lib/{Dnsruby → dnsruby}/resource/NSAP.rb +171 -171
  56. data/lib/dnsruby/resource/NSEC.rb +275 -0
  57. data/lib/dnsruby/resource/NSEC3.rb +332 -0
  58. data/lib/dnsruby/resource/NSEC3PARAM.rb +135 -0
  59. data/lib/dnsruby/resource/OPT.rb +272 -0
  60. data/lib/{Dnsruby → dnsruby}/resource/PX.rb +70 -70
  61. data/lib/{Dnsruby → dnsruby}/resource/RP.rb +75 -75
  62. data/lib/dnsruby/resource/RR.rb +421 -0
  63. data/lib/dnsruby/resource/RRSIG.rb +275 -0
  64. data/lib/dnsruby/resource/RRSet.rb +190 -0
  65. data/lib/{Dnsruby → dnsruby}/resource/RT.rb +67 -67
  66. data/lib/{Dnsruby → dnsruby}/resource/SOA.rb +94 -94
  67. data/lib/dnsruby/resource/SPF.rb +29 -0
  68. data/lib/dnsruby/resource/SRV.rb +112 -0
  69. data/lib/{Dnsruby → dnsruby}/resource/SSHFP.rb +14 -14
  70. data/lib/dnsruby/resource/TKEY.rb +163 -0
  71. data/lib/dnsruby/resource/TSIG.rb +593 -0
  72. data/lib/{Dnsruby → dnsruby}/resource/TXT.rb +191 -191
  73. data/lib/dnsruby/resource/X25.rb +55 -0
  74. data/lib/{Dnsruby → dnsruby}/resource/domain_name.rb +25 -25
  75. data/lib/{Dnsruby → dnsruby}/resource/generic.rb +80 -80
  76. data/lib/dnsruby/resource/resource.rb +25 -0
  77. data/lib/{Dnsruby → dnsruby}/select_thread.rb +148 -148
  78. data/lib/{Dnsruby/SingleResolver.rb → dnsruby/single_resolver.rb} +60 -60
  79. data/lib/{Dnsruby → dnsruby}/single_verifier.rb +344 -344
  80. data/lib/dnsruby/the_log.rb +44 -0
  81. data/lib/dnsruby/update.rb +278 -0
  82. data/lib/dnsruby/validator_thread.rb +124 -0
  83. data/lib/dnsruby/version.rb +3 -0
  84. data/lib/{Dnsruby → dnsruby}/zone_reader.rb +93 -93
  85. data/lib/{Dnsruby → dnsruby}/zone_transfer.rb +377 -377
  86. data/test/spec_helper.rb +16 -0
  87. data/test/tc_axfr.rb +31 -34
  88. data/test/tc_cache.rb +32 -32
  89. data/test/tc_dlv.rb +28 -28
  90. data/test/tc_dns.rb +73 -76
  91. data/test/tc_dnskey.rb +31 -32
  92. data/test/tc_dnsruby.rb +50 -44
  93. data/test/tc_ds.rb +36 -36
  94. data/test/tc_escapedchars.rb +252 -255
  95. data/test/tc_hash.rb +17 -21
  96. data/test/tc_header.rb +48 -57
  97. data/test/tc_hip.rb +19 -22
  98. data/test/tc_ipseckey.rb +18 -21
  99. data/test/tc_keith.rb +300 -0
  100. data/test/tc_message.rb +87 -0
  101. data/test/tc_misc.rb +83 -87
  102. data/test/tc_name.rb +81 -84
  103. data/test/tc_naptr.rb +18 -21
  104. data/test/tc_nsec.rb +55 -55
  105. data/test/tc_nsec3.rb +23 -24
  106. data/test/tc_nsec3param.rb +20 -21
  107. data/test/tc_packet.rb +90 -93
  108. data/test/tc_packet_unique_push.rb +48 -51
  109. data/test/tc_question.rb +30 -33
  110. data/test/tc_queue.rb +16 -17
  111. data/test/tc_recur.rb +16 -17
  112. data/test/tc_res_config.rb +38 -41
  113. data/test/tc_res_env.rb +29 -32
  114. data/test/tc_res_file.rb +26 -29
  115. data/test/tc_res_opt.rb +62 -65
  116. data/test/tc_resolver.rb +287 -242
  117. data/test/tc_rr-opt.rb +70 -63
  118. data/test/tc_rr-txt.rb +68 -71
  119. data/test/tc_rr-unknown.rb +45 -48
  120. data/test/tc_rr.rb +76 -70
  121. data/test/tc_rrset.rb +21 -22
  122. data/test/tc_rrsig.rb +19 -20
  123. data/test/tc_single_resolver.rb +294 -297
  124. data/test/tc_soak.rb +199 -202
  125. data/test/tc_soak_base.rb +29 -34
  126. data/test/tc_sshfp.rb +20 -23
  127. data/test/tc_tcp.rb +32 -35
  128. data/test/tc_tkey.rb +41 -44
  129. data/test/tc_tsig.rb +81 -84
  130. data/test/tc_update.rb +108 -111
  131. data/test/tc_validator.rb +29 -29
  132. data/test/tc_verifier.rb +81 -82
  133. data/test/ts_dnsruby.rb +16 -15
  134. data/test/ts_offline.rb +62 -63
  135. data/test/ts_online.rb +115 -115
  136. metadata +155 -90
  137. data/README +0 -59
  138. data/lib/Dnsruby/DNS.rb +0 -305
  139. data/lib/Dnsruby/PacketSender.rb +0 -656
  140. data/lib/Dnsruby/Resolver.rb +0 -1189
  141. data/lib/Dnsruby/TheLog.rb +0 -44
  142. data/lib/Dnsruby/message.rb +0 -1230
  143. data/lib/Dnsruby/resource/A.rb +0 -56
  144. data/lib/Dnsruby/resource/AAAA.rb +0 -54
  145. data/lib/Dnsruby/resource/DLV.rb +0 -27
  146. data/lib/Dnsruby/resource/NSEC.rb +0 -298
  147. data/lib/Dnsruby/resource/NSEC3.rb +0 -340
  148. data/lib/Dnsruby/resource/NSEC3PARAM.rb +0 -135
  149. data/lib/Dnsruby/resource/OPT.rb +0 -213
  150. data/lib/Dnsruby/resource/RRSIG.rb +0 -275
  151. data/lib/Dnsruby/resource/SPF.rb +0 -29
  152. data/lib/Dnsruby/resource/SRV.rb +0 -112
  153. data/lib/Dnsruby/resource/TKEY.rb +0 -163
  154. data/lib/Dnsruby/resource/TSIG.rb +0 -593
  155. data/lib/Dnsruby/resource/X25.rb +0 -55
  156. data/lib/Dnsruby/resource/resource.rb +0 -678
  157. data/lib/Dnsruby/update.rb +0 -278
  158. data/lib/Dnsruby/validator_thread.rb +0 -124
@@ -1,23 +1,23 @@
1
- #--
2
- #Copyright 2007 Nominet UK
3
- #
4
- #Licensed under the Apache License, Version 2.0 (the "License");
5
- #you may not use this file except in compliance with the License.
6
- #You may obtain a copy of the License at
7
- #
8
- # http://www.apache.org/licenses/LICENSE-2.0
9
- #
10
- #Unless required by applicable law or agreed to in writing, software
11
- #distributed under the License is distributed on an "AS IS" BASIS,
12
- #WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
- #See the License for the specific language governing permissions and
14
- #limitations under the License.
15
- #++
1
+ # --
2
+ # Copyright 2007 Nominet UK
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ # ++
16
16
  module Dnsruby
17
17
  class IPv4
18
- # Regular expression IPv4 addresses must match
18
+ # Regular expression IPv4 addresses must match
19
19
  Regex = /\A(\d\d?\d?)\.(\d\d?\d?)\.(\d\d?\d?)\.(\d\d?\d?)\z/
20
-
20
+
21
21
  def self.create(arg)
22
22
  case arg
23
23
  when IPv4
@@ -35,38 +35,38 @@ module Dnsruby
35
35
  raise ArgumentError.new("cannot interpret as IPv4 address: #{arg.inspect}")
36
36
  end
37
37
  end
38
-
38
+
39
39
  def initialize(address) #:nodoc:
40
40
  unless address.kind_of?(String) && address.length == 4
41
41
  raise ArgumentError.new('IPv4 address must be 4 bytes')
42
42
  end
43
43
  @address = address
44
44
  end
45
-
46
- # A String representation of the IPv4 address.
45
+
46
+ # A String representation of the IPv4 address.
47
47
  attr_reader :address
48
-
48
+
49
49
  def to_s #:nodoc:
50
50
  return sprintf("%d.%d.%d.%d", *@address.unpack("CCCC"))
51
51
  end
52
-
52
+
53
53
  def inspect #:nodoc:
54
54
  return "#<#{self.class} #{self.to_s}>"
55
55
  end
56
-
56
+
57
57
  def to_name
58
58
  return Name.create(
59
59
  '%d.%d.%d.%d.in-addr.arpa.' % @address.unpack('CCCC').reverse)
60
60
  end
61
-
61
+
62
62
  def ==(other)
63
63
  return @address == other.address
64
64
  end
65
-
65
+
66
66
  def eql?(other)
67
67
  return self == other
68
68
  end
69
-
69
+
70
70
  def hash
71
71
  return @address.hash
72
72
  end
@@ -1,57 +1,57 @@
1
- #--
2
- #Copyright 2007 Nominet UK
3
- #
4
- #Licensed under the Apache License, Version 2.0 (the "License");
5
- #you may not use this file except in compliance with the License.
6
- #You may obtain a copy of the License at
7
- #
8
- # http://www.apache.org/licenses/LICENSE-2.0
9
- #
10
- #Unless required by applicable law or agreed to in writing, software
11
- #distributed under the License is distributed on an "AS IS" BASIS,
12
- #WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
- #See the License for the specific language governing permissions and
14
- #limitations under the License.
15
- #++
1
+ # --
2
+ # Copyright 2007 Nominet UK
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ # ++
16
16
  module Dnsruby
17
- #Dnsruby::IPv6 class
17
+ # Dnsruby::IPv6 class
18
18
  class IPv6
19
- #IPv6 address format a:b:c:d:e:f:g:h
19
+ # IPv6 address format a:b:c:d:e:f:g:h
20
20
  Regex_8Hex = /\A
21
21
  (?:[0-9A-Fa-f]{1,4}:){7}
22
22
  [0-9A-Fa-f]{1,4}
23
23
  \z/x
24
-
25
- #Compresses IPv6 format a::b
24
+
25
+ # Compresses IPv6 format a::b
26
26
  Regex_CompressedHex = /\A
27
27
  ((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?) ::
28
28
  ((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?)
29
29
  \z/x
30
-
31
- # IPv4 mapped IPv6 address format a:b:c:d:e:f:w.x.y.z
30
+
31
+ # IPv4 mapped IPv6 address format a:b:c:d:e:f:w.x.y.z
32
32
  Regex_6Hex4Dec = /\A
33
33
  ((?:[0-9A-Fa-f]{1,4}:){6,6})
34
34
  (\d+)\.(\d+)\.(\d+)\.(\d+)
35
35
  \z/x
36
-
37
- # Compressed IPv4 mapped IPv6 address format a::b:w.x.y.z
36
+
37
+ # Compressed IPv4 mapped IPv6 address format a::b:w.x.y.z
38
38
  Regex_CompressedHex4Dec = /\A
39
39
  ((?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?) ::
40
40
  ((?:[0-9A-Fa-f]{1,4}:)*)
41
41
  (\d+)\.(\d+)\.(\d+)\.(\d+)
42
42
  \z/x
43
-
44
- # A composite IPv6 address RegExp
43
+
44
+ # A composite IPv6 address RegExp
45
45
  Regex = /
46
46
  (?:#{Regex_8Hex}) |
47
47
  (?:#{Regex_CompressedHex}) |
48
48
  (?:#{Regex_6Hex4Dec}) |
49
49
  (?:#{Regex_CompressedHex4Dec})/x
50
-
51
- # Created a new IPv6 address from +arg+ which may be:
52
- #
53
- #* IPv6:: returns +arg+
54
- #* String:: +arg+ must match one of the IPv6::Regex* constants
50
+
51
+ # Created a new IPv6 address from +arg+ which may be:
52
+ #
53
+ # * IPv6:: returns +arg+
54
+ # * String:: +arg+ must match one of the IPv6::Regex* constants
55
55
  def self.create(arg)
56
56
  case arg
57
57
  when IPv6
@@ -97,17 +97,17 @@ module Dnsruby
97
97
  raise ArgumentError.new("cannot interpret as IPv6 address: #{arg.inspect}")
98
98
  end
99
99
  end
100
-
100
+
101
101
  def initialize(address) #:nodoc:
102
102
  unless address.kind_of?(String) && address.length == 16
103
103
  raise ArgumentError.new('IPv6 address must be 16 bytes')
104
104
  end
105
105
  @address = address
106
106
  end
107
-
108
- # The raw IPv6 address as a String
107
+
108
+ # The raw IPv6 address as a String
109
109
  attr_reader :address
110
-
110
+
111
111
  def to_s
112
112
  address = sprintf("%X:%X:%X:%X:%X:%X:%X:%X", *@address.unpack("nnnnnnnn"))
113
113
  unless address.sub!(/(^|:)0(:0)+(:|$)/, '::')
@@ -115,28 +115,28 @@ module Dnsruby
115
115
  end
116
116
  return address
117
117
  end
118
-
118
+
119
119
  def inspect #:nodoc:
120
120
  return "#<#{self.class} #{self.to_s}>"
121
121
  end
122
122
 
123
- #Turns this IPv6 address into a Dnsruby::Name
124
- #--
125
- # ip6.arpa should be searched too. [RFC3152]
123
+ # Turns this IPv6 address into a Dnsruby::Name
124
+ # --
125
+ # ip6.arpa should be searched too. [RFC3152]
126
126
  def to_name
127
127
  return Name.create(
128
- # @address.unpack("H32")[0].split(//).reverse + ['ip6', 'arpa'])
128
+ # @address.unpack("H32")[0].split(//).reverse + ['ip6', 'arpa'])
129
129
  @address.unpack("H32")[0].split(//).reverse.join(".") + ".ip6.arpa")
130
130
  end
131
-
131
+
132
132
  def ==(other) #:nodoc:
133
133
  return @address == other.address
134
134
  end
135
-
135
+
136
136
  def eql?(other) #:nodoc:
137
137
  return self == other
138
138
  end
139
-
139
+
140
140
  def hash
141
141
  return @address.hash
142
142
  end
@@ -1,25 +1,25 @@
1
- #--
2
- #Copyright 2007 Nominet UK
3
- #
4
- #Licensed under the Apache License, Version 2.0 (the "License");
5
- #you may not use this file except in compliance with the License.
6
- #You may obtain a copy of the License at
7
- #
1
+ # --
2
+ # Copyright 2007 Nominet UK
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
8
  # http://www.apache.org/licenses/LICENSE-2.0
9
- #
10
- #Unless required by applicable law or agreed to in writing, software
11
- #distributed under the License is distributed on an "AS IS" BASIS,
12
- #WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
- #See the License for the specific language governing permissions and
14
- #limitations under the License.
15
- #++
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ # ++
16
16
 
17
17
  module Dnsruby
18
18
  class KeyCache #:nodoc: all
19
- # Cache includes expiration time for keys
20
- # Cache removes expired records
19
+ # Cache includes expiration time for keys
20
+ # Cache removes expired records
21
21
  def initialize(keys = nil)
22
- # Store key tag against [expiry, key]
22
+ # Store key tag against [expiry, key]
23
23
  @keys = {}
24
24
  add(keys)
25
25
  end
@@ -34,7 +34,7 @@ module Dnsruby
34
34
  elsif (k.kind_of?KeyCache)
35
35
  kaes = k.keys_and_expirations
36
36
  kaes.keys.each { |keykey|
37
- # priv_add_key(keykey, kaes[keykey])
37
+ # priv_add_key(keykey, kaes[keykey])
38
38
  priv_add_key(keykey[1], keykey[0])
39
39
  }
40
40
  else
@@ -44,17 +44,17 @@ module Dnsruby
44
44
  end
45
45
 
46
46
  def add_rrset(k)
47
- # Get expiration from the RRSIG
48
- # There can be several RRSIGs here, one for each key which has signed the RRSet
49
- # We want to choose the one with the most secure signing algorithm, key length,
50
- # and the longest expiration time - not easy!
51
- # for now, we simply accept all signed keys
47
+ # Get expiration from the RRSIG
48
+ # There can be several RRSIGs here, one for each key which has signed the RRSet
49
+ # We want to choose the one with the most secure signing algorithm, key length,
50
+ # and the longest expiration time - not easy!
51
+ # for now, we simply accept all signed keys
52
52
  k.sigs.each { |sig|
53
53
  if (sig.type_covered = Types.DNSKEY)
54
54
  if (sig.inception <= Time.now.to_i)
55
- # Check sig.expiration, sig.algorithm
55
+ # Check sig.expiration, sig.algorithm
56
56
  if (sig.expiration > Time.now.to_i)
57
- # add the keys to the store
57
+ # add the keys to the store
58
58
  k.rrs.each {|rr| priv_add_key(rr, sig.expiration)}
59
59
  end
60
60
  end
@@ -63,7 +63,7 @@ module Dnsruby
63
63
  end
64
64
 
65
65
  def priv_add_key(k, exp)
66
- # Check that the key does not already exist with a longer expiration!
66
+ # Check that the key does not already exist with a longer expiration!
67
67
  if (@keys[k] == nil)
68
68
  @keys[k.key_tag] = [exp,k]
69
69
  elsif ((@keys[k])[0] < exp)
@@ -72,17 +72,17 @@ module Dnsruby
72
72
  end
73
73
 
74
74
  def each
75
- # Only offer currently-valid keys here
75
+ # Only offer currently-valid keys here
76
76
  remove_expired_keys
77
77
  @keys.values.each {|v| yield v[1]}
78
78
  end
79
79
  def keys
80
- # Only offer currently-valid keys here
80
+ # Only offer currently-valid keys here
81
81
  remove_expired_keys
82
82
  ks = []
83
83
  @keys.values.each {|a| ks.push(a[1])}
84
84
  return ks
85
- # return @keys.keys
85
+ # return @keys.keys
86
86
  end
87
87
  def keys_and_expirations
88
88
  remove_expired_keys
@@ -0,0 +1,164 @@
1
+ module Dnsruby
2
+ class MessageDecoder #:nodoc: all
3
+ attr_reader :index
4
+ def initialize(data)
5
+ @data = data
6
+ @index = 0
7
+ @limit = data.length
8
+ yield self if block_given?
9
+ end
10
+
11
+ def has_remaining
12
+ @limit - @index > 0
13
+ end
14
+
15
+ def get_length16
16
+ len, = self.get_unpack('n')
17
+ save_limit = @limit
18
+ @limit = @index + len
19
+ d = yield(len)
20
+ if @index < @limit
21
+ raise DecodeError.new('junk exists')
22
+ elsif @limit < @index
23
+ raise DecodeError.new('limit exceeded')
24
+ end
25
+ @limit = save_limit
26
+ d
27
+ end
28
+
29
+ def get_bytes(len = @limit - @index)
30
+ d = @data[@index, len]
31
+ @index += len
32
+ d
33
+ end
34
+
35
+ def get_unpack(template)
36
+ len = 0
37
+ littlec = ?c
38
+ bigc = ?C
39
+ littleh = ?h
40
+ bigh = ?H
41
+ littlen = ?n
42
+ bign = ?N
43
+ star = ?*
44
+
45
+ if (littlec.class != Fixnum)
46
+ # We're using Ruby 1.9 - convert the codes
47
+ littlec = littlec.getbyte(0)
48
+ bigc = bigc.getbyte(0)
49
+ littleh = littleh.getbyte(0)
50
+ bigh = bigh.getbyte(0)
51
+ littlen = littlen.getbyte(0)
52
+ bign = bign.getbyte(0)
53
+ star = star.getbyte(0)
54
+ end
55
+
56
+ template.each_byte {|byte|
57
+ case byte
58
+ when littlec, bigc
59
+ len += 1
60
+ when littleh, bigh
61
+ len += 1
62
+ when littlen
63
+ len += 2
64
+ when bign
65
+ len += 4
66
+ when star
67
+ len = @limit - @index
68
+ else
69
+ raise StandardError.new("unsupported template: '#{byte.chr}' in '#{template}'")
70
+ end
71
+ }
72
+ raise DecodeError.new('limit exceeded') if @limit < @index + len
73
+ arr = @data.unpack("@#{@index}#{template}")
74
+ @index += len
75
+ arr
76
+ end
77
+
78
+ def get_string
79
+ len = @data[@index]
80
+ if len.class == String
81
+ len = len.getbyte(0)
82
+ end
83
+ raise DecodeError.new("limit exceeded\nlimit = #{@limit}, index = #{@index}, len = #{len}\n") if @limit < @index + 1 + (len ? len : 0)
84
+ d = @data[@index + 1, len]
85
+ @index += 1 + len
86
+ d
87
+ end
88
+
89
+ def get_string_list
90
+ strings = []
91
+ while @index < @limit
92
+ strings << self.get_string
93
+ end
94
+ strings
95
+ end
96
+
97
+ def get_name
98
+ Name.new(self.get_labels)
99
+ end
100
+
101
+ def get_labels(limit=nil)
102
+ limit = @index if !limit || @index < limit
103
+ d = []
104
+ while true
105
+ temp = @data[@index]
106
+ if temp.class == String
107
+ temp = temp.getbyte(0)
108
+ end
109
+ case temp # @data[@index]
110
+ when 0
111
+ @index += 1
112
+ return d
113
+ when 192..255
114
+ idx = self.get_unpack('n')[0] & 0x3fff
115
+ if limit <= idx
116
+ raise DecodeError.new('non-backward name pointer')
117
+ end
118
+ save_index = @index
119
+ @index = idx
120
+ d += self.get_labels(limit)
121
+ @index = save_index
122
+ return d
123
+ else
124
+ d << self.get_label
125
+ end
126
+ end
127
+ d
128
+ end
129
+
130
+ def get_label
131
+ begin
132
+ # label = Name::Label.new(Name::decode(self.get_string))
133
+ label = Name::Label.new(self.get_string)
134
+ return label
135
+ # return Name::Label::Str.new(self.get_string)
136
+ rescue ResolvError => e
137
+ raise DecodeError.new(e) # Turn it into something more suitable
138
+ end
139
+ end
140
+
141
+ def get_question
142
+ name = self.get_name
143
+ type, klass = self.get_unpack('nn')
144
+ q = Question.new(name, type, klass)
145
+ q
146
+ end
147
+
148
+ def get_rr
149
+ name = self.get_name
150
+ type, klass, ttl = self.get_unpack('nnN')
151
+ klass = Classes.new(klass)
152
+ typeclass = RR.get_class(type, klass)
153
+ # @TODO@ Trap decode errors here, and somehow mark the record as bad.
154
+ # Need some way to represent raw data only
155
+ rec = self.get_length16 { typeclass.decode_rdata(self) }
156
+ rec.name = name
157
+ rec.ttl = ttl
158
+ rec.type = type
159
+ rec.klass = klass
160
+ rec
161
+ end
162
+ end
163
+
164
+ end