net-dns 0.2.5 → 0.3
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.
- data/InstalledFiles +0 -21
- data/Rakefile +17 -1
- data/lib/net/dns/dns.rb +2 -2
- data/lib/net/dns/packet.rb +7 -0
- data/lib/net/dns/resolver.rb +79 -32
- data/lib/net/dns/rr.rb +26 -10
- data/test/net/dns/test_rr.rb +5 -0
- metadata +2 -4
- data/lib/net/dns/rr.rb~ +0 -391
- data/lib/net/dns/rr/ptr.rb~ +0 -71
data/InstalledFiles
CHANGED
@@ -1,22 +1 @@
|
|
1
|
-
/usr/local/lib/site_ruby/1.8/net/dns/resolver.rb
|
2
|
-
/usr/local/lib/site_ruby/1.8/net/dns/dns.rb
|
3
1
|
/usr/local/lib/site_ruby/1.8/net/dns/rr.rb
|
4
|
-
/usr/local/lib/site_ruby/1.8/net/dns/question.rb
|
5
|
-
/usr/local/lib/site_ruby/1.8/net/dns/header.rb
|
6
|
-
/usr/local/lib/site_ruby/1.8/net/dns/packet.rb
|
7
|
-
/usr/local/lib/site_ruby/1.8/net/dns/names/names.rb
|
8
|
-
/usr/local/lib/site_ruby/1.8/net/dns/resolver/timeouts.rb
|
9
|
-
/usr/local/lib/site_ruby/1.8/net/dns/resolver/socks.rb
|
10
|
-
/usr/local/lib/site_ruby/1.8/net/dns/rr/null.rb
|
11
|
-
/usr/local/lib/site_ruby/1.8/net/dns/rr/types.rb
|
12
|
-
/usr/local/lib/site_ruby/1.8/net/dns/rr/hinfo.rb
|
13
|
-
/usr/local/lib/site_ruby/1.8/net/dns/rr/mr.rb
|
14
|
-
/usr/local/lib/site_ruby/1.8/net/dns/rr/soa.rb
|
15
|
-
/usr/local/lib/site_ruby/1.8/net/dns/rr/mx.rb
|
16
|
-
/usr/local/lib/site_ruby/1.8/net/dns/rr/txt.rb
|
17
|
-
/usr/local/lib/site_ruby/1.8/net/dns/rr/cname.rb
|
18
|
-
/usr/local/lib/site_ruby/1.8/net/dns/rr/a.rb
|
19
|
-
/usr/local/lib/site_ruby/1.8/net/dns/rr/aaaa.rb
|
20
|
-
/usr/local/lib/site_ruby/1.8/net/dns/rr/ns.rb
|
21
|
-
/usr/local/lib/site_ruby/1.8/net/dns/rr/classes.rb
|
22
|
-
/usr/local/lib/site_ruby/1.8/net/dns/rr/ptr.rb
|
data/Rakefile
CHANGED
@@ -6,7 +6,23 @@ require 'rake/gempackagetask'
|
|
6
6
|
|
7
7
|
require 'rubygems'
|
8
8
|
|
9
|
-
$VERSION = "0.
|
9
|
+
$VERSION = "0.3"
|
10
|
+
|
11
|
+
task :package => [:version, :clean]
|
12
|
+
|
13
|
+
desc "Library version"
|
14
|
+
task :version do
|
15
|
+
file = "lib/net/dns/dns.rb"
|
16
|
+
str = IO.readlines(file).to_s
|
17
|
+
offset = (str =~ /VERSION = "(.*)"/)
|
18
|
+
unless $1 == $VERSION
|
19
|
+
str.gsub!($1,$VERSION)
|
20
|
+
File.open(file,"w") do |out|
|
21
|
+
out << str
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
10
26
|
|
11
27
|
desc "Run the tests"
|
12
28
|
Rake::TestTask.new do |t|
|
data/lib/net/dns/dns.rb
CHANGED
data/lib/net/dns/packet.rb
CHANGED
data/lib/net/dns/resolver.rb
CHANGED
@@ -15,7 +15,7 @@ require 'net/dns/resolver/timeouts'
|
|
15
15
|
module Net # :nodoc:
|
16
16
|
module DNS
|
17
17
|
|
18
|
-
|
18
|
+
include Logger::Severity
|
19
19
|
|
20
20
|
# =Name
|
21
21
|
#
|
@@ -108,7 +108,6 @@ module Net # :nodoc:
|
|
108
108
|
:packet_size => 512,
|
109
109
|
:tcp_timeout => TcpTimeout.new(120),
|
110
110
|
:udp_timeout => UdpTimeout.new(0)}
|
111
|
-
|
112
111
|
|
113
112
|
# Create a new resolver object.
|
114
113
|
#
|
@@ -208,7 +207,7 @@ module Net # :nodoc:
|
|
208
207
|
|
209
208
|
# New logger facility
|
210
209
|
@logger = Logger.new(@config[:log_file])
|
211
|
-
@logger.level = Logger::WARN
|
210
|
+
@logger.level = $DEBUG ? Logger::DEBUG : Logger::WARN
|
212
211
|
|
213
212
|
#------------------------------------------------------------
|
214
213
|
# Resolver configuration will be set in order from:
|
@@ -774,10 +773,6 @@ module Net # :nodoc:
|
|
774
773
|
#
|
775
774
|
# Note that this will destroy the precedent logger.
|
776
775
|
#
|
777
|
-
# This is the only mode user will have to control their logger, such
|
778
|
-
# as setting the level threshold, because no reader is set for this
|
779
|
-
# instance variable.
|
780
|
-
#
|
781
776
|
def logger=(logger)
|
782
777
|
if logger.kind_of? Logger
|
783
778
|
@logger.close
|
@@ -787,6 +782,27 @@ module Net # :nodoc:
|
|
787
782
|
end
|
788
783
|
end
|
789
784
|
|
785
|
+
# Set the log level for the built-in logging facility.
|
786
|
+
#
|
787
|
+
# The log level can be one of the following:
|
788
|
+
#
|
789
|
+
# - +Net::DNS::DEBUG+
|
790
|
+
# - +Net::DNS::INFO+
|
791
|
+
# - +Net::DNS::WARN+
|
792
|
+
# - +Net::DNS::ERROR+
|
793
|
+
# - +Net::DNS::FATAL+
|
794
|
+
#
|
795
|
+
# Note that if the global variable $DEBUG is set (like when the
|
796
|
+
# -d switch is used at the command line) the logger level is
|
797
|
+
# automatically set at DEGUB.
|
798
|
+
#
|
799
|
+
# For further informations, see Logger documentation in the
|
800
|
+
# Ruby standard library.
|
801
|
+
#
|
802
|
+
def log_level=(level)
|
803
|
+
@logger.level = level
|
804
|
+
end
|
805
|
+
|
790
806
|
# Performs a DNS query for the given name, applying the searchlist if
|
791
807
|
# appropriate. The search algorithm is as follows:
|
792
808
|
#
|
@@ -1040,37 +1056,60 @@ module Net # :nodoc:
|
|
1040
1056
|
end
|
1041
1057
|
|
1042
1058
|
def send_tcp(packet,packet_data)
|
1043
|
-
# Generate new TCP socket or use persistent one
|
1044
|
-
if @config[:persistent_tcp] and @@tcp_socket
|
1045
|
-
socket = @@tcp_socket
|
1046
|
-
@logger.info "Using persistent socket #{socket.inspect}"
|
1047
|
-
else
|
1048
|
-
socket = Socket.new(Socket::AF_INET,Socket::SOCK_STREAM,0)
|
1049
|
-
socket.bind(Socket.pack_sockaddr_in(@config[:source_port],@config[:source_address].to_s))
|
1050
|
-
@@tcp_socket = socket if @config[:persistent_tcp]
|
1051
|
-
end
|
1052
1059
|
|
1053
|
-
ans =
|
1054
|
-
response = ""
|
1060
|
+
ans = nil
|
1055
1061
|
length = [packet_data.size].pack("n")
|
1056
1062
|
@config[:nameservers].each do |ns|
|
1057
|
-
|
1063
|
+
begin
|
1064
|
+
|
1065
|
+
# Generate new TCP socket or use persistent one
|
1066
|
+
if @config[:persistent_tcp] and @@tcp_socket
|
1067
|
+
socket = @@tcp_socket
|
1068
|
+
@logger.info "Using persistent socket #{socket.inspect}"
|
1069
|
+
else
|
1070
|
+
socket = Socket.new(Socket::AF_INET,Socket::SOCK_STREAM,0)
|
1071
|
+
socket.bind(Socket.pack_sockaddr_in(@config[:source_port],@config[:source_address].to_s))
|
1072
|
+
@@tcp_socket = socket if @config[:persistent_tcp]
|
1073
|
+
end
|
1074
|
+
|
1058
1075
|
sockaddr = Socket.pack_sockaddr_in(@config[:port],ns.to_s)
|
1059
|
-
|
1060
|
-
|
1061
|
-
|
1062
|
-
|
1063
|
-
|
1064
|
-
|
1065
|
-
|
1066
|
-
|
1067
|
-
|
1076
|
+
|
1077
|
+
@config[:tcp_timeout].timeout do
|
1078
|
+
socket.connect(sockaddr)
|
1079
|
+
@logger.info "Contacting nameserver #{ns} port #{@config[:port]}"
|
1080
|
+
socket.write(length+packet_data)
|
1081
|
+
ans = socket.recv(Net::DNS::INT16SZ)
|
1082
|
+
len = ans.unpack("n")[0]
|
1083
|
+
|
1084
|
+
if len == 0
|
1085
|
+
@logger.warn "Receiving 0 lenght packet from nameserver #{ns}, trying next."
|
1086
|
+
next
|
1087
|
+
end
|
1088
|
+
|
1089
|
+
ans = socket.recv(len)
|
1090
|
+
unless ans.size == len
|
1091
|
+
@logger.warn "Malformed packet from nameserver #{ns}, trying next."
|
1092
|
+
next
|
1093
|
+
end
|
1094
|
+
end
|
1095
|
+
|
1068
1096
|
ans = [ans,["",@config[:port],ns.to_s,ns.to_s]]
|
1069
1097
|
@logger.info "Received #{ans[0].size} bytes from #{ans[1][2]+":"+ans[1][1].to_s}"
|
1098
|
+
|
1099
|
+
rescue TimeoutError
|
1100
|
+
@logger.warn "Nameserver #{ns} not responding within TCP timeout, trying next one"
|
1101
|
+
next
|
1102
|
+
ensure
|
1103
|
+
socket.close unless @config[:persistent_tcp]
|
1070
1104
|
end
|
1071
|
-
response = Net::DNS::Packet.parse(ans[0],ans[1])
|
1072
1105
|
end
|
1073
|
-
|
1106
|
+
|
1107
|
+
if ans
|
1108
|
+
return Net::DNS::Packet.parse(ans[0],ans[1])
|
1109
|
+
else
|
1110
|
+
@logger.fatal "No response from nameservers list: aborting"
|
1111
|
+
raise NoResponseError
|
1112
|
+
end
|
1074
1113
|
end
|
1075
1114
|
|
1076
1115
|
|
@@ -1090,6 +1129,7 @@ module Net # :nodoc:
|
|
1090
1129
|
@config[:nameservers].each do |ns|
|
1091
1130
|
begin
|
1092
1131
|
@config[:udp_timeout].timeout do
|
1132
|
+
@logger.info "Contacting nameserver #{ns} port #{@config[:port]}"
|
1093
1133
|
socket.send(packet_data,0,ns.to_s,@config[:port])
|
1094
1134
|
ans = socket.recvfrom(@config[:packet_size])
|
1095
1135
|
end
|
@@ -1102,7 +1142,12 @@ module Net # :nodoc:
|
|
1102
1142
|
next
|
1103
1143
|
end
|
1104
1144
|
end
|
1105
|
-
|
1145
|
+
if ans
|
1146
|
+
return Net::DNS::Packet.parse(ans[0],ans[1])
|
1147
|
+
else
|
1148
|
+
@logger.fatal "No response from nameservers list: aborting"
|
1149
|
+
raise NoResponseError
|
1150
|
+
end
|
1106
1151
|
end
|
1107
1152
|
|
1108
1153
|
def valid?(name)
|
@@ -1119,7 +1164,9 @@ end # module Net
|
|
1119
1164
|
|
1120
1165
|
class ResolverArgumentError < ArgumentError # :nodoc:
|
1121
1166
|
end
|
1122
|
-
|
1167
|
+
class NoResponseError < StandardError # :nodoc:
|
1168
|
+
end
|
1169
|
+
|
1123
1170
|
module ExtendHash # :nodoc:
|
1124
1171
|
# Returns an hash with all the
|
1125
1172
|
# keys turned into downcase
|
data/lib/net/dns/rr.rb
CHANGED
@@ -212,20 +212,36 @@ module Net # :nodoc:
|
|
212
212
|
# #=> example.com. 7200 IN MX 10 mailhost.example.com.
|
213
213
|
#
|
214
214
|
def inspect
|
215
|
-
# Organize data for pretty format
|
216
|
-
if @name.size >= 24
|
217
|
-
nlen = @name.size + 1
|
218
|
-
tlen = @ttl.to_s.size+2
|
219
|
-
else
|
220
|
-
nlen = 24
|
221
|
-
tlen = 8
|
222
|
-
end
|
223
215
|
data = get_inspect
|
224
216
|
# Returns the preformatted string
|
225
|
-
|
226
|
-
|
217
|
+
if @name.size < 24
|
218
|
+
[@name, @ttl.to_s, @cls.to_s, @type.to_s,
|
219
|
+
data].pack("A24 A8 A8 A8 A*")
|
220
|
+
else
|
221
|
+
to_a.join(" ")
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
# Returns the RR in a string format.
|
226
|
+
#
|
227
|
+
# mx = Net::DNS::RR.new("example.com. 7200 MX 10 mailhost.example.com.")
|
228
|
+
# mx.to_s
|
229
|
+
# #=> "example.com. 7200 IN MX 10 mailhost.example.com."
|
230
|
+
#
|
231
|
+
def to_s
|
232
|
+
"#{self.inspect}"
|
227
233
|
end
|
228
234
|
|
235
|
+
# Returns an array with all the fields for the RR record.
|
236
|
+
#
|
237
|
+
# mx = Net::DNS::RR.new("example.com. 7200 MX 10 mailhost.example.com.")
|
238
|
+
# mx.to_a
|
239
|
+
# #=> ["example.com.",7200,"IN","MX","10 mailhost.example.com."]
|
240
|
+
#
|
241
|
+
def to_a
|
242
|
+
[@name,@ttl,@cls.to_s,@type.to_s,get_inspect]
|
243
|
+
end
|
244
|
+
|
229
245
|
# Type accessor
|
230
246
|
def type
|
231
247
|
@type.to_s
|
data/test/net/dns/test_rr.rb
CHANGED
@@ -33,6 +33,8 @@ class Test_RR < Test::Unit::TestCase
|
|
33
33
|
@a_binary = Net::DNS::RR.parse(@a_data)
|
34
34
|
@mx_data = @mx.data
|
35
35
|
@mx_binary = Net::DNS::RR.parse(@mx_data)
|
36
|
+
|
37
|
+
@array = [@name,@ttl,@cls,@type,@rdata]
|
36
38
|
|
37
39
|
end
|
38
40
|
|
@@ -116,6 +118,9 @@ class Test_RR < Test::Unit::TestCase
|
|
116
118
|
|
117
119
|
assert_equal(@a_data, @a_binary.data)
|
118
120
|
assert_equal(@mx_data, @mx_binary.data)
|
121
|
+
|
122
|
+
assert_equal(@str, @a_hash.to_s)
|
123
|
+
assert_equal(@array, @a_hash.to_a)
|
119
124
|
end
|
120
125
|
|
121
126
|
def test_range
|
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.0
|
|
3
3
|
specification_version: 1
|
4
4
|
name: net-dns
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.
|
7
|
-
date: 2007-02-
|
6
|
+
version: "0.3"
|
7
|
+
date: 2007-02-04 00:00:00 +00:00
|
8
8
|
summary: Pure Ruby DNS library
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -50,7 +50,6 @@ files:
|
|
50
50
|
- lib/net/dns/dns.rb
|
51
51
|
- lib/net/dns/rr.rb
|
52
52
|
- lib/net/dns/question.rb
|
53
|
-
- lib/net/dns/rr.rb~
|
54
53
|
- lib/net/dns/header.rb
|
55
54
|
- lib/net/dns/packet.rb
|
56
55
|
- lib/net/dns/rr
|
@@ -58,7 +57,6 @@ files:
|
|
58
57
|
- lib/net/dns/resolver/timeouts.rb
|
59
58
|
- lib/net/dns/resolver/socks.rb
|
60
59
|
- lib/net/dns/rr/null.rb
|
61
|
-
- lib/net/dns/rr/ptr.rb~
|
62
60
|
- lib/net/dns/rr/types.rb
|
63
61
|
- lib/net/dns/rr/hinfo.rb
|
64
62
|
- lib/net/dns/rr/mr.rb
|
data/lib/net/dns/rr.rb~
DELETED
@@ -1,391 +0,0 @@
|
|
1
|
-
#
|
2
|
-
# $Id: RR.rb,v 1.19 2006/07/28 07:33:36 bluemonk Exp $
|
3
|
-
#
|
4
|
-
|
5
|
-
require 'net/dns/names/names'
|
6
|
-
require 'net/dns/rr/types'
|
7
|
-
require 'net/dns/rr/classes'
|
8
|
-
|
9
|
-
|
10
|
-
files = %w[a ns mx cname txt soa ptr aaaa mr] # hinfo mb mg mr
|
11
|
-
files.each do |file|
|
12
|
-
require "net/dns/rr/#{file}"
|
13
|
-
end
|
14
|
-
|
15
|
-
module Net # :nodoc:
|
16
|
-
module DNS
|
17
|
-
|
18
|
-
# =Name
|
19
|
-
#
|
20
|
-
# Net::DNS::RR - DNS Resource Record class
|
21
|
-
#
|
22
|
-
# =Synopsis
|
23
|
-
#
|
24
|
-
# require 'net/dns/rr'
|
25
|
-
#
|
26
|
-
# =Description
|
27
|
-
#
|
28
|
-
# The Net::DNS::RR is the base class for DNS Resource
|
29
|
-
# Record (RR) objects. A RR is a pack of data that represents
|
30
|
-
# resources for a DNS zone. The form in which this data is
|
31
|
-
# shows can be drawed as follow:
|
32
|
-
#
|
33
|
-
# "name ttl class type data"
|
34
|
-
#
|
35
|
-
# The +name+ is the name of the resource, like an canonical
|
36
|
-
# name for an +A+ record (internet ip address). The +ttl+ is the
|
37
|
-
# time to live, expressed in seconds. +type+ and +class+ are
|
38
|
-
# respectively the type of resource (+A+ for ip addresses, +NS+
|
39
|
-
# for nameservers, and so on) and the class, which is almost
|
40
|
-
# always +IN+, the Internet class. At the end, +data+ is the
|
41
|
-
# value associated to the name for that particular type of
|
42
|
-
# resource record. An example:
|
43
|
-
#
|
44
|
-
# # A record for IP address
|
45
|
-
# "www.example.com 86400 IN A 172.16.100.1"
|
46
|
-
#
|
47
|
-
# # NS record for name server
|
48
|
-
# "www.example.com 86400 IN NS ns.example.com"
|
49
|
-
#
|
50
|
-
# A new RR object can be created in 2 ways: passing a string
|
51
|
-
# such the ones above, or specifying each field as the pair
|
52
|
-
# of an hash. See the Net::DNS::RR.new method for details.
|
53
|
-
#
|
54
|
-
# =Error classes
|
55
|
-
#
|
56
|
-
# Some error classes has been defined for the Net::DNS::RR class,
|
57
|
-
# which are listed here to keep a light and browsable main documentation.
|
58
|
-
# We have:
|
59
|
-
#
|
60
|
-
# * RRArgumentError: Generic argument error for class Net::DNS::RR
|
61
|
-
# * RRDataError: Error in parsing binary data, maybe from a malformed packet
|
62
|
-
#
|
63
|
-
# =Copyright
|
64
|
-
#
|
65
|
-
# Copyright (c) 2006 Marco Ceresa
|
66
|
-
#
|
67
|
-
# All rights reserved. This program is free software; you may redistribute
|
68
|
-
# it and/or modify it under the same terms as Ruby itself.
|
69
|
-
#
|
70
|
-
class RR
|
71
|
-
include Net::DNS::Names
|
72
|
-
|
73
|
-
# Regexp matching an RR string
|
74
|
-
RR_REGEXP = Regexp.new("^\\s*(\\S+)\\s*(\\d+)?\\s+(" +
|
75
|
-
Net::DNS::RR::Classes.regexp +
|
76
|
-
"|CLASS\\d+)?\\s*(" +
|
77
|
-
Net::DNS::RR::Types.regexp +
|
78
|
-
"|TYPE\\d+)?\\s*(.*)$", Regexp::IGNORECASE)
|
79
|
-
|
80
|
-
# Dimension of the sum of class, type, TTL and rdlength fields in a
|
81
|
-
# RR portion of the packet, in bytes
|
82
|
-
RRFIXEDSZ = 10
|
83
|
-
|
84
|
-
# Name of the RR
|
85
|
-
attr_reader :name
|
86
|
-
# TTL time (in seconds) of the RR
|
87
|
-
attr_reader :ttl
|
88
|
-
# Data belonging to that appropriate class,
|
89
|
-
# not to be used (use real accessors instead)
|
90
|
-
attr_reader :rdata
|
91
|
-
|
92
|
-
# Create a new instance of Net::DNS::RR class, or an instance of
|
93
|
-
# any of the subclass of the appropriate type.
|
94
|
-
#
|
95
|
-
# Argument can be a string or an hash. With a sting, we can pass
|
96
|
-
# a RR resource record in the canonical format:
|
97
|
-
#
|
98
|
-
# a = Net::DNS::RR.new("foo.example.com. 86400 A 10.1.2.3")
|
99
|
-
# mx = Net::DNS::RR.new("example.com. 7200 MX 10 mailhost.example.com.")
|
100
|
-
# cname = Net::DNS::RR.new("www.example.com 300 IN CNAME www1.example.com")
|
101
|
-
# txt = Net::DNS::RR.new('baz.example.com 3600 HS TXT "text record"')
|
102
|
-
#
|
103
|
-
# Incidentally, +a+, +mx+, +cname+ and +txt+ objects will be instances of
|
104
|
-
# respectively Net::DNS::RR::A, Net::DNS::RR::MX, Net::DNS::RR::CNAME and
|
105
|
-
# Net::DNS::RR::TXT classes.
|
106
|
-
#
|
107
|
-
# The name is required; all other informations are optional.
|
108
|
-
# If omitted, the +TTL+ defaults to 10800, +type+ default to +A+ and the RR class
|
109
|
-
# defaults to +IN+. Omitting the optional fields is useful for creating the
|
110
|
-
# empty RDATA sections required for certain dynamic update operations.
|
111
|
-
# All names must be fully qualified. The trailing dot (.) is optional.
|
112
|
-
#
|
113
|
-
# The preferred method is however passing an hash with keys and values:
|
114
|
-
#
|
115
|
-
# rr = Net::DNS::RR.new(
|
116
|
-
# :name => "foo.example.com",
|
117
|
-
# :ttl => 86400,
|
118
|
-
# :cls => "IN",
|
119
|
-
# :type => "A",
|
120
|
-
# :address => "10.1.2.3"
|
121
|
-
# )
|
122
|
-
#
|
123
|
-
# rr = Net::DNS::RR.new(
|
124
|
-
# :name => "foo.example.com",
|
125
|
-
# :type => "A"
|
126
|
-
# )
|
127
|
-
#
|
128
|
-
# Name and data are required; all the others fields are optionals like
|
129
|
-
# we've seen before. The data field can be specified either with the
|
130
|
-
# right name of the resource (:address in the example above) or with
|
131
|
-
# the generic key :rdata. Consult documentation to find the exact name
|
132
|
-
# for the resource in each subclass.
|
133
|
-
#
|
134
|
-
def initialize(arg)
|
135
|
-
case arg
|
136
|
-
when String
|
137
|
-
instance = new_from_string(arg)
|
138
|
-
when Hash
|
139
|
-
instance = new_from_hash(arg)
|
140
|
-
else
|
141
|
-
raise RRArgumentError, "Invalid argument, must be a RR string or an hash of values"
|
142
|
-
end
|
143
|
-
|
144
|
-
if @type.to_s == "ANY"
|
145
|
-
@cls = Net::DNS::RR::Classes.new("IN")
|
146
|
-
end
|
147
|
-
|
148
|
-
build_pack
|
149
|
-
set_type
|
150
|
-
|
151
|
-
instance
|
152
|
-
end
|
153
|
-
|
154
|
-
# Return a new RR object of the correct type (like Net::DNS::RR::A
|
155
|
-
# if the type is A) from a binary string, usually obtained from
|
156
|
-
# network stream.
|
157
|
-
#
|
158
|
-
# This method is used when parsing a binary packet by the Packet
|
159
|
-
# class.
|
160
|
-
#
|
161
|
-
def RR.parse(data)
|
162
|
-
o = allocate
|
163
|
-
obj,offset = o.send(:new_from_binary, data, 0)
|
164
|
-
return obj
|
165
|
-
end
|
166
|
-
|
167
|
-
# Same as RR.parse, but takes an entire packet binary data to
|
168
|
-
# perform name expansion. Default when analizing a packet
|
169
|
-
# just received from a network stream.
|
170
|
-
#
|
171
|
-
# Return an instance of appropriate class and the offset
|
172
|
-
# pointing at the end of the data parsed.
|
173
|
-
#
|
174
|
-
def RR.parse_packet(data,offset)
|
175
|
-
o = allocate
|
176
|
-
o.send(:new_from_binary,data,offset)
|
177
|
-
end
|
178
|
-
|
179
|
-
# Return the RR object in binary data format, suitable
|
180
|
-
# for using in network streams, with names compressed.
|
181
|
-
# Must pass as arguments the offset inside the packet
|
182
|
-
# and an hash of compressed names.
|
183
|
-
#
|
184
|
-
# This method is to be used in other classes and is
|
185
|
-
# not intended for user space programs.
|
186
|
-
#
|
187
|
-
# TO FIX in one of the future releases
|
188
|
-
#
|
189
|
-
def comp_data(offset,compnames)
|
190
|
-
type,cls = @type.to_i, @cls.to_i
|
191
|
-
str,offset,names = dn_comp(@name,offset,compnames)
|
192
|
-
str += [type,cls,@ttl,@rdlength].pack("n2 N n")
|
193
|
-
offset += Net::DNS::RRFIXEDSZ
|
194
|
-
return str,offset,names
|
195
|
-
end
|
196
|
-
|
197
|
-
# Return the RR object in binary data format, suitable
|
198
|
-
# for using in network streams.
|
199
|
-
#
|
200
|
-
# raw_data = rr.data
|
201
|
-
# puts "RR is #{raw_data.size} bytes long"
|
202
|
-
#
|
203
|
-
def data
|
204
|
-
type,cls = @type.to_i, @cls.to_i
|
205
|
-
str = pack_name(@name)
|
206
|
-
return str + [type,cls,@ttl,@rdlength].pack("n2 N n") + get_data
|
207
|
-
end
|
208
|
-
|
209
|
-
# Canonical inspect method
|
210
|
-
#
|
211
|
-
# mx = Net::DNS::RR.new("example.com. 7200 MX 10 mailhost.example.com.")
|
212
|
-
# #=> example.com. 7200 IN MX 10 mailhost.example.com.
|
213
|
-
#
|
214
|
-
def inspect
|
215
|
-
# Organize data for pretty format
|
216
|
-
if @name.size >= 24
|
217
|
-
nlen = @name.size + 1
|
218
|
-
tlen = @ttl.to_s.size+2
|
219
|
-
else
|
220
|
-
nlen = 24
|
221
|
-
tlen = 8
|
222
|
-
end
|
223
|
-
data = get_inspect
|
224
|
-
# Returns the preformatted string
|
225
|
-
[@name, @ttl.to_s, @cls.to_s, @type.to_s,
|
226
|
-
data].pack("A#{nlen} A#{tlen} A#{8-(nlen-24)-(tlen-8)} A8 A*")
|
227
|
-
end
|
228
|
-
|
229
|
-
# Type accessor
|
230
|
-
def type
|
231
|
-
@type.to_s
|
232
|
-
end
|
233
|
-
|
234
|
-
# Class accessor
|
235
|
-
def cls
|
236
|
-
@cls.to_s
|
237
|
-
end
|
238
|
-
|
239
|
-
private
|
240
|
-
|
241
|
-
#---
|
242
|
-
# New RR with argument in string form
|
243
|
-
#---
|
244
|
-
def new_from_string(rrstring)
|
245
|
-
|
246
|
-
unless rrstring =~ RR_REGEXP
|
247
|
-
raise RRArgumentError,
|
248
|
-
"Format error for RR string (maybe CLASS and TYPE not valid?)"
|
249
|
-
end
|
250
|
-
|
251
|
-
# Name of RR - mandatory
|
252
|
-
begin
|
253
|
-
@name = $1.downcase
|
254
|
-
rescue NoMethodError
|
255
|
-
raise RRArgumentError, "Missing name field in RR string #{rrstring}"
|
256
|
-
end
|
257
|
-
|
258
|
-
# Time to live for RR, default 3 hours
|
259
|
-
@ttl = $2 ? $2.to_i : 10800
|
260
|
-
|
261
|
-
# RR class, default to IN
|
262
|
-
@cls = Net::DNS::RR::Classes.new $3
|
263
|
-
|
264
|
-
# RR type, default to A
|
265
|
-
@type = Net::DNS::RR::Types.new $4
|
266
|
-
|
267
|
-
# All the rest is data
|
268
|
-
@rdata = $5 ? $5.strip : ""
|
269
|
-
|
270
|
-
if self.class == Net::DNS::RR
|
271
|
-
(eval "Net::DNS::RR::#@type").new(rrstring)
|
272
|
-
else
|
273
|
-
subclass_new_from_string(@rdata)
|
274
|
-
self.class
|
275
|
-
end
|
276
|
-
end
|
277
|
-
|
278
|
-
def new_from_hash(args)
|
279
|
-
|
280
|
-
# Name field is mandatory
|
281
|
-
unless args.has_key? :name
|
282
|
-
raise RRArgumentError, "RR argument error: need at least RR name"
|
283
|
-
end
|
284
|
-
|
285
|
-
@name = args[:name].downcase
|
286
|
-
@ttl = args[:ttl] ? args[:ttl].to_i : 10800 # Default 3 hours
|
287
|
-
@type = Net::DNS::RR::Types.new args[:type]
|
288
|
-
@cls = Net::DNS::RR::Classes.new args[:cls]
|
289
|
-
|
290
|
-
@rdata = args[:rdata] ? args[:rdata].strip : ""
|
291
|
-
@rdlength = args[:rdlength] || @rdata.size
|
292
|
-
|
293
|
-
if self.class == Net::DNS::RR
|
294
|
-
(eval "Net::DNS::RR::#@type").new(args)
|
295
|
-
else
|
296
|
-
hash = args - [:name,:ttl,:type,:cls]
|
297
|
-
if hash.has_key? :rdata
|
298
|
-
subclass_new_from_string(hash[:rdata])
|
299
|
-
else
|
300
|
-
subclass_new_from_hash(hash)
|
301
|
-
end
|
302
|
-
self.class
|
303
|
-
end
|
304
|
-
end # new_from_hash
|
305
|
-
|
306
|
-
def new_from_binary(data,offset)
|
307
|
-
if self.class == Net::DNS::RR
|
308
|
-
temp = dn_expand(data,offset)[1]
|
309
|
-
type = Net::DNS::RR::Types.new data.unpack("@#{temp} n")[0]
|
310
|
-
(eval "Net::DNS::RR::#{type}").parse_packet(data,offset)
|
311
|
-
else
|
312
|
-
@name,offset = dn_expand(data,offset)
|
313
|
-
rrtype,cls,@ttl,@rdlength = data.unpack("@#{offset} n2 N n")
|
314
|
-
@type = Net::DNS::RR::Types.new rrtype
|
315
|
-
@cls = Net::DNS::RR::Classes.new cls
|
316
|
-
offset += RRFIXEDSZ
|
317
|
-
offset = subclass_new_from_binary(data,offset)
|
318
|
-
build_pack
|
319
|
-
set_type
|
320
|
-
return [self,offset]
|
321
|
-
end
|
322
|
-
# rescue StandardError => err
|
323
|
-
# raise RRDataError, "Caught exception, maybe packet malformed: #{err}"
|
324
|
-
end
|
325
|
-
|
326
|
-
# Methods to be overridden by subclasses
|
327
|
-
def subclass_new_from_array(arr)
|
328
|
-
end
|
329
|
-
def subclass_new_from_string(str)
|
330
|
-
end
|
331
|
-
def subclass_new_from_hash(hash)
|
332
|
-
end
|
333
|
-
def subclass_new_from_binary(data,offset)
|
334
|
-
end
|
335
|
-
def build_pack
|
336
|
-
end
|
337
|
-
def set_type
|
338
|
-
end
|
339
|
-
def get_inspect
|
340
|
-
@rdata
|
341
|
-
end
|
342
|
-
def get_data
|
343
|
-
@rdata
|
344
|
-
end
|
345
|
-
|
346
|
-
# NEW new method :)
|
347
|
-
def self.new(*args)
|
348
|
-
o = allocate
|
349
|
-
obj = o.send(:initialize,*args)
|
350
|
-
if self == Net::DNS::RR
|
351
|
-
return obj
|
352
|
-
else
|
353
|
-
return o
|
354
|
-
end
|
355
|
-
end
|
356
|
-
|
357
|
-
end # class RR
|
358
|
-
|
359
|
-
end # module DNS
|
360
|
-
end # module Net
|
361
|
-
|
362
|
-
class RRArgumentError < ArgumentError # :nodoc:
|
363
|
-
end
|
364
|
-
class RRDataError < StandardError # :nodoc:
|
365
|
-
end
|
366
|
-
|
367
|
-
module ExtendHash # :nodoc:
|
368
|
-
|
369
|
-
# Performs a sort of group difference
|
370
|
-
# operation on hashes or arrays
|
371
|
-
#
|
372
|
-
# a = {:a=>1,:b=>2,:c=>3}
|
373
|
-
# b = {:a=>1,:b=>2}
|
374
|
-
# c = [:a,:c]
|
375
|
-
# a-b #=> {:c=>3}
|
376
|
-
# a-c #=> {:b=>2}
|
377
|
-
#
|
378
|
-
def -(oth)
|
379
|
-
case oth
|
380
|
-
when Hash
|
381
|
-
delete_if {|k,v| oth.has_key? k}
|
382
|
-
when Array
|
383
|
-
delete_if {|k,v| oth.include? k}
|
384
|
-
end
|
385
|
-
end
|
386
|
-
end
|
387
|
-
|
388
|
-
class Hash # :nodoc:
|
389
|
-
include ExtendHash
|
390
|
-
end
|
391
|
-
|
data/lib/net/dns/rr/ptr.rb~
DELETED
@@ -1,71 +0,0 @@
|
|
1
|
-
##
|
2
|
-
#
|
3
|
-
# Net::DNS::RR::PTR
|
4
|
-
#
|
5
|
-
# $Id: PTR.rb,v 1.5 2006/07/28 07:33:36 bluemonk Exp $
|
6
|
-
#
|
7
|
-
##
|
8
|
-
|
9
|
-
module Net
|
10
|
-
module DNS
|
11
|
-
class RR
|
12
|
-
|
13
|
-
#------------------------------------------------------------
|
14
|
-
# RR type PTR
|
15
|
-
#------------------------------------------------------------
|
16
|
-
class PTR < RR
|
17
|
-
|
18
|
-
# Getter for PTR resource
|
19
|
-
def ptr
|
20
|
-
@ptrdname.to_s
|
21
|
-
end
|
22
|
-
alias_method :ptrdname, :ptr
|
23
|
-
|
24
|
-
private
|
25
|
-
|
26
|
-
def check_ptr(str)
|
27
|
-
IPAddr.new str
|
28
|
-
rescue
|
29
|
-
raise RRArgumentError, "PTR section not valid"
|
30
|
-
end
|
31
|
-
|
32
|
-
def build_pack
|
33
|
-
@ptrdname_pack = pack_name(@ptrdname)
|
34
|
-
@rdlength = @ptrdname_pack.size
|
35
|
-
end
|
36
|
-
|
37
|
-
def set_type
|
38
|
-
@type = Net::DNS::RR::RRTypes.new("PTR")
|
39
|
-
end
|
40
|
-
|
41
|
-
def get_data
|
42
|
-
@ptrdname_pack
|
43
|
-
end
|
44
|
-
|
45
|
-
def get_inspect
|
46
|
-
"#@ptrdname"
|
47
|
-
end
|
48
|
-
|
49
|
-
def subclass_new_from_hash(args)
|
50
|
-
if args.has_key? :ptrdname or args.has_key? :ptr
|
51
|
-
@ptrdname = args[0][:ptrdname]
|
52
|
-
else
|
53
|
-
raise RRArgumentError, ":ptrdname or :ptr field is mandatory but missing"
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
def subclass_new_from_string(str)
|
58
|
-
@ptrdname = check_ptr(str)
|
59
|
-
end
|
60
|
-
|
61
|
-
def subclass_new_from_binary(data,offset)
|
62
|
-
@ptrdname,offset = dn_expand(data,offset)
|
63
|
-
return offset
|
64
|
-
end
|
65
|
-
|
66
|
-
end # class PTR
|
67
|
-
|
68
|
-
end # class RR
|
69
|
-
end # module DNS
|
70
|
-
end # module Net
|
71
|
-
|