pNet-DNS 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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
@@ -0,0 +1,117 @@
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
+ module Net
17
+ module DNS
18
+ #= NAME
19
+ #
20
+ #Net::DNS::Question - DNS question class
21
+ #
22
+ #= SYNOPSIS
23
+ #
24
+ #use Net::DNS::Question
25
+ #
26
+ #= DESCRIPTION
27
+ #
28
+ #A Net::DNS::Question object represents a record in the
29
+ #question section of a DNS packet.
30
+ #
31
+ #
32
+ #= COPYRIGHT
33
+ #
34
+ #Copyright (c) 1997-2002 Michael Fuhr.
35
+ #
36
+ #Portions Copyright (c) 2002-2004 Chris Reinhardt.
37
+ #
38
+ #All rights reserved. This program is free software; you may redistribute
39
+ #it and/or modify it under the same terms as Perl itself.
40
+ #
41
+ #= SEE ALSO
42
+ #
43
+ #Net::DNS, Net::DNS::Resolver, Net::DNS::Packet,
44
+ #Net::DNS::Update, Net::DNS::Header, Net::DNS::RR,
45
+ #RFC 1035 Section 4.1.2
46
+ class Question < RR
47
+ attr_accessor :qname, :qtype, :qclass
48
+
49
+ #Creates a question object from the domain, type, and class passed
50
+ #as arguments.
51
+ #
52
+ # question = Net::DNS::Question.new("example.com", "MX", "IN")
53
+ def initialize(qname, qtypein="ANY", qclassin="ANY")
54
+ qname = "" if (qname==nil);
55
+
56
+ qtype = qtypein.upcase
57
+ qclass = qclassin.upcase
58
+
59
+ # Check if the caller has the type and class reversed.
60
+ # We are not that kind for unknown types.... :-)
61
+ if ((Net::DNS::typesbyname(qtype)==nil || \
62
+ Net::DNS::classesbyname(qclass)==nil) \
63
+ && Net::DNS::classesbyname(qtype)!=nil \
64
+ && Net::DNS::typesbyname(qclass)!=nil)
65
+
66
+ temp = qtype
67
+ qtype = qclass
68
+ qclass = temp
69
+ end
70
+
71
+ # $qname =~ s/^\.+//o;
72
+ # $qname =~ s/\.+$//o;
73
+ qname.gsub!("^\.+", "");
74
+ qname.gsub!("\.+$", "");
75
+
76
+ @qname = qname;
77
+ @qtype = qtype;
78
+ @qclass = qclass;
79
+ end
80
+
81
+ #Returns a string representation of the question record.
82
+ #
83
+ # print qr.inspect, "\n"
84
+ def inspect
85
+ return "#{@qname}.\t#{@qclass}\t#{@qtype}";
86
+ end
87
+
88
+ #Returns the question record in binary format suitable for inclusion
89
+ #in a DNS packet.
90
+ #
91
+ #Arguments are a Net::DNS::Packet object and the offset within
92
+ #that packet's data where the Net::DNS::Question record is to
93
+ #be stored. This information is necessary for using compressed
94
+ #domain names.
95
+ #
96
+ # qdata = question.data(packet, offset)
97
+ def data(packet, offset)
98
+ data, offset = packet.dn_comp(@qname, offset);
99
+
100
+ data+=[Net::DNS::typesbyname(@qtype.upcase)].pack("n")
101
+ data+=[Net::DNS::classesbyname(@qclass.upcase)].pack("n")
102
+
103
+ return data;
104
+ end
105
+
106
+ def zname
107
+ return qname
108
+ end
109
+ def ztype
110
+ return qtype
111
+ end
112
+ def zclass
113
+ return qclass
114
+ end
115
+ end
116
+ end
117
+ end
@@ -0,0 +1,630 @@
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
+ module Net
17
+ module DNS
18
+ #= NAME
19
+ #
20
+ #Net::DNS::RR - DNS Resource Record class
21
+ #
22
+ #= DESCRIPTION
23
+ #
24
+ #Net::DNS::RR is the base class for DNS Resource Record (RR) objects.
25
+ #See also the manual pages for each RR type.
26
+ #
27
+ #*WARNING!!!* Don't assume the RR objects you receive from a query
28
+ #are of a particular type -- always check an object's type before calling
29
+ #any of its methods. If you call an unknown method, you'll get a nasty
30
+ #warning message and Net::DNS::RR will return *nil* to the caller.
31
+ #
32
+ #= Sorting of RR arrays
33
+ #
34
+ #As of version 0.55 there is functionality to help you sort RR
35
+ #arrays. The sorting is done by Net::DNS::rrsort(), see the
36
+ #Net::DNS documentation. This package provides class methods to set
37
+ #the sorting functions used for a particular RR based on a particular
38
+ #attribute.
39
+ #
40
+ #= BUGS
41
+ #
42
+ #This version of Net::DNS::RR does little sanity checking on user-created
43
+ #RR objects.
44
+ #
45
+ #= COPYRIGHT
46
+ #
47
+ #Copyright (c) 1997-2002 Michael Fuhr.
48
+ #
49
+ #Portions Copyright (c) 2002-2004 Chris Reinhardt.
50
+ #
51
+ #Portions Copyright (c) 2005 Olaf Kolkman
52
+ #
53
+ #Ruby version Copyright (c) 2006 AlexD (Nominet UK)
54
+ #
55
+ #All rights reserved. This program is free software; you may redistribute
56
+ #it and/or modify it under the same terms as Perl itself.
57
+ #
58
+ #EDNS0 extensions by Olaf Kolkman.
59
+ #
60
+ #= SEE ALSO
61
+ #
62
+ #Net::DNS, Net::DNS::Resolver, Net::DNS::Packet,
63
+ #Net::DNS::Update, Net::DNS::Header, Net::DNS::Question,
64
+ #RFC 1035 Section 4.1.3
65
+ class RR
66
+ RRS = [
67
+ "A",
68
+ "AAAA",
69
+ "AFSDB",
70
+ "CNAME",
71
+ "CERT",
72
+ "DNAME",
73
+ "EID",
74
+ "HINFO",
75
+ "ISDN",
76
+ "LOC",
77
+ "MB",
78
+ "MG",
79
+ "MINFO",
80
+ "MR",
81
+ "MX",
82
+ "NAPTR",
83
+ "NIMLOC",
84
+ "NS",
85
+ "NSAP",
86
+ "NULL",
87
+ "PTR",
88
+ "PX",
89
+ "RP",
90
+ "RT",
91
+ "SOA",
92
+ "SRV",
93
+ "TKEY",
94
+ "TSIG",
95
+ "TXT",
96
+ "X25",
97
+ "OPT",
98
+ "SSHFP",
99
+ "SPF"]
100
+
101
+ #The record's domain name.
102
+ attr_accessor :name
103
+
104
+ #The record's type.
105
+ attr_accessor :type
106
+
107
+ #The record's class.
108
+ attr_accessor :rrclass
109
+
110
+ #Returns the record's time-to-live (TTL).
111
+ attr_accessor :ttl
112
+
113
+ #Returns the length of the record's data section.
114
+ attr_accessor :rdlength
115
+
116
+ #Returns the record's data section as binary data.
117
+ attr_writer :rdata
118
+
119
+
120
+ # @TODO Only load DNSSEC if available
121
+ #
122
+
123
+ @@rr_regex = nil
124
+ def RR.build_regex
125
+ if (@@rr_regex!=nil)
126
+ return @@rr_regex
127
+ end
128
+ # Types = join('|', sort { length $b <=> length $a } keys Net::DNS::TypesByName)
129
+ # Longest ones go first, so the regex engine will match AAAA before A.
130
+ types = (Net::DNS::Typesbyname.keys.sort { |a, b| b.length <=> a.length }).join('|')
131
+ types += '|TYPE\\d+';
132
+
133
+ # my $classes = join('|', keys %Net::DNS::classesbyname, 'CLASS\\d+');
134
+ classes = Net::DNS::Classesbyname.keys.join('|') + "|CLASS\\d+"
135
+
136
+ # # @rr_regex = Regexp.new("^\s*(\S+)\s*(\d+)?\s*(#{classes})?\s*(#{types})?\s*(.*)$")
137
+ # @rr_regex = Regexp.new("^\\s*(\\S+)\\s*(\\d+)?\\s*(#{classes})?\\s*(#{types})?\\s*(.*)\$");
138
+ @@rr_regex = Regexp.new("^\\s*(\\S+)\\s*(\\d+)?\\s*(#{classes})?\\s*(#{types})?\\s*([\\s\\S]*)\$");
139
+ return @@rr_regex
140
+ end
141
+
142
+ def init(*args)
143
+ if (args.length == 2)
144
+ # @rdata = args[0]
145
+ # @rdlength = @rdata.length
146
+ new_from_data(args[0], args[1])
147
+ elsif (args.length == 1)
148
+ if (args[0].class == String)
149
+ @rdatastr = args[0]
150
+ new_from_string(args[0])
151
+ elsif (args[0].class == Hash)
152
+ new_from_hash(args[0])
153
+ end
154
+ end
155
+ end
156
+
157
+ #String version
158
+ #
159
+ # a = Net::DNS::RR.create("foo.example.com. 86400 A 10.1.2.3")
160
+ # mx = Net::DNS::RR.create("example.com. 7200 MX 10 mailhost.example.com.")
161
+ # cname = Net::DNS::RR.create("www.example.com 300 IN CNAME www1.example.com")
162
+ # txt = Net::DNS::RR.create('baz.example.com 3600 HS TXT "text record"')
163
+ #
164
+ #Returns a Net::DNS::RR object of the appropriate type and
165
+ #initialized from the string passed by the user. The format of the
166
+ #string is that used in zone files, and is compatible with the string
167
+ #returned by Net::DNS::RR.inspect
168
+ #
169
+ #The name and RR type are required; all other information is optional.
170
+ #If omitted, the TTL defaults to 0 and the RR class defaults to IN.
171
+ #Omitting the optional fields is useful for creating the empty RDATA
172
+ #sections required for certain dynamic update operations. See the
173
+ #Net::DNS::Update manual page for additional examples.
174
+ #
175
+ #All names must be fully qualified. The trailing dot (.) is optional.
176
+ #
177
+ #
178
+ #
179
+ #Hash version
180
+ #
181
+ # rr = Net::DNS::RR.create({
182
+ # "name" => "foo.example.com",
183
+ # "ttl" => 86400,
184
+ # "rrclass" => "IN",
185
+ # "type" => "A",
186
+ # "address" => "10.1.2.3"
187
+ # })
188
+ #
189
+ # rr = Net::DNS::RR.create({
190
+ # "name" => "foo.example.com",
191
+ # "type" => "A"
192
+ # })
193
+ #
194
+ #Returns an RR object of the appropriate type, or a Net::DNS::RR
195
+ #object if the type isn't implemented. See the manual pages for
196
+ #each RR type to see what fields the type requires.
197
+ #
198
+ #The name and type fields are required; all others are optional.
199
+ #If omitted, ttl defaults to 0 and rrclass defaults to IN. Omitting
200
+ #the optional fields is useful for creating the empty RDATA sections
201
+ #required for certain dynamic update operations.
202
+ #
203
+ #The fields are case-insensitive, but starting each with uppercase
204
+ #is recommended.
205
+ def RR.create(*args)
206
+ if (args.length == 1) && (args[0].class == String)
207
+ return new_from_string(args[0])
208
+ elsif (args.length == 1) && (args[0].class == Hash)
209
+ return new_from_hash(args[0])
210
+ else
211
+ return new_from_data(args)
212
+ end
213
+ end
214
+
215
+ def RR.new_from_data(args)
216
+ name = args[0]
217
+ rrtype = args[1]
218
+ rrclass = args[2]
219
+ ttl = args[3]
220
+ rdlength = args[4]
221
+ data = args[5]
222
+ offset = args[6];
223
+ rdata = data[offset, rdlength]
224
+ if (RRS.include?(rrtype))
225
+ subclass = _get_subclass(name, rrtype, rrclass, ttl, rdlength);
226
+ else
227
+ subclass = _get_subclass(name, rrtype, rrclass, ttl, rdlength);
228
+ end
229
+ subclass.init(data, offset);
230
+ return subclass
231
+ end
232
+
233
+ def RR.new_from_hash(values)
234
+ raise ArgumentError, 'RR name not specified' if !(values.has_key?(:name))
235
+ raise ArgumentError, 'RR type not specified' if !(values.has_key?(:type))
236
+ name = values[:name]
237
+ rrtype = values[:type]
238
+ rrclass = 'IN'
239
+ if (values.has_key?:class)
240
+ rrclass = values[:class]
241
+ end
242
+ ttl = 0
243
+ if (values.has_key?:ttl)
244
+ ttl = values[:ttl]
245
+ end
246
+ rdata = ""
247
+ if (values.has_key?:data)
248
+ rdata = values[:data]
249
+ end
250
+ rdlength = rdata.length
251
+
252
+ subclass = _get_subclass(name, rrtype, rrclass, ttl, rdlength);
253
+
254
+ subclass.init(values)
255
+ return subclass
256
+ end
257
+
258
+ def RR.new_from_string(rrstring, update_type=nil)
259
+ build_regex()
260
+
261
+ # strip out comments
262
+ # Test for non escaped ";" by means of the look-behind assertion
263
+ # (the backslash is escaped)
264
+ rrstring.gsub!(/(\?<!\\);.*/o, "");
265
+
266
+ # if ((rrstring =~/#{@rr_regex}/xso) == nil)
267
+ if ((rrstring =~@@rr_regex) == nil)
268
+ raise Exception, "#{rrstring} did not match RR pat.\nPlease report this to the author!\n";
269
+ end
270
+
271
+ name = $1;
272
+ ttl = $2.to_i || 0;
273
+ rrclass = $3 || '';
274
+
275
+
276
+ rrtype = $4 || '';
277
+ rdata = $5 || '';
278
+
279
+ if rdata
280
+ rdata.gsub!(/\s+$/o, "")
281
+ end
282
+ if name
283
+ name.gsub!(/\.$/o, "");
284
+ end
285
+
286
+
287
+ # RFC3597 tweaks
288
+ # This converts to known class and type if specified as TYPE###
289
+ if rrtype =~/^TYPE\d+/o
290
+ rrtype = Net::DNS::typesbyval(Net::DNS::typesbyname(rrtype))
291
+ end
292
+ if rrclass =~/^CLASS\d+/o
293
+ rrclass = Net::DNS::classesbyval(Net::DNS::classesbyname(rrclass))
294
+ end
295
+
296
+
297
+ if (rrtype=='' && rrclass && rrclass == 'ANY')
298
+ rrtype = 'ANY';
299
+ rrclass = 'IN';
300
+ elsif (rrclass=='')
301
+ rrclass = 'IN';
302
+ end
303
+
304
+ if (rrtype == '')
305
+ rrtype = 'ANY';
306
+ end
307
+
308
+ if (update_type)
309
+ update_type.downcase!;
310
+
311
+ if (update_type == 'yxrrset')
312
+ ttl = 0;
313
+ rrclass = 'ANY' unless rdata!=nil && rdata.length > 0
314
+ elsif (update_type == 'nxrrset')
315
+ ttl = 0;
316
+ rrclass = 'NONE';
317
+ rdata = '';
318
+ elsif (update_type == 'yxdomain')
319
+ ttl = 0;
320
+ rrclass = 'ANY';
321
+ rrtype = 'ANY';
322
+ rdata = '';
323
+ elsif (update_type == 'nxdomain')
324
+ ttl = 0;
325
+ rrclass = 'NONE';
326
+ rrtype = 'ANY';
327
+ rdata = '';
328
+ elsif (update_type =~/^(rr_)?add$/o)
329
+ ttl = 86400 unless ttl!=nil
330
+ elsif (update_type =~/^(rr_)?del(ete)?$/o)
331
+ ttl = 0;
332
+ rrclass = (rdata != nil && rdata.length > 0) ? 'NONE' : 'ANY';
333
+ end
334
+ end
335
+
336
+
337
+ if (RRS.include?(rrtype) && rdata !~/^\s*\\#/o )
338
+ # subclass = _get_subclass(rrtype);
339
+ subclass = _get_subclass(name, rrtype, rrclass, ttl);
340
+
341
+ subclass.init(rdata);
342
+ return subclass
343
+ elsif (RRS.include?(rrtype)) # A RR type known to Net::DNS starting with \#
344
+ rdata =~ /\\\#\s+(\d+)\s+(.*)$/o;
345
+
346
+ rdlength = $1.to_i;
347
+ hexdump = $2;
348
+ hexdump.gsub!(/\s*/, "");
349
+
350
+ if hexdump.length() != rdlength*2
351
+ raise Exception, "#{rdata} is inconsistent; length does not match content"
352
+ end
353
+
354
+ rdata = [hexdump].pack('H*');
355
+
356
+ return new_from_data([name, rrtype, rrclass, ttl, rdlength, rdata, 0]) # rdata.length() - rdlength]);
357
+ elsif (rdata=~/\s*\\\#\s+\d+\s+/o)
358
+ #We are now dealing with the truly unknown.
359
+ raise Exception, 'Expected RFC3597 representation of RDATA' unless rdata =~/\\\#\s+(\d+)\s+(.*)$/o;
360
+
361
+ rdlength = $1.to_i;
362
+ hexdump = $2;
363
+ hexdump.gsub!(/\s*/o, "");
364
+
365
+ if hexdump.length() != rdlength*2
366
+ raise Exception, "#{rdata} is inconsistent; length does not match content" ;
367
+ end
368
+
369
+ rdata = [hexdump].pack('H*');
370
+
371
+ return new_from_data([name,rrtype,rrclass,ttl,rdlength,rdata,0]) # rdata.length() - rdlength);
372
+ else
373
+ #God knows how to handle these... bless them in the RR class.
374
+ subclass = _get_subclass(name, rrtype, rrclass, ttl);
375
+ return subclass
376
+ end
377
+ end
378
+
379
+ #Returns a string representation of the RR. Calls the
380
+ #rdatastr method to get the RR-specific data.
381
+ #
382
+ # print rr.inspect, "\n"
383
+ def inspect
384
+ return @name + ".\t" +@ttl.to_s + "\t" + @rrclass.to_s + "\t" + @type + "\t" + ((rdatastr()!=nil && rdatastr().length>0) ? rdatastr() : '; no data')
385
+ end
386
+
387
+ #Returns a string containing RR-specific data.
388
+ #
389
+ # s = rr.rdatastr
390
+ def rdatastr
391
+ # For subclasses to implement themselves
392
+ @rdlength!=nil ? "; rdlength = #{@rdlength}" : '';
393
+ end
394
+
395
+ def rdata(*args)
396
+ if (args.length == 2)
397
+ packet, offset = args;
398
+ ret = rr_rdata(packet, offset);
399
+ return ret
400
+ # rr_rdata
401
+ elsif (@rdata != nil)
402
+ return @rdata;
403
+ end
404
+ return nil;
405
+ end
406
+
407
+ def rr_rdata(*args)
408
+ return (@rdata!=nil ? @rdata : '');
409
+ end
410
+
411
+
412
+ #--
413
+ #------------------------------------------------------------------------------
414
+ # sub data
415
+ #
416
+ # This method is called by Net::DNS::Packet->data to get the binary
417
+ # representation of an RR.
418
+ #------------------------------------------------------------------------------
419
+ def data(packet, offset)
420
+ # Don't compress TSIG or TKEY names and don't mess with EDNS0 packets
421
+ if (@type.upcase == 'TSIG' || @type.upcase == 'TKEY')
422
+ tmp_packet = Net::DNS::Packet.new_from_binary()
423
+ data = tmp_packet.dn_comp(@name, 0)
424
+ elsif (@type.upcase == 'OPT')
425
+ tmp_packet = Net::DNS::Packet.new_from_binary()
426
+ data = tmp_packet.dn_comp('', 0)
427
+ else
428
+ data = packet.dn_comp(@name, offset)
429
+ end
430
+ qtype = @type.upcase;
431
+ ret = (qtype =~ /^\d+$/o)
432
+ qtype_val = (ret != nil) ? qtype : Net::DNS::typesbyname(qtype)
433
+ qtype_val = 0 if (qtype_val==nil)
434
+
435
+ qclass_val = 0
436
+ if (@rrclass != nil)
437
+ qclass = @rrclass.to_s.upcase
438
+ ret = qclass =~ /^\d+$/o
439
+ qclass_val = (ret != nil) ? qclass : Net::DNS::classesbyname(qclass)
440
+ qclass_val = 0 if (qclass_val==nil)
441
+ end
442
+ data += [qtype_val].pack('n')
443
+
444
+ # If the type is OPT then class will need to contain a decimal number
445
+ # containing the UDP payload size. (RFC2671 section 4.3)
446
+ if (@type != 'OPT')
447
+ data += [qclass_val].pack('n')
448
+ else
449
+ data += [@rrclass].pack('n')
450
+ end
451
+
452
+ data += [@ttl].pack('N')
453
+
454
+ offset += data.length + Net::DNS::INT16SZ # allow for rdlength
455
+
456
+ rd = rdata(packet, offset)
457
+
458
+ data += [rd.length].pack('n')
459
+ data+=rd
460
+
461
+ return data
462
+ end
463
+
464
+ #--
465
+ #------------------------------------------------------------------------------
466
+ # This method is called by SIG objects verify method.
467
+ # It is almost the same as data but needed to get an representation of the
468
+ # packets in wire format withoud domain name compression.
469
+ # It is essential to DNSSEC RFC 2535 section 8
470
+ #------------------------------------------------------------------------------
471
+ def _canonicaldata
472
+ data=''
473
+ dname=Net::DNS::name2labels(@name)
474
+ # for (my $i=0;$i<dname;$i++){
475
+ i = 0
476
+ dname.length.times do
477
+ data += [dname[i].length].pack('C')
478
+ data += dname[i].downcase
479
+ i += 1
480
+ end
481
+ data += [0].pack('C')
482
+ data += [Net::DNS::typesbyname(@type.upcase)].pack('n')
483
+ data += [Net::DNS::classesbyname(@rrclass.upcase)].pack('n')
484
+ data += [@ttl].pack('N')
485
+
486
+ rdata = _canonicalRdata
487
+
488
+ data += [rdata.length].pack('n')
489
+ data += rdata
490
+ return data
491
+ end
492
+
493
+ #--
494
+ # These are methods that are used in the DNSSEC context... Some RR
495
+ # have domain names in them. Verification works only on RRs with
496
+ # uncompressed domain names. (Canonical format as in sect 8 of
497
+ # RFC2535) _canonicalRdata is overwritten in those RR objects that
498
+ # have domain names in the RDATA and _name2wire is used to convert a
499
+ # domain name to "wire format"
500
+
501
+ def _canonicalRdata
502
+ packet=Net::DNS::Packet.new()
503
+ rdata = rr_rdata(packet,0)
504
+ return rdata
505
+ end
506
+
507
+ def _name2wire(name)
508
+ return RR._name2wire(name)
509
+ end
510
+
511
+ def RR._name2wire(name)
512
+ rdata="";
513
+ compname = "";
514
+ dname = Net::DNS::name2labels(name);
515
+
516
+ dname.each { |i|
517
+ rdata += [i.length].pack('C');
518
+ rdata += i ;
519
+ }
520
+ rdata += [0].pack('C');
521
+ return rdata;
522
+ end
523
+
524
+ def RR._get_subclass(name, type, rrclass, ttl, rdlength=0)
525
+ return unless (type!=nil)
526
+ if RRS.include?(type)
527
+ klass = Net::DNS::RR.const_get(type)
528
+ else
529
+ klass = Net::DNS::RR::UNKNOWN
530
+ end
531
+ ret = klass.new
532
+ ret.name=(name)
533
+ ret.type=(type)
534
+ ret.rrclass=(rrclass)
535
+ ret.rdlength=(rdlength)
536
+ ret.ttl=(ttl)
537
+ ret.create_rrsort_func
538
+ return ret
539
+ end
540
+
541
+ def create_rrsort_func
542
+ @rrsortfunc=Hash.new()
543
+ init_rrsort_func
544
+ end
545
+
546
+ def init_rrsort_func
547
+ # empty implementation for interested subclasses to fill out
548
+ end
549
+
550
+ #set_rrsort_func needs to be called as a class method. The first
551
+ #argument is the attribute name on which the sorting will need to take
552
+ #place. If you specify "default_sort" than that is the sort algorithm
553
+ #that will be used in the case that rrsort() is called without an RR
554
+ #attribute as argument. The second argument is a Proc to do the sort.
555
+ #
556
+ #The following example is the sorting function that actually is implemented in
557
+ #SRV.
558
+ #
559
+ # Net::DNS::RR::SRV.set_rrsort_func("priority", Proc.new { |a,b|
560
+ # a.priority <=> b.priority
561
+ # ||
562
+ # b.weight <=> a.weight})
563
+ #
564
+ # Net::DNS::RR::SRV.set_rrsort_func("default_sort", Proc.new { |a,b|
565
+ # a.priority <=> b.priority
566
+ # ||
567
+ # b.weight <=> a.weight})
568
+ def set_rrsort_func(attribute, func)
569
+ @rrsortfunc[attribute]=func;
570
+ end
571
+
572
+ def get_rrsort_func(attribute=nil)
573
+ if (@rrsortfunc != nil)
574
+ if (attribute!=nil && @rrsortfunc[attribute]!=nil)
575
+ # The default overwritten by the class variable in Net::DNS
576
+ return @rrsortfunc[attribute];
577
+ elsif((attribute==nil) && (@rrsortfunc[:default_sort]!=nil))
578
+ # The default overwritten by the class variable in Net::DNS
579
+ return @rrsortfunc[:default_sort];
580
+ end
581
+ end
582
+ if( attribute!=nil && attribute != "")
583
+ ret = Proc.new { |a,b| (a.respond_to?(attribute) ? (a.send(attribute) <=> b.send(attribute)) : (a._canonicaldata() <=> b._canonicaldata())) }
584
+ return ret
585
+ else
586
+ ret = Proc.new { |a,b| a._canonicaldata() <=> b._canonicaldata() }
587
+ return ret
588
+ end
589
+
590
+ return sortsub;
591
+ end
592
+
593
+
594
+ end
595
+ end
596
+ end
597
+
598
+ require 'Net/DNS/RR/A'
599
+ require 'Net/DNS/RR/AAAA'
600
+ require 'Net/DNS/RR/MX'
601
+ require 'Net/DNS/RR/TXT'
602
+ require 'Net/DNS/RR/SRV'
603
+ require 'Net/DNS/RR/NS'
604
+ require 'Net/DNS/RR/SOA'
605
+ require 'Net/DNS/RR/OPT'
606
+ require 'Net/DNS/RR/AFSDB'
607
+ require 'Net/DNS/RR/CNAME'
608
+ require 'Net/DNS/RR/DNAME'
609
+ require 'Net/DNS/RR/HINFO'
610
+ require 'Net/DNS/RR/ISDN'
611
+ require 'Net/DNS/RR/MB'
612
+ require 'Net/DNS/RR/MG'
613
+ require 'Net/DNS/RR/MINFO'
614
+ require 'Net/DNS/RR/MR'
615
+ require 'Net/DNS/RR/NAPTR'
616
+ require 'Net/DNS/RR/PTR'
617
+ require 'Net/DNS/RR/NSAP'
618
+ require 'Net/DNS/RR/PX'
619
+ require 'Net/DNS/RR/RP'
620
+ require 'Net/DNS/RR/RT'
621
+ require 'Net/DNS/RR/X25'
622
+ require 'Net/DNS/RR/LOC'
623
+ require 'Net/DNS/RR/CERT'
624
+ require 'Net/DNS/RR/SPF'
625
+ require 'Net/DNS/RR/TKEY'
626
+ require 'Net/DNS/RR/TSIG'
627
+ require 'Net/DNS/RR/EID'
628
+ require 'Net/DNS/RR/NIMLOC'
629
+ require 'Net/DNS/RR/NULL'
630
+ require 'Net/DNS/RR/UNKNOWN'