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
@@ -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'