bluemonk-net-dns 0.5.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.
- data/AUTHORS +10 -0
- data/CHANGELOG +7 -0
- data/INSTALL +8 -0
- data/README.rdoc +150 -0
- data/Rakefile +93 -0
- data/THANKS +24 -0
- data/VERSION.yml +4 -0
- data/demo/check_soa.rb +120 -0
- data/demo/threads.rb +22 -0
- data/lib/net/dns/dns.rb +117 -0
- data/lib/net/dns/header.rb +761 -0
- data/lib/net/dns/names/names.rb +109 -0
- data/lib/net/dns/packet.rb +581 -0
- data/lib/net/dns/question.rb +195 -0
- data/lib/net/dns/resolver/socks.rb +154 -0
- data/lib/net/dns/resolver/timeouts.rb +73 -0
- data/lib/net/dns/resolver.rb +1267 -0
- data/lib/net/dns/rr/a.rb +121 -0
- data/lib/net/dns/rr/aaaa.rb +92 -0
- data/lib/net/dns/rr/classes.rb +148 -0
- data/lib/net/dns/rr/cname.rb +69 -0
- data/lib/net/dns/rr/hinfo.rb +74 -0
- data/lib/net/dns/rr/mr.rb +68 -0
- data/lib/net/dns/rr/mx.rb +74 -0
- data/lib/net/dns/rr/ns.rb +70 -0
- data/lib/net/dns/rr/null.rb +61 -0
- data/lib/net/dns/rr/ptr.rb +71 -0
- data/lib/net/dns/rr/soa.rb +85 -0
- data/lib/net/dns/rr/srv.rb +57 -0
- data/lib/net/dns/rr/txt.rb +72 -0
- data/lib/net/dns/rr/types.rb +200 -0
- data/lib/net/dns/rr.rb +406 -0
- data/setup.rb +1360 -0
- data/test/net/dns/resolver/test_timeouts.rb +59 -0
- data/test/net/dns/rr/test_a.rb +72 -0
- data/test/net/dns/rr/test_classes.rb +73 -0
- data/test/net/dns/rr/test_ns.rb +66 -0
- data/test/net/dns/rr/test_types.rb +127 -0
- data/test/net/dns/test_header.rb +170 -0
- data/test/net/dns/test_packet.rb +42 -0
- data/test/net/dns/test_question.rb +54 -0
- data/test/net/dns/test_rr.rb +133 -0
- metadata +105 -0
data/lib/net/dns/rr/a.rb
ADDED
@@ -0,0 +1,121 @@
|
|
1
|
+
##
|
2
|
+
#
|
3
|
+
# Net::DNS::RR::A
|
4
|
+
#
|
5
|
+
# $id$
|
6
|
+
#
|
7
|
+
##
|
8
|
+
|
9
|
+
require 'ipaddr'
|
10
|
+
|
11
|
+
module Net # :nodoc:
|
12
|
+
module DNS
|
13
|
+
|
14
|
+
class RR
|
15
|
+
|
16
|
+
# =Name
|
17
|
+
#
|
18
|
+
# Net::DNS::RR::A DNS A resource record
|
19
|
+
#
|
20
|
+
# =Synopsis
|
21
|
+
#
|
22
|
+
# require "net/dns/rr"
|
23
|
+
#
|
24
|
+
# =Description
|
25
|
+
#
|
26
|
+
# Net::DNS::RR::A is the class to handle resource records of type A, the
|
27
|
+
# most common in a DNS query. Its resource data is an IPv4 (i.e. 32 bit
|
28
|
+
# long) address, hold in the instance variable +address+.
|
29
|
+
# a = Net::DNS::RR::A.new("localhost.movie.edu. 360 IN A 127.0.0.1")
|
30
|
+
#
|
31
|
+
# a = Net::DNS::RR::A.new(:name => "localhost.movie.edu.",
|
32
|
+
# :ttl => 360,
|
33
|
+
# :cls => Net::DNS::IN,
|
34
|
+
# :type => Net::DNS::A,
|
35
|
+
# :address => "127.0.0.1")
|
36
|
+
#
|
37
|
+
# When computing binary data to trasmit the RR, the RDATA section is an
|
38
|
+
# Internet address expressed as four decimal numbers separated by dots
|
39
|
+
# without any imbedded spaces (e.g.,"10.2.0.52" or "192.0.5.6").
|
40
|
+
#
|
41
|
+
class A < RR
|
42
|
+
attr_reader :address
|
43
|
+
|
44
|
+
# Assign to the RR::A object a new IPv4 address, which can be in the
|
45
|
+
# form of a string or an IPAddr object
|
46
|
+
#
|
47
|
+
# a.address = "192.168.0.1"
|
48
|
+
# a.address = IPAddr.new("10.0.0.1")
|
49
|
+
#
|
50
|
+
def address=(addr)
|
51
|
+
@address = check_address addr
|
52
|
+
build_pack
|
53
|
+
end # address=
|
54
|
+
|
55
|
+
private
|
56
|
+
|
57
|
+
def check_address(addr)
|
58
|
+
address = ""
|
59
|
+
case addr
|
60
|
+
when String
|
61
|
+
address = IPAddr.new addr
|
62
|
+
when Integer # Address in numeric form
|
63
|
+
tempAddr = [(addr>>24),(addr>>16)&0xFF,(addr>>8)&0xFF,addr&0xFF]
|
64
|
+
tempAddr = tempAddr.collect {|x| x.to_s}.join(".")
|
65
|
+
address = IPAddr.new tempAddr
|
66
|
+
when IPAddr
|
67
|
+
address = addr
|
68
|
+
else
|
69
|
+
raise RRArgumentError, "Unknown address type: #{addr}"
|
70
|
+
end
|
71
|
+
raise RRArgumentError, "Must specify an IPv4 address" unless address.ipv4?
|
72
|
+
address
|
73
|
+
rescue ArgumentError
|
74
|
+
raise RRArgumentError, "Invalid address #{addr}"
|
75
|
+
end
|
76
|
+
|
77
|
+
def build_pack
|
78
|
+
@address_pack = @address.hton
|
79
|
+
@rdlength = @address_pack.size
|
80
|
+
end
|
81
|
+
|
82
|
+
def set_type
|
83
|
+
@type = Net::DNS::RR::Types.new("A")
|
84
|
+
end
|
85
|
+
|
86
|
+
def get_data
|
87
|
+
@address_pack
|
88
|
+
end
|
89
|
+
|
90
|
+
def get_inspect
|
91
|
+
"#@address"
|
92
|
+
end
|
93
|
+
|
94
|
+
def subclass_new_from_hash(args)
|
95
|
+
if args.has_key? :address
|
96
|
+
@address = check_address args[:address]
|
97
|
+
elsif args.has_key? :rdata
|
98
|
+
@address = check_address args[:rdata]
|
99
|
+
else
|
100
|
+
# Address field is mandatory
|
101
|
+
raise RRArgumentError, ":address field is mandatory but missing"
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def subclass_new_from_string(str)
|
106
|
+
@address = check_address(str)
|
107
|
+
end
|
108
|
+
|
109
|
+
def subclass_new_from_binary(data,offset)
|
110
|
+
a,b,c,d = data.unpack("@#{offset} CCCC")
|
111
|
+
@address = IPAddr.new "#{a}.#{b}.#{c}.#{d}"
|
112
|
+
return offset + 4
|
113
|
+
end
|
114
|
+
|
115
|
+
end # class A
|
116
|
+
|
117
|
+
end # class RR
|
118
|
+
end # module DNS
|
119
|
+
end # module Net
|
120
|
+
|
121
|
+
|
@@ -0,0 +1,92 @@
|
|
1
|
+
##
|
2
|
+
#
|
3
|
+
# Net::DNS::RR::AAAA
|
4
|
+
#
|
5
|
+
# $id$
|
6
|
+
#
|
7
|
+
##
|
8
|
+
|
9
|
+
require 'ipaddr'
|
10
|
+
|
11
|
+
module Net
|
12
|
+
module DNS
|
13
|
+
|
14
|
+
class RR
|
15
|
+
|
16
|
+
#
|
17
|
+
# RR type AAAA
|
18
|
+
#
|
19
|
+
class AAAA < RR
|
20
|
+
attr_reader :address
|
21
|
+
|
22
|
+
# Assign to the RR::AAAA object a new IPv6 address, which can be in the
|
23
|
+
# form of a string or an IPAddr object
|
24
|
+
#
|
25
|
+
# a.address = "::1"
|
26
|
+
# a.address = IPAddr.new("::1")
|
27
|
+
#
|
28
|
+
def address=(addr)
|
29
|
+
@address = check_address addr
|
30
|
+
build_pack
|
31
|
+
end # address=
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def check_address(addr)
|
36
|
+
address = ""
|
37
|
+
case addr
|
38
|
+
when String
|
39
|
+
address = IPAddr.new addr
|
40
|
+
when IPAddr
|
41
|
+
address = addr
|
42
|
+
else
|
43
|
+
raise RRArgumentError, "Unknown address type: #{addr.inspect}"
|
44
|
+
end
|
45
|
+
raise RRArgumentError, "Must specify an IPv6 address" unless address.ipv6?
|
46
|
+
address
|
47
|
+
rescue ArgumentError
|
48
|
+
raise RRArgumentError, "Invalid address #{addr.inspect}"
|
49
|
+
end
|
50
|
+
|
51
|
+
def build_pack
|
52
|
+
@address_pack = @address.hton
|
53
|
+
@rdlength = @address_pack.size
|
54
|
+
end
|
55
|
+
|
56
|
+
def set_type
|
57
|
+
@type = Net::DNS::RR::Types.new("AAAA")
|
58
|
+
end
|
59
|
+
|
60
|
+
def get_data
|
61
|
+
@address_pack
|
62
|
+
end
|
63
|
+
|
64
|
+
def get_inspect
|
65
|
+
"#@address"
|
66
|
+
end
|
67
|
+
|
68
|
+
def subclass_new_from_hash(args)
|
69
|
+
if args.has_key? :address
|
70
|
+
@address = check_address args[:address]
|
71
|
+
else
|
72
|
+
raise RRArgumentError, ":address field is mandatory but missing"
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def subclass_new_from_string(str)
|
77
|
+
@address = check_address(str)
|
78
|
+
end
|
79
|
+
|
80
|
+
def subclass_new_from_binary(data,offset)
|
81
|
+
arr = data.unpack("@#{offset} n8")
|
82
|
+
@address = IPAddr.new sprintf("%x:%x:%x:%x:%x:%x:%x:%x",*arr)
|
83
|
+
return offset + 16
|
84
|
+
end
|
85
|
+
|
86
|
+
end # class AAAA
|
87
|
+
|
88
|
+
end # class RR
|
89
|
+
end # module DNS
|
90
|
+
end # module Net
|
91
|
+
|
92
|
+
|
@@ -0,0 +1,148 @@
|
|
1
|
+
module Net # :nodoc:
|
2
|
+
module DNS
|
3
|
+
|
4
|
+
class RR
|
5
|
+
|
6
|
+
#
|
7
|
+
# This is an auxiliary class to hadle RR class field in a DNS packet.
|
8
|
+
#
|
9
|
+
class Classes
|
10
|
+
|
11
|
+
# An hash with the values of each RR class stored with the
|
12
|
+
# respective id number
|
13
|
+
Classes = {
|
14
|
+
'IN' => 1, # RFC 1035
|
15
|
+
'CH' => 3, # RFC 1035
|
16
|
+
'HS' => 4, # RFC 1035
|
17
|
+
'NONE' => 254, # RFC 2136
|
18
|
+
'ANY' => 255, # RFC 1035
|
19
|
+
}
|
20
|
+
|
21
|
+
# The default value when class is nil in Resource Records
|
22
|
+
@@default = Classes["IN"]
|
23
|
+
|
24
|
+
# Be able to control the default class to assign when
|
25
|
+
# cls argument is +nil+. Default to +IN+
|
26
|
+
def self.default=(str)
|
27
|
+
if Classes.has_key? str
|
28
|
+
@@default = Classes[str]
|
29
|
+
else
|
30
|
+
raise ClassArgumentError, "Unknown class #{str}"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# Checks whether +cls+ is a valid RR class.
|
35
|
+
def self.valid?(cls)
|
36
|
+
case cls
|
37
|
+
when String
|
38
|
+
return Classes.has_key?(cls)
|
39
|
+
when Fixnum
|
40
|
+
return Classes.invert.has_key?(cls)
|
41
|
+
else
|
42
|
+
raise ClassArgumentError, "Wrong cls class: #{cls.class}"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# Returns the class in string format, as "IN" or "CH",
|
47
|
+
# given the numeric value
|
48
|
+
def self.to_str(cls)
|
49
|
+
case cls
|
50
|
+
when Fixnum
|
51
|
+
if Classes.invert.has_key? cls
|
52
|
+
return Classes.invert[cls]
|
53
|
+
else
|
54
|
+
raise ClassArgumentError, "Unknown class number #{cls}"
|
55
|
+
end
|
56
|
+
else
|
57
|
+
raise ClassArgumentError, "Wrong cls class: #{cls.class}"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
# Gives in output the keys from the +Classes+ hash
|
62
|
+
# in a format suited for regexps
|
63
|
+
def self.regexp
|
64
|
+
Classes.keys.join("|")
|
65
|
+
end
|
66
|
+
|
67
|
+
# Creates a new object representing an RR class. Performs some
|
68
|
+
# checks on the argument validity too. Il +cls+ is +nil+, the
|
69
|
+
# default value is +ANY+ or the one set with Classes.default=
|
70
|
+
def initialize(cls)
|
71
|
+
case cls
|
72
|
+
when String
|
73
|
+
# type in the form "A" or "NS"
|
74
|
+
new_from_string(cls.upcase)
|
75
|
+
when Fixnum
|
76
|
+
# type in numeric form
|
77
|
+
new_from_num(cls)
|
78
|
+
when nil
|
79
|
+
# default type, control with Classes.default=
|
80
|
+
@str = Classes.invert[@@default]
|
81
|
+
@num = @@default
|
82
|
+
else
|
83
|
+
raise ClassArgumentError, "Wrong cls class: #{cls.class}"
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
# Constructor for string data class,
|
88
|
+
# *PRIVATE* method
|
89
|
+
def new_from_string(cls)
|
90
|
+
case cls
|
91
|
+
when /^CLASS\\d+/
|
92
|
+
# TODO!!!
|
93
|
+
else
|
94
|
+
# String with name of class
|
95
|
+
if Classes.has_key? cls
|
96
|
+
@str = cls
|
97
|
+
@num = Classes[cls]
|
98
|
+
else
|
99
|
+
raise ClassesArgumentError, "Unknown cls #{cls}"
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
# Contructor for numeric data class
|
105
|
+
# *PRIVATE* method
|
106
|
+
def new_from_num(cls)
|
107
|
+
if Classes.invert.has_key? cls
|
108
|
+
@num = cls
|
109
|
+
@str = Classes.invert[cls]
|
110
|
+
else
|
111
|
+
raise ClassesArgumentError, "Unkown cls number #{cls}"
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
# Returns the class in number format
|
116
|
+
# (default for normal use)
|
117
|
+
def inspect
|
118
|
+
@num
|
119
|
+
end
|
120
|
+
|
121
|
+
# Returns the class in string format,
|
122
|
+
# i.d. "IN" or "CH" or such a string.
|
123
|
+
def to_s
|
124
|
+
@str
|
125
|
+
end
|
126
|
+
|
127
|
+
# Returns the class in numeric format,
|
128
|
+
# usable by the pack methods for data transfers
|
129
|
+
def to_i
|
130
|
+
@num.to_i
|
131
|
+
end
|
132
|
+
|
133
|
+
|
134
|
+
# Should be used only for testing purpouses
|
135
|
+
def to_str
|
136
|
+
@num.to_s
|
137
|
+
end
|
138
|
+
|
139
|
+
private :new_from_num, :new_from_string
|
140
|
+
|
141
|
+
end # class Classes
|
142
|
+
|
143
|
+
end # class RR
|
144
|
+
end # module DNS
|
145
|
+
end # module Net
|
146
|
+
|
147
|
+
class ClassArgumentError < ArgumentError # :nodoc:
|
148
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
##
|
2
|
+
#
|
3
|
+
# Net::DNS::RR::CNAME
|
4
|
+
#
|
5
|
+
# $Id: CNAME.rb,v 1.7 2006/07/28 07:33:36 bluemonk Exp $
|
6
|
+
#
|
7
|
+
##
|
8
|
+
|
9
|
+
module Net
|
10
|
+
module DNS
|
11
|
+
|
12
|
+
class RR
|
13
|
+
|
14
|
+
#------------------------------------------------------------
|
15
|
+
# RR type CNAME
|
16
|
+
#------------------------------------------------------------
|
17
|
+
class CNAME < RR
|
18
|
+
attr_reader :cname
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def check_name(name)
|
23
|
+
unless name =~ /(\w\.?)+\s*$/ and name =~ /[a-zA-Z]/
|
24
|
+
raise RRArgumentError, "Canonical Name not valid: #{name}"
|
25
|
+
end
|
26
|
+
name
|
27
|
+
end
|
28
|
+
|
29
|
+
def build_pack
|
30
|
+
@cname_pack = pack_name(@cname)
|
31
|
+
@rdlength = @cname_pack.size
|
32
|
+
end
|
33
|
+
|
34
|
+
def set_type
|
35
|
+
@type = Net::DNS::RR::Types.new("CNAME")
|
36
|
+
end
|
37
|
+
|
38
|
+
def get_data
|
39
|
+
@cname_pack
|
40
|
+
end
|
41
|
+
|
42
|
+
def get_inspect
|
43
|
+
"#@cname"
|
44
|
+
end
|
45
|
+
|
46
|
+
def subclass_new_from_hash(args)
|
47
|
+
if args.has_key? :cname
|
48
|
+
@cname = check_name args[:cname]
|
49
|
+
else
|
50
|
+
raise RRArgumentError, ":cname field is mandatory but missing"
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def subclass_new_from_string(str)
|
55
|
+
@cname = check_name(str)
|
56
|
+
end
|
57
|
+
|
58
|
+
def subclass_new_from_binary(data,offset)
|
59
|
+
@cname,offset = dn_expand(data,offset)
|
60
|
+
return offset
|
61
|
+
end
|
62
|
+
|
63
|
+
end # class CNAME
|
64
|
+
|
65
|
+
end # class RR
|
66
|
+
end # module DNS
|
67
|
+
end # module Net
|
68
|
+
|
69
|
+
|
@@ -0,0 +1,74 @@
|
|
1
|
+
##
|
2
|
+
#
|
3
|
+
# Net::DNS::RR::HINFO
|
4
|
+
#
|
5
|
+
# $Id: HINFO.rb,v 1.4 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 HINFO
|
15
|
+
#------------------------------------------------------------
|
16
|
+
class HINFO < RR
|
17
|
+
attr_reader :cpu, :os
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def check_hinfo(str)
|
22
|
+
if str.strip =~ /^["'](.*?)["']\s+["'](.*?)["']$/
|
23
|
+
return $1,$2
|
24
|
+
else
|
25
|
+
raise RRArgumentError, "HINFO section not valid: #{str.inspect}"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def build_pack
|
30
|
+
@hinfo_pack = [@cpu.size].pack("C") + @cpu
|
31
|
+
@hinfo_pack += [@os.size].pack("C") + @os
|
32
|
+
@rdlength = @hinfo_pack.size
|
33
|
+
end
|
34
|
+
|
35
|
+
def set_type
|
36
|
+
@type = Net::DNS::RR::Types.new("HINFO")
|
37
|
+
end
|
38
|
+
|
39
|
+
def get_data
|
40
|
+
@hinfo_pack
|
41
|
+
end
|
42
|
+
|
43
|
+
def get_inspect
|
44
|
+
"#@cpu #@os"
|
45
|
+
end
|
46
|
+
|
47
|
+
def subclass_new_from_hash(args)
|
48
|
+
if args.has_key? :cpu and args.has_key? :os
|
49
|
+
@cpu = args[:cpu]
|
50
|
+
@os = args[:os]
|
51
|
+
else
|
52
|
+
raise RRArgumentError, ":cpu and :os fields are mandatory but missing"
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def subclass_new_from_string(str)
|
57
|
+
@cpu,@os = check_hinfo(str)
|
58
|
+
end
|
59
|
+
|
60
|
+
def subclass_new_from_binary(data,offset)
|
61
|
+
len = data.unpack("@#{offset} C")[0]
|
62
|
+
@cpu = data[offset+1..offset+1+len]
|
63
|
+
offset += len+1
|
64
|
+
len = @data.unpack("@#{offset} C")[0]
|
65
|
+
@os = data[offset+1..offset+1+len]
|
66
|
+
return offset += len+1
|
67
|
+
end
|
68
|
+
|
69
|
+
end # class HINFO
|
70
|
+
|
71
|
+
end # class RR
|
72
|
+
end # module DNS
|
73
|
+
end # module Net
|
74
|
+
|
@@ -0,0 +1,68 @@
|
|
1
|
+
##
|
2
|
+
#
|
3
|
+
# Net::DNS::RR::MR
|
4
|
+
#
|
5
|
+
# $Id: MR.rb,v 1.4 2006/07/28 07:33:36 bluemonk Exp $
|
6
|
+
#
|
7
|
+
##
|
8
|
+
|
9
|
+
module Net
|
10
|
+
module DNS
|
11
|
+
|
12
|
+
class RR
|
13
|
+
|
14
|
+
#------------------------------------------------------------
|
15
|
+
# RR type MR
|
16
|
+
#------------------------------------------------------------
|
17
|
+
class MR < RR
|
18
|
+
attr_reader :newname
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def check_name(name)
|
23
|
+
unless name =~ /(\w\.?)+\s*$/
|
24
|
+
raise RRArgumentError, "Name not valid: #{name.inspect}"
|
25
|
+
end
|
26
|
+
name
|
27
|
+
end
|
28
|
+
|
29
|
+
def build_pack
|
30
|
+
@newname_pack = pack_name(@newname)
|
31
|
+
@rdlength = @newname_pack.size
|
32
|
+
end
|
33
|
+
|
34
|
+
def set_type
|
35
|
+
@type = Net::DNS::RR::Types.new("MR")
|
36
|
+
end
|
37
|
+
|
38
|
+
def get_data
|
39
|
+
@newname_pack
|
40
|
+
end
|
41
|
+
|
42
|
+
def get_inspect
|
43
|
+
"#@newname"
|
44
|
+
end
|
45
|
+
|
46
|
+
def subclass_new_from_hash(args)
|
47
|
+
if args.has_key? :newname
|
48
|
+
@newname = check_name args[:newname]
|
49
|
+
else
|
50
|
+
raise RRArgumentError, ":newname field is mandatory but missing"
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def subclass_new_from_string(str)
|
55
|
+
@newname = check_name(str)
|
56
|
+
end
|
57
|
+
|
58
|
+
def subclass_new_from_array(data,offset)
|
59
|
+
@newname = dn_expand(data,offset)
|
60
|
+
return offset
|
61
|
+
end
|
62
|
+
|
63
|
+
end # class MR
|
64
|
+
|
65
|
+
end # class RR
|
66
|
+
end # module DNS
|
67
|
+
end # module Net
|
68
|
+
|
@@ -0,0 +1,74 @@
|
|
1
|
+
##
|
2
|
+
#
|
3
|
+
# Net::DNS::RR::MX
|
4
|
+
#
|
5
|
+
# $Id: MX.rb,v 1.8 2006/07/28 07:33:36 bluemonk Exp $
|
6
|
+
#
|
7
|
+
##
|
8
|
+
|
9
|
+
|
10
|
+
module Net
|
11
|
+
module DNS
|
12
|
+
class RR
|
13
|
+
|
14
|
+
#------------------------------------------------------------
|
15
|
+
# RR type MX
|
16
|
+
#------------------------------------------------------------
|
17
|
+
class MX < RR
|
18
|
+
attr_reader :preference, :exchange
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def check_mx(str)
|
23
|
+
if str.strip =~ /^(\d+)\s+(\S+)$/
|
24
|
+
return $1.to_i,$2
|
25
|
+
else
|
26
|
+
raise RRArgumentError, "MX section not valid"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def build_pack
|
31
|
+
@mx_pack = [@preference].pack("n") + pack_name(@exchange)
|
32
|
+
@rdlength = @mx_pack.size
|
33
|
+
end
|
34
|
+
|
35
|
+
def set_type
|
36
|
+
@type = Net::DNS::RR::Types.new("MX")
|
37
|
+
end
|
38
|
+
|
39
|
+
def get_data
|
40
|
+
@mx_pack
|
41
|
+
end
|
42
|
+
|
43
|
+
def get_inspect
|
44
|
+
"#@preference #@exchange"
|
45
|
+
end
|
46
|
+
|
47
|
+
def subclass_new_from_hash(args)
|
48
|
+
if args.has_key? :preference and args.has_key? :exchange
|
49
|
+
@preference = args[0][:preference].to_i
|
50
|
+
@exchange = args[0][:exchange]
|
51
|
+
else
|
52
|
+
raise RRArgumentError, ":preference and :exchange fields are mandatory but missing"
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def subclass_new_from_string(str)
|
57
|
+
@preference,@exchange = check_mx(str)
|
58
|
+
end
|
59
|
+
|
60
|
+
def subclass_new_from_binary(data,offset)
|
61
|
+
@preference = data.unpack("@#{offset} n")[0]
|
62
|
+
offset += 2
|
63
|
+
@exchange,offset = dn_expand(data,offset)
|
64
|
+
return offset
|
65
|
+
end
|
66
|
+
|
67
|
+
end # class MX
|
68
|
+
|
69
|
+
end # class RR
|
70
|
+
end # module DNS
|
71
|
+
end # module Net
|
72
|
+
|
73
|
+
|
74
|
+
|
@@ -0,0 +1,70 @@
|
|
1
|
+
##
|
2
|
+
#
|
3
|
+
# Net::DNS::RR::NS
|
4
|
+
#
|
5
|
+
# $Id: NS.rb,v 1.8 2006/07/28 07:33:36 bluemonk Exp $
|
6
|
+
#
|
7
|
+
##
|
8
|
+
|
9
|
+
module Net
|
10
|
+
module DNS
|
11
|
+
|
12
|
+
class RR
|
13
|
+
|
14
|
+
#------------------------------------------------------------
|
15
|
+
# RR type NS
|
16
|
+
#------------------------------------------------------------
|
17
|
+
class NS < RR
|
18
|
+
attr_reader :nsdname
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def check_name(name)
|
23
|
+
unless name =~ /(\w\.?)+\s*$/ and name =~ /[a-zA-Z]/
|
24
|
+
raise RRArgumentError, "NS Domain Name not valid: #{name}"
|
25
|
+
end
|
26
|
+
name
|
27
|
+
end
|
28
|
+
|
29
|
+
def build_pack
|
30
|
+
@nsdname_pack = pack_name(@nsdname)
|
31
|
+
@rdlength = @nsdname_pack.size
|
32
|
+
end
|
33
|
+
|
34
|
+
def set_type
|
35
|
+
@type = Net::DNS::RR::Types.new("NS")
|
36
|
+
end
|
37
|
+
|
38
|
+
def get_data
|
39
|
+
@nsdname_pack
|
40
|
+
end
|
41
|
+
|
42
|
+
def get_inspect
|
43
|
+
"#@nsdname"
|
44
|
+
end
|
45
|
+
|
46
|
+
def subclass_new_from_hash(args)
|
47
|
+
if args.has_key? :nsdname
|
48
|
+
@nsdname = check_name args[:nsdname]
|
49
|
+
else
|
50
|
+
raise RRArgumentError, ":nsdname field is mandatory but missing"
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def subclass_new_from_string(str)
|
55
|
+
@nsdname = check_name(str)
|
56
|
+
end
|
57
|
+
|
58
|
+
def subclass_new_from_binary(data,offset)
|
59
|
+
@nsdname,offset = dn_expand(data,offset)
|
60
|
+
return offset
|
61
|
+
end
|
62
|
+
|
63
|
+
end # class NS
|
64
|
+
|
65
|
+
end # class RR
|
66
|
+
end # module DNS
|
67
|
+
end # module Net
|
68
|
+
|
69
|
+
|
70
|
+
|