pNet-DNS 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README +68 -0
- data/lib/Net/DNS.rb +879 -0
- data/lib/Net/DNS/Header.rb +303 -0
- data/lib/Net/DNS/Nameserver.rb +601 -0
- data/lib/Net/DNS/Packet.rb +851 -0
- data/lib/Net/DNS/Question.rb +117 -0
- data/lib/Net/DNS/RR.rb +630 -0
- data/lib/Net/DNS/RR/A.rb +103 -0
- data/lib/Net/DNS/RR/AAAA.rb +147 -0
- data/lib/Net/DNS/RR/AFSDB.rb +114 -0
- data/lib/Net/DNS/RR/CERT.rb +191 -0
- data/lib/Net/DNS/RR/CNAME.rb +89 -0
- data/lib/Net/DNS/RR/DNAME.rb +84 -0
- data/lib/Net/DNS/RR/EID.rb +70 -0
- data/lib/Net/DNS/RR/HINFO.rb +108 -0
- data/lib/Net/DNS/RR/ISDN.rb +118 -0
- data/lib/Net/DNS/RR/LOC.rb +341 -0
- data/lib/Net/DNS/RR/MB.rb +92 -0
- data/lib/Net/DNS/RR/MG.rb +96 -0
- data/lib/Net/DNS/RR/MINFO.rb +109 -0
- data/lib/Net/DNS/RR/MR.rb +92 -0
- data/lib/Net/DNS/RR/MX.rb +124 -0
- data/lib/Net/DNS/RR/NAPTR.rb +182 -0
- data/lib/Net/DNS/RR/NIMLOC.rb +70 -0
- data/lib/Net/DNS/RR/NS.rb +100 -0
- data/lib/Net/DNS/RR/NSAP.rb +273 -0
- data/lib/Net/DNS/RR/NULL.rb +68 -0
- data/lib/Net/DNS/RR/OPT.rb +251 -0
- data/lib/Net/DNS/RR/PTR.rb +93 -0
- data/lib/Net/DNS/RR/PX.rb +131 -0
- data/lib/Net/DNS/RR/RP.rb +108 -0
- data/lib/Net/DNS/RR/RT.rb +115 -0
- data/lib/Net/DNS/RR/SOA.rb +195 -0
- data/lib/Net/DNS/RR/SPF.rb +46 -0
- data/lib/Net/DNS/RR/SRV.rb +153 -0
- data/lib/Net/DNS/RR/SSHFP.rb +190 -0
- data/lib/Net/DNS/RR/TKEY.rb +219 -0
- data/lib/Net/DNS/RR/TSIG.rb +358 -0
- data/lib/Net/DNS/RR/TXT.rb +162 -0
- data/lib/Net/DNS/RR/UNKNOWN.rb +76 -0
- data/lib/Net/DNS/RR/X25.rb +90 -0
- data/lib/Net/DNS/Resolver.rb +2090 -0
- data/lib/Net/DNS/Resolver/Recurse.rb +478 -0
- data/lib/Net/DNS/Update.rb +189 -0
- data/test/custom.txt +4 -0
- data/test/resolv.conf +4 -0
- data/test/tc_escapedchars.rb +498 -0
- data/test/tc_header.rb +91 -0
- data/test/tc_inet6.rb +169 -0
- data/test/tc_misc.rb +137 -0
- data/test/tc_online.rb +236 -0
- data/test/tc_packet.rb +174 -0
- data/test/tc_packet_unique_push.rb +126 -0
- data/test/tc_question.rb +49 -0
- data/test/tc_recurse.rb +69 -0
- data/test/tc_res_env.rb +59 -0
- data/test/tc_res_file.rb +55 -0
- data/test/tc_res_opt.rb +135 -0
- data/test/tc_resolver.rb +102 -0
- data/test/tc_rr-opt.rb +40 -0
- data/test/tc_rr-rrsort.rb +116 -0
- data/test/tc_rr-txt.rb +138 -0
- data/test/tc_rr-unknown.rb +95 -0
- data/test/tc_rr.rb +246 -0
- data/test/tc_tcp.rb +34 -0
- data/test/tc_tkey.rb +115 -0
- data/test/tc_update.rb +226 -0
- data/test/ts_netdns.rb +17 -0
- data/test/ts_offline.rb +32 -0
- data/test/ts_online.rb +33 -0
- metadata +119 -0
data/README
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
pNet::DNS
|
2
|
+
---------
|
3
|
+
|
4
|
+
Ruby port of perl Net::DNS.
|
5
|
+
|
6
|
+
This project is a direct port of perl Net::DNS, version 0.57.
|
7
|
+
It has tried to stick as closely as possible to the original
|
8
|
+
perl code, to allow existing perl code to be ported quickly and
|
9
|
+
easily to Ruby. This project is not intended to be anything more
|
10
|
+
than a direct port of the perl code.
|
11
|
+
|
12
|
+
The perl test code has also been ported to Ruby, and all runs
|
13
|
+
successfully. The demo code has also been ported.
|
14
|
+
|
15
|
+
No effort has been made to fix bugs in the original perl code -
|
16
|
+
this port is as close as possible to the perl.
|
17
|
+
|
18
|
+
Author : AlexD
|
19
|
+
Contact : alexd@nominet.org.uk
|
20
|
+
Copyright (c) Nominet UK, 2006
|
21
|
+
|
22
|
+
Check out demo and test folders for examples.
|
23
|
+
|
24
|
+
Issues
|
25
|
+
------
|
26
|
+
|
27
|
+
I've still not had a chance to test on IPv6, so the functionality in
|
28
|
+
tc_inet6.rb is untested.
|
29
|
+
|
30
|
+
Nameserver.rb is a port of the perl version - bugs and all.
|
31
|
+
It's obviously broken, but would not be hard to fix.
|
32
|
+
If you need a working version of this code, please contact me.
|
33
|
+
|
34
|
+
Licensing
|
35
|
+
---------
|
36
|
+
|
37
|
+
This project is licensed under the Mozilla Public License.
|
38
|
+
|
39
|
+
The contents of this file are subject to the Mozilla Public Licence
|
40
|
+
Version 1.1 (the `Licence'); you may not use this file except in
|
41
|
+
compliance with the Licence. You may obtain a copy of the Licence at
|
42
|
+
http://www.mozilla.org/MPL
|
43
|
+
|
44
|
+
Software distributed under the Licence is distributed on an `AS IS'
|
45
|
+
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
46
|
+
the Licence of the specific language governing rights and limitations
|
47
|
+
under the Licence.
|
48
|
+
|
49
|
+
The Original Code is pNet::DNS.
|
50
|
+
|
51
|
+
The Initial Developer of the Original Code is Nominet UK
|
52
|
+
(http://www.nominet.org.uk). Portions created by Nominet UK are
|
53
|
+
Copyright (c) Nominet UK 2006. All rights reserved.
|
54
|
+
|
55
|
+
PERL AUTHOR INFORMATION
|
56
|
+
-----------------------
|
57
|
+
|
58
|
+
Net::DNS is currently maintained at NLnet Labs (www.nlnetlabs.nl) by:
|
59
|
+
Olaf Kolkman and his team.
|
60
|
+
olaf at net-dns.org
|
61
|
+
|
62
|
+
Between 2002 and 2004 Net::DNS was maintained by:
|
63
|
+
Chris Reinhardt
|
64
|
+
|
65
|
+
|
66
|
+
Net::DNS was created by:
|
67
|
+
Michael Fuhr
|
68
|
+
mike at fuhr.org
|
data/lib/Net/DNS.rb
ADDED
@@ -0,0 +1,879 @@
|
|
1
|
+
# The contents of this file are subject to the Mozilla
|
2
|
+
# Public Licence Version 1.1 (the "Licence"); you may
|
3
|
+
# not use this file except in compliance with the
|
4
|
+
# Licence. You may obtain a copy of the Licence at
|
5
|
+
# http://www.mozilla.org/MPL
|
6
|
+
# Software distributed under the Licence is distributed
|
7
|
+
# on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND,
|
8
|
+
# either express or implied. See the Licence of the
|
9
|
+
# specific language governing rights and limitations
|
10
|
+
# under the Licence.
|
11
|
+
# The Original Code is pNet::DNS.
|
12
|
+
# The Initial Developer of the Original Code is
|
13
|
+
# Nominet UK (www.nominet.org.uk). Portions created by
|
14
|
+
# Nominet UK are Copyright (c) Nominet UK 2006.
|
15
|
+
# All rights reserved.
|
16
|
+
require 'Net/DNS/Resolver'
|
17
|
+
require 'Net/DNS/Nameserver'
|
18
|
+
|
19
|
+
|
20
|
+
module Net
|
21
|
+
#= NAME
|
22
|
+
#
|
23
|
+
#Net::DNS - Perl interface to the DNS resolver
|
24
|
+
#
|
25
|
+
#= SYNOPSIS
|
26
|
+
#
|
27
|
+
#<tt>use Net::DNS;</tt>
|
28
|
+
#
|
29
|
+
#= DESCRIPTION
|
30
|
+
#
|
31
|
+
#Net::DNS is a collection of modules that act as a Domain
|
32
|
+
#Name System (DNS) resolver. It is a port of the perl
|
33
|
+
#Net::DNS package.
|
34
|
+
#
|
35
|
+
#The programmer should be somewhat familiar with the format of
|
36
|
+
#a DNS packet and its various sections. See RFC 1035 or
|
37
|
+
#<em>DNS and BIND</em> (Albitz & Liu) for details.
|
38
|
+
#
|
39
|
+
#= Resolver Objects
|
40
|
+
#
|
41
|
+
#A resolver object is an instance of the
|
42
|
+
#Net::DNS::Resolver class. A program can have
|
43
|
+
#multiple resolver objects, each maintaining its own state information
|
44
|
+
#such as the nameservers to be queried, whether recursion is desired,
|
45
|
+
#etc.
|
46
|
+
#
|
47
|
+
#== Packet Objects
|
48
|
+
#
|
49
|
+
#Net::DNS::Resolver queries return
|
50
|
+
#Net::DNS::Packet objects. Packet objects have five
|
51
|
+
#sections:
|
52
|
+
#
|
53
|
+
# * The header section, a Net::DNS::Header object.
|
54
|
+
#
|
55
|
+
# * The question section, a list of Net::DNS::Question objects.
|
56
|
+
#
|
57
|
+
# * The answer section, a list of Net::DNS::RR objects.
|
58
|
+
#
|
59
|
+
# * The authority section, a list of Net::DNS::RR objects.
|
60
|
+
#
|
61
|
+
# * The additional section, a list of Net::DNS::RR objects.
|
62
|
+
#
|
63
|
+
#== Update Objects
|
64
|
+
#
|
65
|
+
#The Net::DNS::Update package is a subclass of
|
66
|
+
#Net::DNS::Packet for creating packet objects to be
|
67
|
+
#used in dynamic updates.
|
68
|
+
#
|
69
|
+
#== Header Objects
|
70
|
+
#
|
71
|
+
#Net::DNS::Header objects represent the header
|
72
|
+
#section of a DNS packet.
|
73
|
+
#
|
74
|
+
#== Question Objects
|
75
|
+
#
|
76
|
+
#Net::DNS::Question objects represent the question
|
77
|
+
#section of a DNS packet.
|
78
|
+
#
|
79
|
+
#== RR Objects
|
80
|
+
#
|
81
|
+
#Net::DNS::RR is the base class for DNS resource record
|
82
|
+
#(RR) objects in the answer, authority, and additional sections of a DNS
|
83
|
+
#packet.
|
84
|
+
#
|
85
|
+
#Don't assume that RR objects will be of the type you requested -- always
|
86
|
+
#check an RR object's type before calling any of its methods.
|
87
|
+
#
|
88
|
+
#== Sorting of RR arrays
|
89
|
+
#
|
90
|
+
#As of version 0.55 there is functionality to help you sort RR
|
91
|
+
#arrays. 'rrsort()' is the function that is available to do the
|
92
|
+
#sorting. In most cases rrsort will give you the answer that you
|
93
|
+
#want but you can specify your own sorting method by using the
|
94
|
+
#Net::DNS::RR::FOO.set_rrsort_func() class method. See Net::DNS::RR
|
95
|
+
#for details.
|
96
|
+
#
|
97
|
+
#= EXAMPLES
|
98
|
+
#
|
99
|
+
#The following examples show how to use the <tt>Net::DNS</tt> modules.
|
100
|
+
#See the other manual pages and the demo scripts included with the
|
101
|
+
#source code for additional examples.
|
102
|
+
#
|
103
|
+
#See the <tt>Net::DNS::Update</tt> manual page for an example of performing
|
104
|
+
#dynamic updates.
|
105
|
+
#
|
106
|
+
#== Look up a host's addresses.
|
107
|
+
#
|
108
|
+
# require 'Net/DNS'
|
109
|
+
# res = Net::DNS::Resolver.new
|
110
|
+
# query = res.search("host.example.com")
|
111
|
+
#
|
112
|
+
# if (query)
|
113
|
+
# query.answer.each do |rr|
|
114
|
+
# next unless rr.class == Net::DNS::RR::A
|
115
|
+
# print rr.address + "\n"
|
116
|
+
# end
|
117
|
+
# else
|
118
|
+
# print "query failed: " + res.errorstring + "\n"
|
119
|
+
# end
|
120
|
+
#
|
121
|
+
#
|
122
|
+
#== Find the nameservers for a domain.
|
123
|
+
#
|
124
|
+
# require 'Net/DNS'
|
125
|
+
# res = Net::DNS::Resolver.new
|
126
|
+
# query = res.query("example.com", "NS")
|
127
|
+
#
|
128
|
+
# if (query)
|
129
|
+
# (query.answer.select { |i| i.class == Net::DNS::RR::NS}).each do |rr|
|
130
|
+
# print rr.nsdname + "\n"
|
131
|
+
# end
|
132
|
+
# else
|
133
|
+
# print "query failed: " + res.errorstring + "\n"
|
134
|
+
# end
|
135
|
+
#
|
136
|
+
#== Find the MX records for a domain.
|
137
|
+
#
|
138
|
+
# require 'Net/DNS'
|
139
|
+
# name='ENTER_NAME_HERE'
|
140
|
+
# res = Net::DNS::Resolver.new
|
141
|
+
# mx = Net::DNS.mx(name, res, 'IN')
|
142
|
+
#
|
143
|
+
# if (mx)
|
144
|
+
# mx.each do |rr|
|
145
|
+
# print rr.preference, " ", rr.exchange, "\n"
|
146
|
+
# end
|
147
|
+
# else
|
148
|
+
# print "Can't find MX records for #{name}: " + res.errorstring + "\n"
|
149
|
+
# end
|
150
|
+
#
|
151
|
+
#== Print a domain's SOA record in zone file format.
|
152
|
+
#
|
153
|
+
# require 'Net/DNS'
|
154
|
+
# res = Net::DNS::Resolver.new
|
155
|
+
# query = res.query("example.com", "SOA")
|
156
|
+
#
|
157
|
+
# if (query)
|
158
|
+
# (query.answer)[0].print
|
159
|
+
# else
|
160
|
+
# print "query failed: ", res.errorstring, "\n"
|
161
|
+
# end
|
162
|
+
#
|
163
|
+
#== Perform a zone transfer and print all the records.
|
164
|
+
#
|
165
|
+
# require 'Net/DNS'
|
166
|
+
# res = Net::DNS::Resolver.new
|
167
|
+
# res.nameservers("ns.example.com")
|
168
|
+
#
|
169
|
+
# zone = res.axfr("example.com")
|
170
|
+
#
|
171
|
+
# zone.each do |rr|
|
172
|
+
# rr.print
|
173
|
+
# end
|
174
|
+
#
|
175
|
+
#--
|
176
|
+
#== Perform a background query and do some other work while waiting
|
177
|
+
#for the answer.
|
178
|
+
#
|
179
|
+
# require 'Net/DNS'
|
180
|
+
# res = Net::DNS::Resolver.new
|
181
|
+
# socket = res.bgsend("host.example.com")
|
182
|
+
#
|
183
|
+
# until (res.bgisready(socket))
|
184
|
+
# # do some work here while waiting for the answer
|
185
|
+
# # ...and some more here
|
186
|
+
# end
|
187
|
+
#
|
188
|
+
# packet = res.bgread(socket)
|
189
|
+
# packet.print
|
190
|
+
#
|
191
|
+
#
|
192
|
+
#== Send a background query and use select to determine when the answer
|
193
|
+
#has arrived.
|
194
|
+
#
|
195
|
+
# require 'Net/DNS'
|
196
|
+
#
|
197
|
+
# timeout = 5
|
198
|
+
# res = Net::DNS::Resolver.new
|
199
|
+
# sockets = [res.bgsend("host.example.com")]
|
200
|
+
#
|
201
|
+
# # Add more sockets to sockets if desired.
|
202
|
+
# ready = IO::select(sockets, nil, nil, timeout)[0]
|
203
|
+
# if (ready != nil)
|
204
|
+
# ready.each do { |sock|
|
205
|
+
# if (sock == bgsock)
|
206
|
+
# packet = res.bgread(bgsock)
|
207
|
+
# packet.print
|
208
|
+
# bgsock = nil
|
209
|
+
# end
|
210
|
+
# # Check for the other sockets.
|
211
|
+
# sockets.remove(sock)
|
212
|
+
# end
|
213
|
+
# else
|
214
|
+
# warn "timed out after #{timeout} seconds\n"
|
215
|
+
# end
|
216
|
+
#
|
217
|
+
#++
|
218
|
+
#
|
219
|
+
#= BUGS
|
220
|
+
#
|
221
|
+
#Net::DNS is slow.
|
222
|
+
#
|
223
|
+
#For other items to be fixed, please see the "TODO" file included with
|
224
|
+
#the source distribution.
|
225
|
+
#
|
226
|
+
#= COPYRIGHT
|
227
|
+
#
|
228
|
+
#Copyright (c) 1997-2002 Michael Fuhr.
|
229
|
+
#
|
230
|
+
#Portions Copyright (c) 2002-2004 Chris Reinhardt.
|
231
|
+
#
|
232
|
+
#Portions Copyright (c) 2005 Olaf Kolkman (RIPE NCC)
|
233
|
+
#
|
234
|
+
#Portions Copyright (c) 2006 Olaf Kolkman (NLnet Labs)
|
235
|
+
#
|
236
|
+
#Portions Copyright (c) 2006 AlexD (Nominet UK)
|
237
|
+
#
|
238
|
+
#All rights reserved. This program is distributed under the
|
239
|
+
#Mozilla Public License (MPL1.1)
|
240
|
+
#
|
241
|
+
#= AUTHOR INFORMATION
|
242
|
+
#
|
243
|
+
#Ruby port (2006) from Nominet UK by :
|
244
|
+
# Alex D
|
245
|
+
# alexd@nominet.org.uk
|
246
|
+
#
|
247
|
+
#Port from perl Net::DNS (version 0.57) maintained at NLnet Labs (www.nlnetlabs.nl) by:
|
248
|
+
# Olaf Kolkman
|
249
|
+
# olaf@net-dns.org
|
250
|
+
#
|
251
|
+
#Between 2002 and 2004 Net::DNS was maintained by:
|
252
|
+
# Chris Reinhardt
|
253
|
+
#
|
254
|
+
#
|
255
|
+
#Net::DNS was created by:
|
256
|
+
# Michael Fuhr
|
257
|
+
# mike@fuhr.org
|
258
|
+
#
|
259
|
+
#
|
260
|
+
#
|
261
|
+
#For more information see:
|
262
|
+
# http://www.net-dns.org/
|
263
|
+
#
|
264
|
+
#Stay tuned and syncicate:
|
265
|
+
# http://www.net-dns.org/blog/
|
266
|
+
#
|
267
|
+
#= SEE ALSO
|
268
|
+
#
|
269
|
+
# Net::DNS::Resolver, Net::DNS::Packet, Net::DNS::Update,
|
270
|
+
#Net::DNS::Header, Net::DNS::Question, Net::DNS::RR, RFC 1035,
|
271
|
+
#<em>DNS and BIND</em> by Paul Albitz & Cricket Liu
|
272
|
+
module DNS
|
273
|
+
|
274
|
+
|
275
|
+
#Returns the version of Net::DNS.
|
276
|
+
VERSION = '0.0.1'
|
277
|
+
#Returns the default packet size
|
278
|
+
PACKETSZ = 512
|
279
|
+
#Header size
|
280
|
+
HFIXEDSZ = 12
|
281
|
+
QFIXEDSZ = 4
|
282
|
+
RRFIXEDSZ = 10
|
283
|
+
INT32SZ = 4
|
284
|
+
INT16SZ = 2
|
285
|
+
|
286
|
+
HAVE_XS = false # @TODO
|
287
|
+
DNSSEC = false # @TODO
|
288
|
+
DN_EXPAND_ESCAPES = false # @TODO
|
289
|
+
|
290
|
+
|
291
|
+
#--
|
292
|
+
# If you implement an RR record make sure you also add it to
|
293
|
+
# Net::DNS::RR::RR hash otherwise it will be treated as unknown type.
|
294
|
+
#
|
295
|
+
|
296
|
+
# Do not use these tybesby hashes directly. Use the interface
|
297
|
+
# functions, see below.
|
298
|
+
#
|
299
|
+
Typesbyname = {
|
300
|
+
'SIGZERO' => 0, # RFC2931 consider this a pseudo type
|
301
|
+
'A' => 1, # RFC 1035, Section 3.4.1
|
302
|
+
'NS' => 2, # RFC 1035, Section 3.3.11
|
303
|
+
'MD' => 3, # RFC 1035, Section 3.3.4 (obsolete)
|
304
|
+
'MF' => 4, # RFC 1035, Section 3.3.5 (obsolete)
|
305
|
+
'CNAME' => 5, # RFC 1035, Section 3.3.1
|
306
|
+
'SOA' => 6, # RFC 1035, Section 3.3.13
|
307
|
+
'MB' => 7, # RFC 1035, Section 3.3.3
|
308
|
+
'MG' => 8, # RFC 1035, Section 3.3.6
|
309
|
+
'MR' => 9, # RFC 1035, Section 3.3.8
|
310
|
+
'NULL' => 10, # RFC 1035, Section 3.3.10
|
311
|
+
'WKS' => 11, # RFC 1035, Section 3.4.2 (deprecated)
|
312
|
+
'PTR' => 12, # RFC 1035, Section 3.3.12
|
313
|
+
'HINFO' => 13, # RFC 1035, Section 3.3.2
|
314
|
+
'MINFO' => 14, # RFC 1035, Section 3.3.7
|
315
|
+
'MX' => 15, # RFC 1035, Section 3.3.9
|
316
|
+
'TXT' => 16, # RFC 1035, Section 3.3.14
|
317
|
+
'RP' => 17, # RFC 1183, Section 2.2
|
318
|
+
'AFSDB' => 18, # RFC 1183, Section 1
|
319
|
+
'X25' => 19, # RFC 1183, Section 3.1
|
320
|
+
'ISDN' => 20, # RFC 1183, Section 3.2
|
321
|
+
'RT' => 21, # RFC 1183, Section 3.3
|
322
|
+
'NSAP' => 22, # RFC 1706, Section 5
|
323
|
+
'NSAP_PTR' => 23, # RFC 1348 (obsolete)
|
324
|
+
# The following 2 RRs are impemented in Net::DNS::SEC
|
325
|
+
'SIG' => 24, # RFC 2535, Section 4.1
|
326
|
+
'KEY' => 25, # RFC 2535, Section 3.1
|
327
|
+
'PX' => 26, # RFC 2163,
|
328
|
+
'GPOS' => 27, # RFC 1712 (obsolete)
|
329
|
+
'AAAA' => 28, # RFC 1886, Section 2.1
|
330
|
+
'LOC' => 29, # RFC 1876
|
331
|
+
# The following RR is impemented in Net::DNS::SEC
|
332
|
+
'NXT' => 30, # RFC 2535, Section 5.2 obsoleted by RFC3755
|
333
|
+
'EID' => 31, # draft-ietf-nimrod-dns-xx.txt
|
334
|
+
'NIMLOC' => 32, # draft-ietf-nimrod-dns-xx.txt
|
335
|
+
'SRV' => 33, # RFC 2052
|
336
|
+
'ATMA' => 34, # ???
|
337
|
+
'NAPTR' => 35, # RFC 2168
|
338
|
+
'KX' => 36, # RFC 2230
|
339
|
+
'CERT' => 37, # RFC 2538
|
340
|
+
'DNAME' => 39, # RFC 2672
|
341
|
+
'OPT' => 41, # RFC 2671
|
342
|
+
# The following 4 RRs are impemented in Net::DNS::SEC
|
343
|
+
'DS' => 43, # RFC 4034
|
344
|
+
'SSHFP' => 44, # draft-ietf-secsh-dns (No RFC # yet at time of coding)
|
345
|
+
# 'IPSECKEY' => 45, # RFC 4025
|
346
|
+
'RRSIG' => 46, # RFC 4034
|
347
|
+
'NSEC' => 47, # RFC 4034
|
348
|
+
'DNSKEY' => 48, # RFC 4034
|
349
|
+
'SPF' => 99, # rfc-schlitt-spf-classic-o2 (No RFC # yet at time of coding)
|
350
|
+
'UINFO' => 100, # non-standard
|
351
|
+
'UID' => 101, # non-standard
|
352
|
+
'GID' => 102, # non-standard
|
353
|
+
'UNSPEC' => 103, # non-standard
|
354
|
+
'TKEY' => 249, # RFC 2930
|
355
|
+
'TSIG' => 250, # RFC 2931
|
356
|
+
'IXFR' => 251, # RFC 1995
|
357
|
+
'AXFR' => 252, # RFC 1035
|
358
|
+
'MAILB' => 253, # RFC 1035 (MB, MG, MR)
|
359
|
+
'MAILA' => 254, # RFC 1035 (obsolete - see MX)
|
360
|
+
'ANY' => 255, # RFC 1035
|
361
|
+
}
|
362
|
+
Typesbyval = Typesbyname.invert;
|
363
|
+
|
364
|
+
#
|
365
|
+
# Do not use these classesby hashes directly. See below.
|
366
|
+
#
|
367
|
+
|
368
|
+
Classesbyname = {
|
369
|
+
'IN' => 1, # RFC 1035
|
370
|
+
'CH' => 3, # RFC 1035
|
371
|
+
'CHAOS' => 3, # RFC 1035
|
372
|
+
'HS' => 4, # RFC 1035
|
373
|
+
'HESIOD' => 4, # RFC 1035
|
374
|
+
'NONE' => 254, # RFC 2136
|
375
|
+
'ANY' => 255, # RFC 1035
|
376
|
+
}
|
377
|
+
Classesbyval = {
|
378
|
+
1 => 'IN', # RFC 1035
|
379
|
+
3 => 'CH', # RFC 1035
|
380
|
+
4 => 'HS', # RFC 1035
|
381
|
+
254 => 'NONE', # RFC 2136
|
382
|
+
255 => 'ANY', # RFC 1035
|
383
|
+
}
|
384
|
+
|
385
|
+
|
386
|
+
# The qtypesbyval and metatypesbyval specify special typecodes
|
387
|
+
# See rfc2929 and the relevant IANA registry
|
388
|
+
# http://www.iana.org/assignments/dns-parameters
|
389
|
+
|
390
|
+
|
391
|
+
Qtypesbyname = {
|
392
|
+
'IXFR' => 251, # incremental transfer [RFC1995]
|
393
|
+
'AXFR' => 252, # transfer of an entire zone [RFC1035]
|
394
|
+
'MAILB' => 253, # mailbox-related RRs (MB, MG or MR) [RFC1035]
|
395
|
+
'MAILA' => 254, # mail agent RRs (Obsolete - see MX) [RFC1035]
|
396
|
+
'ANY' => 255, # all records [RFC1035]
|
397
|
+
}
|
398
|
+
Qtypesbyval = Qtypesbyname.invert;
|
399
|
+
|
400
|
+
|
401
|
+
Metatypesbyname = {
|
402
|
+
'TKEY' => 249, # Transaction Key [RFC2930]
|
403
|
+
'TSIG' => 250, # Transaction Signature [RFC2845]
|
404
|
+
'OPT' => 41, # RFC 2671
|
405
|
+
}
|
406
|
+
Metatypesbyval = Metatypesbyname.invert;
|
407
|
+
|
408
|
+
|
409
|
+
Opcodesbyname = {
|
410
|
+
'QUERY' => 0, # RFC 1035
|
411
|
+
'IQUERY' => 1, # RFC 1035
|
412
|
+
'STATUS' => 2, # RFC 1035
|
413
|
+
'NS_NOTIFY_OP' => 4, # RFC 1996
|
414
|
+
'UPDATE' => 5, # RFC 2136
|
415
|
+
}
|
416
|
+
Opcodesbyval = Opcodesbyname.invert;
|
417
|
+
|
418
|
+
|
419
|
+
Rcodesbyname = {
|
420
|
+
'NOERROR' => 0, # RFC 1035
|
421
|
+
'FORMERR' => 1, # RFC 1035
|
422
|
+
'SERVFAIL' => 2, # RFC 1035
|
423
|
+
'NXDOMAIN' => 3, # RFC 1035
|
424
|
+
'NOTIMP' => 4, # RFC 1035
|
425
|
+
'REFUSED' => 5, # RFC 1035
|
426
|
+
'YXDOMAIN' => 6, # RFC 2136
|
427
|
+
'YXRRSET' => 7, # RFC 2136
|
428
|
+
'NXRRSET' => 8, # RFC 2136
|
429
|
+
'NOTAUTH' => 9, # RFC 2136
|
430
|
+
'NOTZONE' => 10, # RFC 2136
|
431
|
+
}
|
432
|
+
Rcodesbyval = Rcodesbyname.invert;
|
433
|
+
|
434
|
+
#--
|
435
|
+
# typesbyval and typesbyname functions are wrappers around the similarly named
|
436
|
+
# hashes. They are used for 'unknown' DNS RR types (RFC3597)
|
437
|
+
# typesbyname returns they TYPEcode as a function of the TYPE
|
438
|
+
# mnemonic. If the TYPE mapping is not specified the generic mnemonic
|
439
|
+
# TYPE### is returned.
|
440
|
+
def DNS.typesbyname(name)
|
441
|
+
name.upcase!
|
442
|
+
|
443
|
+
if Typesbyname[name]
|
444
|
+
return Typesbyname[name]
|
445
|
+
end
|
446
|
+
|
447
|
+
|
448
|
+
if ((name =~/^\s*TYPE(\d+)\s*$/o)==nil)
|
449
|
+
raise ArgumentError, "Net::DNS::typesbyname() argument (#{name}) is not TYPE###"
|
450
|
+
end
|
451
|
+
|
452
|
+
val = $1.to_i
|
453
|
+
if val > 0xffff
|
454
|
+
raise ArgumentError, 'Net::DNS::typesbyname() argument larger than ' + 0xffff
|
455
|
+
end
|
456
|
+
|
457
|
+
return val;
|
458
|
+
end
|
459
|
+
|
460
|
+
|
461
|
+
# typesbyval returns they TYPE mnemonic as a function of the TYPE
|
462
|
+
# code. If the TYPE mapping is not specified the generic mnemonic
|
463
|
+
# TYPE### is returned.
|
464
|
+
def DNS.typesbyval(val)
|
465
|
+
if (!defined?val)
|
466
|
+
raise ArgumentError, "Net::DNS::typesbyval() argument is not defined"
|
467
|
+
end
|
468
|
+
|
469
|
+
if val.class == String
|
470
|
+
# if val.gsub!("^\s*0*(\d+)\s*$", "$1")
|
471
|
+
if ((val =~ /^\s*0*(\d+)\s*$", "$1/o) == nil)
|
472
|
+
raise ArgumentError, "Net::DNS::typesbyval() argument (#{val}) is not numeric"
|
473
|
+
# val =~s/^\s*0*(\d+)\s*$/$1/o;
|
474
|
+
end
|
475
|
+
|
476
|
+
val = $1.to_i
|
477
|
+
end
|
478
|
+
|
479
|
+
|
480
|
+
if Typesbyval[val]
|
481
|
+
return Typesbyval[val]
|
482
|
+
end
|
483
|
+
|
484
|
+
raise ArgumentError, 'Net::DNS::typesbyval() argument larger than ' + 0xffff if
|
485
|
+
val > 0xffff;
|
486
|
+
|
487
|
+
return "TYPE#{val}";
|
488
|
+
end
|
489
|
+
|
490
|
+
|
491
|
+
|
492
|
+
# classesbyval and classesbyname functions are wrappers around the
|
493
|
+
# similarly named hashes. They are used for 'unknown' DNS RR classess
|
494
|
+
# (RFC3597)
|
495
|
+
# See typesbyval and typesbyname, these beasts have the same functionality
|
496
|
+
def DNS.classesbyname(name)
|
497
|
+
name.upcase!;
|
498
|
+
if Classesbyname[name]
|
499
|
+
return Classesbyname[name]
|
500
|
+
end
|
501
|
+
|
502
|
+
if ((name =~/^\s*CLASS(\d+)\s*$/o) == nil)
|
503
|
+
raise ArgumentError, "Net::DNS::classesbyval() argument is not CLASS### (#{name})"
|
504
|
+
end
|
505
|
+
|
506
|
+
val = $1.to_i
|
507
|
+
if val > 0xffff
|
508
|
+
raise ArgumentError, 'Net::DNS::classesbyval() argument larger than ' + 0xffff
|
509
|
+
end
|
510
|
+
|
511
|
+
return val;
|
512
|
+
end
|
513
|
+
|
514
|
+
|
515
|
+
|
516
|
+
def DNS.classesbyval(val)
|
517
|
+
if (val.class == String)
|
518
|
+
if ((val =~ /^\s*0*([0-9]+)\s*$/) == nil)
|
519
|
+
raise ArgumentError, "Net::DNS::classesbybal() argument is not numeric (#{val})" # unless val.gsub!("^\s*0*([0-9]+)\s*$", "$1")
|
520
|
+
# val =~ s/^\s*0*([0-9]+)\s*$/$1/o;#
|
521
|
+
end
|
522
|
+
val = $1.to_i
|
523
|
+
end
|
524
|
+
|
525
|
+
return Classesbyval[val] if Classesbyval[val];
|
526
|
+
|
527
|
+
raise ArgumentError, 'Net::DNS::classesbyval() argument larger than ' + 0xffff if val > 0xffff;
|
528
|
+
|
529
|
+
return "CLASS#{val}";
|
530
|
+
end
|
531
|
+
|
532
|
+
# Usage:
|
533
|
+
# mxes = mx('example.com', 'IN')
|
534
|
+
#
|
535
|
+
# # Use a default resolver -- can't get an error string this way.
|
536
|
+
# require 'Net/DNS'
|
537
|
+
# mx = Net::DNS.mx("example.com")
|
538
|
+
#
|
539
|
+
# # Use your own resolver object.
|
540
|
+
# require 'Net/DNS'
|
541
|
+
# res = Net::DNS::Resolver.new
|
542
|
+
# mx = Net::DNS.mx("example.com", res)
|
543
|
+
#
|
544
|
+
#Returns a list of Net::DNS::RR::MX objects
|
545
|
+
#representing the MX records for the specified name; the list will be
|
546
|
+
#sorted by preference. Returns an empty list if the query failed or no MX
|
547
|
+
#records were found.
|
548
|
+
#
|
549
|
+
#This method does not look up A records -- it only performs MX queries.
|
550
|
+
#
|
551
|
+
#See EXAMPLES for a more complete example.
|
552
|
+
#
|
553
|
+
def DNS.mx(name, resolver=nil, klass='IN')
|
554
|
+
if resolver == nil
|
555
|
+
resolver = Net::DNS::Resolver.new
|
556
|
+
end
|
557
|
+
|
558
|
+
ans = resolver.query(name, 'MX', klass) || return;
|
559
|
+
|
560
|
+
# This construct is best read backwords.
|
561
|
+
#
|
562
|
+
# First we take the answer secion of the packet.
|
563
|
+
# Then we take just the MX records from that list
|
564
|
+
# Then we sort the list by preference
|
565
|
+
# Then we return it.
|
566
|
+
# We do this into an array to force list context.
|
567
|
+
ret = []
|
568
|
+
ans.answer.each do |rec|
|
569
|
+
if (rec.type == 'MX')
|
570
|
+
ret.push(rec)
|
571
|
+
end
|
572
|
+
end
|
573
|
+
ret.sort! { |a,b| a.preference <=> b.preference }
|
574
|
+
|
575
|
+
return ret;
|
576
|
+
end
|
577
|
+
|
578
|
+
#Use this method to add an "RRset exists" prerequisite to a dynamic
|
579
|
+
#update packet. There are two forms, value-independent and
|
580
|
+
#value-dependent:
|
581
|
+
#
|
582
|
+
# # RRset exists (value-independent)
|
583
|
+
# update.push('pre' => yxrrset("host.example.com A"))
|
584
|
+
#
|
585
|
+
#Meaning: At least one RR with the specified name and type must
|
586
|
+
#exist.
|
587
|
+
#
|
588
|
+
# # RRset exists (value-dependent)
|
589
|
+
# packet.push('pre' => yxrrset("host.example.com A 10.1.2.3"))
|
590
|
+
#
|
591
|
+
#Meaning: At least one RR with the specified name and type must
|
592
|
+
#exist and must have matching data.
|
593
|
+
#
|
594
|
+
#Returns a Net::DNS::RR object or nil if the object couldn't
|
595
|
+
#be created.
|
596
|
+
def DNS.yxrrset(arg)
|
597
|
+
return Net::DNS::RR.new_from_string(arg, 'yxrrset');
|
598
|
+
end
|
599
|
+
|
600
|
+
#Use this method to add an "RRset does not exist" prerequisite to
|
601
|
+
#a dynamic update packet.
|
602
|
+
#
|
603
|
+
# packet.push('pre' => nxrrset("host.example.com A"))
|
604
|
+
#
|
605
|
+
#Meaning: No RRs with the specified name and type can exist.
|
606
|
+
#
|
607
|
+
#Returns a Net::DNS::RR object or nil if the object couldn't
|
608
|
+
#be created.
|
609
|
+
#
|
610
|
+
def DNS.nxrrset(arg)
|
611
|
+
return Net::DNS::RR.new_from_string(arg, 'nxrrset');
|
612
|
+
end
|
613
|
+
|
614
|
+
#Use this method to add a "name is in use" prerequisite to a dynamic
|
615
|
+
#update packet.
|
616
|
+
#
|
617
|
+
# packet.push('pre' => yxdomain("host.example.com"))
|
618
|
+
#
|
619
|
+
#Meaning: At least one RR with the specified name must exist.
|
620
|
+
#
|
621
|
+
#Returns a Net::DNS::RR object or nil if the object couldn't
|
622
|
+
#be created.
|
623
|
+
def DNS.yxdomain(arg)
|
624
|
+
return Net::DNS::RR.new_from_string(arg, 'yxdomain')
|
625
|
+
end
|
626
|
+
|
627
|
+
#Use this method to add a "name is not in use" prerequisite to a
|
628
|
+
#dynamic update packet.
|
629
|
+
#
|
630
|
+
# packet.push('pre' => nxdomain("host.example.com"))
|
631
|
+
#
|
632
|
+
#Meaning: No RR with the specified name can exist.
|
633
|
+
#
|
634
|
+
#Returns a Net::DNS::RR object or nil if the object couldn't
|
635
|
+
#be created.
|
636
|
+
#
|
637
|
+
def DNS.nxdomain(arg)
|
638
|
+
return Net::DNS::RR.new_from_string(arg, 'nxdomain')
|
639
|
+
end
|
640
|
+
|
641
|
+
#Use this method to add RRs to a zone.
|
642
|
+
#
|
643
|
+
# packet.push('update' => rr_add("host.example.com A 10.1.2.3"))
|
644
|
+
#
|
645
|
+
#Meaning: Add this RR to the zone.
|
646
|
+
#
|
647
|
+
#RR objects created by this method should be added to the "update"
|
648
|
+
#section of a dynamic update packet. The TTL defaults to 86400
|
649
|
+
#seconds (24 hours) if not specified.
|
650
|
+
#
|
651
|
+
#Returns a C<Net::DNS::RR object or nil if the object couldn't
|
652
|
+
#be created.
|
653
|
+
#
|
654
|
+
def DNS.rr_add(arg)
|
655
|
+
return Net::DNS::RR.new_from_string(arg, 'rr_add');
|
656
|
+
end
|
657
|
+
|
658
|
+
#Use this method to delete RRs from a zone. There are three forms:
|
659
|
+
#delete an RRset, delete all RRsets, and delete an RR.
|
660
|
+
#
|
661
|
+
# # Delete an RRset.
|
662
|
+
# packet.push(:update => rr_del("host.example.com A"))
|
663
|
+
#
|
664
|
+
#Meaning: Delete all RRs having the specified name and type.
|
665
|
+
#
|
666
|
+
# # Delete all RRsets.
|
667
|
+
# packet.push(:update => rr_del("host.example.com"))
|
668
|
+
#
|
669
|
+
#Meaning: Delete all RRs having the specified name.
|
670
|
+
#
|
671
|
+
# # Delete an RR.
|
672
|
+
# packet.push(:update => rr_del("host.example.com A 10.1.2.3"))
|
673
|
+
#
|
674
|
+
#Meaning: Delete all RRs having the specified name, type, and data.
|
675
|
+
#
|
676
|
+
#RR objects created by this method should be added to the "update"
|
677
|
+
#section of a dynamic update packet.
|
678
|
+
#
|
679
|
+
#Returns a Net::DNS::RR object or nil if the object couldn't
|
680
|
+
#be created.
|
681
|
+
#
|
682
|
+
def DNS.rr_del(arg)
|
683
|
+
return Net::DNS::RR.new_from_string(arg, 'rr_del')
|
684
|
+
end
|
685
|
+
|
686
|
+
|
687
|
+
# Utility function
|
688
|
+
#
|
689
|
+
# name2labels to translate names from presentation format into an
|
690
|
+
# array of "wire-format" labels.
|
691
|
+
# in: dName a string with a domain name in presentation format (1035
|
692
|
+
# sect 5.1)
|
693
|
+
# out: an array of labels in wire format.
|
694
|
+
def DNS.name2labels (dName)
|
695
|
+
names=[]
|
696
|
+
j=0;
|
697
|
+
while (dName && dName.length > 0)
|
698
|
+
names[j],dName = presentation2wire(dName)
|
699
|
+
j+=1
|
700
|
+
end
|
701
|
+
|
702
|
+
return names
|
703
|
+
end
|
704
|
+
|
705
|
+
|
706
|
+
def DNS.wire2presentation(wire)
|
707
|
+
presentation=""
|
708
|
+
length=wire.length
|
709
|
+
# There must be a nice regexp to do this.. but since I failed to
|
710
|
+
# find one I scan the name string until I find a '\', at that time
|
711
|
+
# I start looking forward and do the magic.
|
712
|
+
|
713
|
+
i=0;
|
714
|
+
|
715
|
+
while (i < length )
|
716
|
+
c=wire.unpack("x#{i}C1") [0]
|
717
|
+
if ( c < 33 || c > 126 )
|
718
|
+
presentation=presentation + sprintf("\\%03u" ,c)
|
719
|
+
elsif ( c.chr == "\"" )
|
720
|
+
presentation=presentation + "\\\""
|
721
|
+
elsif ( c.chr == "\$")
|
722
|
+
presentation=presentation + "\\\$"
|
723
|
+
elsif ( c.chr == "(" )
|
724
|
+
presentation=presentation + "\\("
|
725
|
+
elsif ( c.chr == ")" )
|
726
|
+
presentation=presentation + "\\)"
|
727
|
+
elsif ( c.chr == ";" )
|
728
|
+
presentation=presentation + "\\;"
|
729
|
+
elsif ( c.chr == "@" )
|
730
|
+
presentation=presentation + "\\@"
|
731
|
+
elsif ( c.chr == "\\" )
|
732
|
+
presentation=presentation + "\\\\"
|
733
|
+
elsif ( c.chr == ".")
|
734
|
+
presentation=presentation + "\\."
|
735
|
+
else
|
736
|
+
presentation=presentation + c.chr()
|
737
|
+
end
|
738
|
+
i=i+1
|
739
|
+
end
|
740
|
+
|
741
|
+
return presentation
|
742
|
+
end
|
743
|
+
|
744
|
+
|
745
|
+
|
746
|
+
# wire,leftover=presentation2wire(leftover)
|
747
|
+
# Will parse the input presentation format and return everything before
|
748
|
+
# the first non-escaped "." in the first element of the return array and
|
749
|
+
# all that has not been parsed yet in the 2nd argument.
|
750
|
+
def DNS.presentation2wire(presentation)
|
751
|
+
wire="";
|
752
|
+
length=presentation.length;
|
753
|
+
|
754
|
+
i=0;
|
755
|
+
|
756
|
+
while (i < length )
|
757
|
+
c=presentation.unpack("x#{i}C1") [0]
|
758
|
+
if (c == 46) # ord('.')
|
759
|
+
# return (wire,substr(presentation,i+1));
|
760
|
+
# return wire,presentation[i+1, length-(i+1)]
|
761
|
+
endstring = presentation[i+1, presentation.length-(i+1)]
|
762
|
+
return wire,endstring
|
763
|
+
end
|
764
|
+
if (c == 92) # ord'\\'
|
765
|
+
#backslash found
|
766
|
+
# pos(presentation)=i+1;
|
767
|
+
pos = i+1
|
768
|
+
# pos sets where next pattern matching should start
|
769
|
+
# if (presentation=~/\G(\d\d\d)/)
|
770
|
+
if (presentation.index(/\G(\d\d\d)/o, pos))
|
771
|
+
wire=wire+[$1.to_i].pack("C")
|
772
|
+
i=i+3
|
773
|
+
# elsif(presentation=~/\Gx([0..9a..fA..F][0..9a..fA..F])/)
|
774
|
+
elsif(presentation.index(/\Gx([0..9a..fA..F][0..9a..fA..F])/o, pos))
|
775
|
+
wire=wire+[$1].pack("H*")
|
776
|
+
i=i+3
|
777
|
+
# elsif(presentation=~/\G\./)
|
778
|
+
elsif(presentation.index(/\G\./o, pos))
|
779
|
+
wire=wire+"\."
|
780
|
+
i=i+1
|
781
|
+
# elsif(presentation=~/\G@/)
|
782
|
+
elsif(presentation.index(/\G@/o,pos))
|
783
|
+
wire=wire+"@"
|
784
|
+
i=i+1
|
785
|
+
# elsif(presentation=~/\G\(/)
|
786
|
+
elsif(presentation.index(/\G\(/o, pos))
|
787
|
+
wire=wire+"("
|
788
|
+
i=i+1
|
789
|
+
# elsif(presentation=~/\G\)/)
|
790
|
+
elsif(presentation.index(/\G\)/o, pos))
|
791
|
+
wire=wire+")"
|
792
|
+
i=i+1
|
793
|
+
# elsif(presentation=~/\G\\/)
|
794
|
+
elsif(presentation.index(/\G\\/o, pos))
|
795
|
+
wire=wire+"\\"
|
796
|
+
i+=1
|
797
|
+
end
|
798
|
+
else
|
799
|
+
wire = wire + [c].pack("C")
|
800
|
+
end
|
801
|
+
i=i+1
|
802
|
+
end
|
803
|
+
|
804
|
+
return wire
|
805
|
+
end
|
806
|
+
|
807
|
+
# require 'Net::DNS'
|
808
|
+
#
|
809
|
+
# prioritysorted=rrsort("SRV","priority",rr_array)
|
810
|
+
#
|
811
|
+
#
|
812
|
+
#rrsort() selects all RRs from the input array that are of the type
|
813
|
+
#that are defined in the first argument. Those RRs are sorted based on
|
814
|
+
#the attribute that is specified as second argument.
|
815
|
+
#
|
816
|
+
#There are a number of RRs for which the sorting function is
|
817
|
+
#specifically defined for certain attributes. If such sorting function
|
818
|
+
#is defined in the code (it can be set or overwritten using the
|
819
|
+
#set_rrsort_func() class method) that function is used.
|
820
|
+
#
|
821
|
+
#For instance:
|
822
|
+
# prioritysorted=rrsort("SRV","priority",rr_array)
|
823
|
+
#returns the SRV records sorted from lowest to heighest priority and
|
824
|
+
#for equal priorities from heighes to lowes weight.
|
825
|
+
#
|
826
|
+
#If the function does not exist then a numerical sort on the attribute
|
827
|
+
#value is performed.
|
828
|
+
# portsorted=rrsort("SRV","port",rr_array)
|
829
|
+
#
|
830
|
+
#If the attribute does not exist for a certain RR than the RRs are
|
831
|
+
#sorted on string comparrisson of the rdata.
|
832
|
+
#
|
833
|
+
#If the attribute is not defined than either the default_sort function
|
834
|
+
#will be defined or "Canonical sorting" (as defined by DNSSEC) will be
|
835
|
+
#used.
|
836
|
+
#
|
837
|
+
#rrsort() returns a sorted array with only elements of the specified
|
838
|
+
#RR type or undef.
|
839
|
+
#
|
840
|
+
#rrsort() returns undef when arguments are incorrect.
|
841
|
+
#--
|
842
|
+
def DNS.rrsort(*args)
|
843
|
+
rrtype = args[0]
|
844
|
+
attribute = args[1]
|
845
|
+
rr_array = args[2]
|
846
|
+
if (args.length < 2)
|
847
|
+
return nil
|
848
|
+
elsif (args.length == 2)
|
849
|
+
rr_array = attribute
|
850
|
+
attribute = nil
|
851
|
+
end
|
852
|
+
# invalid error type
|
853
|
+
return unless (Net::DNS::typesbyname(rrtype.upcase()))
|
854
|
+
if (rr_array == nil)
|
855
|
+
rr_array = Array.new
|
856
|
+
end
|
857
|
+
|
858
|
+
# attribute is empty or not specified.
|
859
|
+
if( attribute=~/^Net::DNS::RR::.*/)
|
860
|
+
# push the attribute back on the array.
|
861
|
+
rr_array.push(attribute)
|
862
|
+
attribute=nil
|
863
|
+
end
|
864
|
+
|
865
|
+
extracted_rr=[]
|
866
|
+
rr_array.each do |rr|
|
867
|
+
extracted_rr.push(rr) if ((rr.type.upcase) == rrtype.upcase)
|
868
|
+
end
|
869
|
+
return () unless extracted_rr.size() > 0
|
870
|
+
|
871
|
+
proc = ((Net::DNS::RR.const_get(rrtype)).new).get_rrsort_func(attribute)
|
872
|
+
sorted = extracted_rr.sort{ |a,b| proc.call(a,b)}
|
873
|
+
|
874
|
+
return sorted;
|
875
|
+
|
876
|
+
end
|
877
|
+
|
878
|
+
end
|
879
|
+
end
|