pNet-DNS 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (71) hide show
  1. data/README +68 -0
  2. data/lib/Net/DNS.rb +879 -0
  3. data/lib/Net/DNS/Header.rb +303 -0
  4. data/lib/Net/DNS/Nameserver.rb +601 -0
  5. data/lib/Net/DNS/Packet.rb +851 -0
  6. data/lib/Net/DNS/Question.rb +117 -0
  7. data/lib/Net/DNS/RR.rb +630 -0
  8. data/lib/Net/DNS/RR/A.rb +103 -0
  9. data/lib/Net/DNS/RR/AAAA.rb +147 -0
  10. data/lib/Net/DNS/RR/AFSDB.rb +114 -0
  11. data/lib/Net/DNS/RR/CERT.rb +191 -0
  12. data/lib/Net/DNS/RR/CNAME.rb +89 -0
  13. data/lib/Net/DNS/RR/DNAME.rb +84 -0
  14. data/lib/Net/DNS/RR/EID.rb +70 -0
  15. data/lib/Net/DNS/RR/HINFO.rb +108 -0
  16. data/lib/Net/DNS/RR/ISDN.rb +118 -0
  17. data/lib/Net/DNS/RR/LOC.rb +341 -0
  18. data/lib/Net/DNS/RR/MB.rb +92 -0
  19. data/lib/Net/DNS/RR/MG.rb +96 -0
  20. data/lib/Net/DNS/RR/MINFO.rb +109 -0
  21. data/lib/Net/DNS/RR/MR.rb +92 -0
  22. data/lib/Net/DNS/RR/MX.rb +124 -0
  23. data/lib/Net/DNS/RR/NAPTR.rb +182 -0
  24. data/lib/Net/DNS/RR/NIMLOC.rb +70 -0
  25. data/lib/Net/DNS/RR/NS.rb +100 -0
  26. data/lib/Net/DNS/RR/NSAP.rb +273 -0
  27. data/lib/Net/DNS/RR/NULL.rb +68 -0
  28. data/lib/Net/DNS/RR/OPT.rb +251 -0
  29. data/lib/Net/DNS/RR/PTR.rb +93 -0
  30. data/lib/Net/DNS/RR/PX.rb +131 -0
  31. data/lib/Net/DNS/RR/RP.rb +108 -0
  32. data/lib/Net/DNS/RR/RT.rb +115 -0
  33. data/lib/Net/DNS/RR/SOA.rb +195 -0
  34. data/lib/Net/DNS/RR/SPF.rb +46 -0
  35. data/lib/Net/DNS/RR/SRV.rb +153 -0
  36. data/lib/Net/DNS/RR/SSHFP.rb +190 -0
  37. data/lib/Net/DNS/RR/TKEY.rb +219 -0
  38. data/lib/Net/DNS/RR/TSIG.rb +358 -0
  39. data/lib/Net/DNS/RR/TXT.rb +162 -0
  40. data/lib/Net/DNS/RR/UNKNOWN.rb +76 -0
  41. data/lib/Net/DNS/RR/X25.rb +90 -0
  42. data/lib/Net/DNS/Resolver.rb +2090 -0
  43. data/lib/Net/DNS/Resolver/Recurse.rb +478 -0
  44. data/lib/Net/DNS/Update.rb +189 -0
  45. data/test/custom.txt +4 -0
  46. data/test/resolv.conf +4 -0
  47. data/test/tc_escapedchars.rb +498 -0
  48. data/test/tc_header.rb +91 -0
  49. data/test/tc_inet6.rb +169 -0
  50. data/test/tc_misc.rb +137 -0
  51. data/test/tc_online.rb +236 -0
  52. data/test/tc_packet.rb +174 -0
  53. data/test/tc_packet_unique_push.rb +126 -0
  54. data/test/tc_question.rb +49 -0
  55. data/test/tc_recurse.rb +69 -0
  56. data/test/tc_res_env.rb +59 -0
  57. data/test/tc_res_file.rb +55 -0
  58. data/test/tc_res_opt.rb +135 -0
  59. data/test/tc_resolver.rb +102 -0
  60. data/test/tc_rr-opt.rb +40 -0
  61. data/test/tc_rr-rrsort.rb +116 -0
  62. data/test/tc_rr-txt.rb +138 -0
  63. data/test/tc_rr-unknown.rb +95 -0
  64. data/test/tc_rr.rb +246 -0
  65. data/test/tc_tcp.rb +34 -0
  66. data/test/tc_tkey.rb +115 -0
  67. data/test/tc_update.rb +226 -0
  68. data/test/ts_netdns.rb +17 -0
  69. data/test/ts_offline.rb +32 -0
  70. data/test/ts_online.rb +33 -0
  71. 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
@@ -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