net-dns 0.6.1 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. data/.gitignore +8 -6
  2. data/.travis.yml +14 -0
  3. data/CHANGELOG.md +79 -0
  4. data/Gemfile +4 -0
  5. data/Rakefile +56 -66
  6. data/demo/check_soa.rb +1 -1
  7. data/demo/threads.rb +1 -1
  8. data/lib/net/dns.rb +24 -22
  9. data/lib/net/dns/header.rb +77 -103
  10. data/lib/net/dns/{names/names.rb → names.rb} +19 -20
  11. data/lib/net/dns/packet.rb +231 -256
  12. data/lib/net/dns/question.rb +11 -40
  13. data/lib/net/dns/resolver.rb +248 -250
  14. data/lib/net/dns/resolver/socks.rb +6 -6
  15. data/lib/net/dns/resolver/timeouts.rb +1 -1
  16. data/lib/net/dns/rr.rb +112 -117
  17. data/lib/net/dns/rr/a.rb +98 -89
  18. data/lib/net/dns/rr/aaaa.rb +84 -68
  19. data/lib/net/dns/rr/classes.rb +91 -106
  20. data/lib/net/dns/rr/cname.rb +64 -45
  21. data/lib/net/dns/rr/hinfo.rb +90 -50
  22. data/lib/net/dns/rr/mr.rb +61 -44
  23. data/lib/net/dns/rr/mx.rb +73 -48
  24. data/lib/net/dns/rr/ns.rb +60 -46
  25. data/lib/net/dns/rr/null.rb +11 -12
  26. data/lib/net/dns/rr/ptr.rb +47 -34
  27. data/lib/net/dns/rr/soa.rb +5 -6
  28. data/lib/net/dns/rr/srv.rb +1 -4
  29. data/lib/net/dns/rr/txt.rb +14 -14
  30. data/lib/net/dns/rr/types.rb +13 -13
  31. data/lib/net/dns/version.rb +8 -14
  32. data/net-dns.gemspec +35 -0
  33. data/setup.rb +3 -2
  34. data/test/header_test.rb +18 -18
  35. data/test/names_test.rb +21 -0
  36. data/test/packet_test.rb +38 -31
  37. data/test/question_test.rb +23 -24
  38. data/test/resolver/timeouts_test.rb +13 -13
  39. data/test/resolver_test.rb +28 -20
  40. data/test/rr/a_test.rb +70 -23
  41. data/test/rr/aaaa_test.rb +109 -0
  42. data/test/rr/classes_test.rb +61 -49
  43. data/test/rr/cname_test.rb +97 -0
  44. data/test/rr/hinfo_test.rb +117 -0
  45. data/test/rr/mr_test.rb +105 -0
  46. data/test/rr/mx_test.rb +112 -0
  47. data/test/rr/ns_test.rb +34 -12
  48. data/test/rr/types_test.rb +4 -4
  49. data/test/rr_test.rb +1 -1
  50. metadata +77 -52
  51. data/AUTHORS.rdoc +0 -7
  52. data/CHANGELOG.rdoc +0 -46
  53. data/VERSION.yml +0 -5
@@ -62,12 +62,12 @@ class RawSocket # :nodoc:
62
62
 
63
63
  def check_addr addr
64
64
  case addr
65
- when String
66
- IPAddr.new addr
67
- when IPAddr
68
- addr
69
- else
70
- raise ArgumentError, "Wrong address format: #{addr}"
65
+ when String
66
+ IPAddr.new(addr)
67
+ when IPAddr
68
+ addr
69
+ else
70
+ raise ArgumentError, "Wrong address format: #{addr}"
71
71
  end
72
72
  end
73
73
 
@@ -13,7 +13,7 @@ module Net # :nodoc:
13
13
  if seconds.is_a? Numeric and seconds >= 0
14
14
  @seconds = seconds
15
15
  else
16
- raise ::ArgumentError, "Invalid value for tcp timeout"
16
+ raise ArgumentError, "Invalid value for tcp timeout"
17
17
  end
18
18
  end
19
19
 
@@ -1,37 +1,37 @@
1
- require 'net/dns/names/names'
1
+ require 'ipaddr'
2
+ require 'net/dns/names'
2
3
  require 'net/dns/rr/types'
3
4
  require 'net/dns/rr/classes'
4
5
 
5
-
6
- %w[a ns mx cname txt soa ptr aaaa mr].each do |file|
6
+ %w(a aaaa cname hinfo mr mx ns ptr soa srv txt).each do |file|
7
7
  require "net/dns/rr/#{file}"
8
8
  end
9
9
 
10
- module Net # :nodoc:
11
- module DNS
12
-
10
+ module Net
11
+ module DNS
12
+
13
13
  #
14
14
  # = Net::DNS::RR - DNS Resource Record class
15
15
  #
16
- # The Net::DNS::RR is the base class for DNS Resource
16
+ # The Net::DNS::RR is the base class for DNS Resource
17
17
  # Record (RR) objects. A RR is a pack of data that represents
18
- # resources for a DNS zone. The form in which this data is
18
+ # resources for a DNS zone. The form in which this data is
19
19
  # shows can be drawed as follow:
20
20
  #
21
21
  # "name ttl class type data"
22
- #
22
+ #
23
23
  # The +name+ is the name of the resource, like an canonical
24
24
  # name for an +A+ record (internet ip address). The +ttl+ is the
25
- # time to live, expressed in seconds. +type+ and +class+ are
25
+ # time to live, expressed in seconds. +type+ and +class+ are
26
26
  # respectively the type of resource (+A+ for ip addresses, +NS+
27
- # for nameservers, and so on) and the class, which is almost
27
+ # for nameservers, and so on) and the class, which is almost
28
28
  # always +IN+, the Internet class. At the end, +data+ is the
29
- # value associated to the name for that particular type of
29
+ # value associated to the name for that particular type of
30
30
  # resource record. An example:
31
31
  #
32
32
  # # A record for IP address
33
33
  # "www.example.com 86400 IN A 172.16.100.1"
34
- #
34
+ #
35
35
  # # NS record for name server
36
36
  # "www.example.com 86400 IN NS ns.example.com"
37
37
  #
@@ -39,34 +39,22 @@ module Net # :nodoc:
39
39
  # such the ones above, or specifying each field as the pair
40
40
  # of an hash. See the Net::DNS::RR.new method for details.
41
41
  #
42
- # == Error classes
43
- #
44
- # Some error classes has been defined for the Net::DNS::RR class,
45
- # which are listed here to keep a light and browsable main documentation.
46
- # We have:
47
- #
48
- # ArgumentError:: Generic argument error for class Net::DNS::RR
49
- # DataError:: Error in parsing binary data, maybe from a malformed packet.
50
- #
51
42
  class RR
52
- include Net::DNS::Names
53
-
54
- # Argument Error for class Net::DNS::RR.
55
- class ArgumentError < ArgumentError
56
- end
57
-
43
+ include Names
44
+
45
+
58
46
  # Base error class.
59
47
  class Error < StandardError
60
48
  end
61
-
49
+
62
50
  # Error in parsing binary data, maybe from a malformed packet.
63
51
  class DataError < Error
64
52
  end
65
-
66
-
53
+
54
+
67
55
  # Regexp matching an RR string
68
56
  RR_REGEXP = Regexp.new("^\\s*(\\S+)\\s*(\\d+)?\\s+(" +
69
- Net::DNS::RR::Classes.regexp +
57
+ Net::DNS::RR::Classes.regexp +
70
58
  "|CLASS\\d+)?\\s*(" +
71
59
  Net::DNS::RR::Types.regexp +
72
60
  "|TYPE\\d+)?\\s*(.*)$", Regexp::IGNORECASE)
@@ -75,17 +63,10 @@ module Net # :nodoc:
75
63
  # RR portion of the packet, in bytes
76
64
  RRFIXEDSZ = 10
77
65
 
78
- # Name of the RR
79
- attr_reader :name
80
- # TTL time (in seconds) of the RR
81
- attr_reader :ttl
82
- # Data belonging to that appropriate class,
83
- # not to be used (use real accessors instead)
84
- attr_reader :rdata
85
-
66
+
86
67
  # Create a new instance of Net::DNS::RR class, or an instance of
87
68
  # any of the subclass of the appropriate type.
88
- #
69
+ #
89
70
  # Argument can be a string or an hash. With a sting, we can pass
90
71
  # a RR resource record in the canonical format:
91
72
  #
@@ -95,12 +76,12 @@ module Net # :nodoc:
95
76
  # txt = Net::DNS::RR.new('baz.example.com 3600 HS TXT "text record"')
96
77
  #
97
78
  # Incidentally, +a+, +mx+, +cname+ and +txt+ objects will be instances of
98
- # respectively Net::DNS::RR::A, Net::DNS::RR::MX, Net::DNS::RR::CNAME and
79
+ # respectively Net::DNS::RR::A, Net::DNS::RR::MX, Net::DNS::RR::CNAME and
99
80
  # Net::DNS::RR::TXT classes.
100
81
  #
101
- # The name and RR data are required; all other informations are optional.
82
+ # The name and RR data are required; all other informations are optional.
102
83
  # If omitted, the +TTL+ defaults to 10800, +type+ default to +A+ and the RR class
103
- # defaults to +IN+. Omitting the optional fields is useful for creating the
84
+ # defaults to +IN+. Omitting the optional fields is useful for creating the
104
85
  # empty RDATA sections required for certain dynamic update operations.
105
86
  # All names must be fully qualified. The trailing dot (.) is optional.
106
87
  #
@@ -119,12 +100,12 @@ module Net # :nodoc:
119
100
  # :rdata => "10.1.2.3"
120
101
  # )
121
102
  #
122
- # Name and data are required; all the others fields are optionals like
123
- # we've seen before. The data field can be specified either with the
103
+ # Name and data are required; all the others fields are optionals like
104
+ # we've seen before. The data field can be specified either with the
124
105
  # right name of the resource (+:address+ in the example above) or with
125
106
  # the generic key +:rdata+. Consult documentation to find the exact name
126
107
  # for the resource in each subclass.
127
- #
108
+ #
128
109
  def initialize(arg)
129
110
  instance = case arg
130
111
  when String
@@ -151,107 +132,122 @@ module Net # :nodoc:
151
132
  #
152
133
  # This method is used when parsing a binary packet by the Packet
153
134
  # class.
154
- #
135
+ #
155
136
  def RR.parse(data)
156
137
  o = allocate
157
- obj,offset = o.send(:new_from_binary, data, 0)
158
- return obj
138
+ obj, offset = o.send(:new_from_binary, data, 0)
139
+ obj
159
140
  end
160
-
161
- # Same as RR.parse, but takes an entire packet binary data to
141
+
142
+ # Same as RR.parse, but takes an entire packet binary data to
162
143
  # perform name expansion. Default when analizing a packet
163
144
  # just received from a network stream.
164
145
  #
165
- # Return an instance of appropriate class and the offset
146
+ # Return an instance of appropriate class and the offset
166
147
  # pointing at the end of the data parsed.
167
148
  #
168
- def RR.parse_packet(data,offset)
149
+ def RR.parse_packet(data, offset)
169
150
  o = allocate
170
- o.send(:new_from_binary,data,offset)
151
+ o.send(:new_from_binary, data, offset)
152
+ end
153
+
154
+ def name
155
+ @name
156
+ end
157
+
158
+ def ttl
159
+ @ttl
160
+ end
161
+
162
+ # Type accessor
163
+ def type
164
+ @type.to_s
165
+ end
166
+
167
+ # Class accessor
168
+ def cls
169
+ @cls.to_s
170
+ end
171
+
172
+
173
+ def value
174
+ get_inspect
171
175
  end
172
176
 
173
- # Return the RR object in binary data format, suitable
174
- # for using in network streams, with names compressed.
177
+ # Data belonging to that appropriate class,
178
+ # not to be used (use real accessors instead)
179
+ def rdata
180
+ @rdata
181
+ end
182
+
183
+ # Return the RR object in binary data format, suitable
184
+ # for using in network streams.
185
+ #
186
+ # raw_data = rr.data
187
+ # puts "RR is #{raw_data.size} bytes long"
188
+ #
189
+ def data
190
+ str = pack_name(@name)
191
+ str + [@type.to_i, @cls.to_i, ttl, @rdlength].pack("n2 N n") + get_data
192
+ end
193
+
194
+ # Return the RR object in binary data format, suitable
195
+ # for using in network streams, with names compressed.
175
196
  # Must pass as arguments the offset inside the packet
176
197
  # and an hash of compressed names.
177
198
  #
178
- # This method is to be used in other classes and is
199
+ # This method is to be used in other classes and is
179
200
  # not intended for user space programs.
180
201
  #
181
202
  # TO FIX in one of the future releases
182
203
  #
183
204
  def comp_data(offset,compnames)
184
- type,cls = @type.to_i, @cls.to_i
185
- str,offset,names = dn_comp(@name,offset,compnames)
186
- str += [type,cls,@ttl,@rdlength].pack("n2 N n")
205
+ str, offset, names = dn_comp(@name, offset, compnames)
206
+ str += [@type.to_i, @cls.to_i, ttl, @rdlength].pack("n2 N n")
187
207
  offset += Net::DNS::RRFIXEDSZ
188
- return str,offset,names
189
- end
190
-
191
- # Return the RR object in binary data format, suitable
192
- # for using in network streams.
193
- #
194
- # raw_data = rr.data
195
- # puts "RR is #{raw_data.size} bytes long"
196
- #
197
- def data
198
- type,cls = @type.to_i, @cls.to_i
199
- str = pack_name(@name)
200
- return str + [type,cls,@ttl,@rdlength].pack("n2 N n") + get_data
208
+ [str, offset, names]
201
209
  end
202
-
203
- # Canonical inspect method.
210
+
211
+
212
+ # Returns a human readable representation of this record.
213
+ # The value is always a String.
204
214
  #
205
215
  # mx = Net::DNS::RR.new("example.com. 7200 MX 10 mailhost.example.com.")
206
216
  # #=> example.com. 7200 IN MX 10 mailhost.example.com.
207
217
  #
208
218
  def inspect
209
- data = get_inspect
210
- # Returns the preformatted string
211
- if @name.size < 24
212
- [@name, @ttl.to_s, @cls.to_s, @type.to_s, data].pack("A24 A8 A8 A8 A*")
213
- else
214
- to_a.join(" ")
215
- end
219
+ to_s
216
220
  end
217
221
 
218
- # Returns the RR in a string format.
222
+ # Returns a String representation of this record.
219
223
  #
220
224
  # mx = Net::DNS::RR.new("example.com. 7200 MX 10 mailhost.example.com.")
221
225
  # mx.to_s
222
226
  # #=> "example.com. 7200 IN MX 10 mailhost.example.com."
223
227
  #
224
228
  def to_s
225
- inspect.to_s
229
+ items = to_a.map { |e| e.to_s }
230
+ if @name.size < 24
231
+ items.pack("A24 A8 A8 A8 A*")
232
+ else
233
+ items.join(" ")
234
+ end.to_s
226
235
  end
227
236
 
228
- # Returns an array with all the fields for the RR record.
237
+ # Returns an Array with all the attributes for this record.
229
238
  #
230
239
  # mx = Net::DNS::RR.new("example.com. 7200 MX 10 mailhost.example.com.")
231
240
  # mx.to_a
232
- # #=> ["example.com.",7200,"IN","MX","10 mailhost.example.com."]
241
+ # #=> ["example.com.", 7200, "IN", "MX", "10 mailhost.example.com."]
233
242
  #
234
243
  def to_a
235
- [@name, @ttl, @cls.to_s, @type.to_s, get_inspect]
236
- end
237
-
238
- # Type accessor
239
- def type
240
- @type.to_s
244
+ [name, ttl, cls.to_s, type.to_s, value]
241
245
  end
242
-
243
- # Class accessor
244
- def cls
245
- @cls.to_s
246
- end
247
-
246
+
247
+
248
248
  private
249
249
 
250
- #---
251
- # New RR with argument in string form
252
- #---
253
250
  def new_from_string(rrstring)
254
-
255
251
  unless rrstring =~ RR_REGEXP
256
252
  raise ArgumentError,
257
253
  "Format error for RR string (maybe CLASS and TYPE not valid?)"
@@ -277,7 +273,7 @@ module Net # :nodoc:
277
273
  @rdata = $5 ? $5.strip : ""
278
274
 
279
275
  if self.class == Net::DNS::RR
280
- (eval "Net::DNS::RR::#@type").new(rrstring)
276
+ Net::DNS::RR.const_get(@type.to_s).new(rrstring)
281
277
  else
282
278
  subclass_new_from_string(@rdata)
283
279
  self.class
@@ -287,7 +283,7 @@ module Net # :nodoc:
287
283
  def new_from_hash(args)
288
284
  # Name field is mandatory
289
285
  unless args.has_key? :name
290
- raise ArgumentError, "RR argument error: need at least RR name"
286
+ raise ArgumentError, ":name field is mandatory"
291
287
  end
292
288
 
293
289
  @name = args[:name].downcase
@@ -299,9 +295,9 @@ module Net # :nodoc:
299
295
  @rdlength = args[:rdlength] || @rdata.size
300
296
 
301
297
  if self.class == Net::DNS::RR
302
- (eval "Net::DNS::RR::#@type").new(args)
298
+ Net::DNS::RR.const_get(@type.to_s).new(args)
303
299
  else
304
- hash = args - [:name,:ttl,:type,:cls]
300
+ hash = args - [:name, :ttl, :type, :cls]
305
301
  if hash.has_key? :rdata
306
302
  subclass_new_from_string(hash[:rdata])
307
303
  else
@@ -309,7 +305,7 @@ module Net # :nodoc:
309
305
  end
310
306
  self.class
311
307
  end
312
- end # new_from_hash
308
+ end
313
309
 
314
310
  def new_from_binary(data,offset)
315
311
  if self.class == Net::DNS::RR
@@ -325,7 +321,7 @@ module Net # :nodoc:
325
321
  offset = subclass_new_from_binary(data,offset)
326
322
  build_pack
327
323
  set_type
328
- return [self,offset]
324
+ [self, offset]
329
325
  end
330
326
  end
331
327
 
@@ -336,7 +332,7 @@ module Net # :nodoc:
336
332
  end
337
333
  def subclass_new_from_hash(hash)
338
334
  end
339
- def subclass_new_from_binary(data,offset)
335
+ def subclass_new_from_binary(data, offset)
340
336
  end
341
337
  def build_pack
342
338
  end
@@ -354,18 +350,17 @@ module Net # :nodoc:
354
350
  end
355
351
 
356
352
 
357
- # NEW new method :)
358
353
  def self.new(*args)
359
- o = allocate
354
+ o = allocate
360
355
  obj = o.send(:initialize,*args)
361
356
  if self == Net::DNS::RR
362
- return obj
357
+ obj
363
358
  else
364
- return o
359
+ o
365
360
  end
366
361
  end
367
-
362
+
368
363
  end
369
-
364
+
370
365
  end
371
- end
366
+ end
@@ -1,115 +1,124 @@
1
- require 'ipaddr'
1
+ module Net
2
+ module DNS
3
+ class RR
2
4
 
3
-
4
- module Net # :nodoc:
5
- module DNS
6
-
7
- class RR
8
-
9
- # =Name
10
- #
11
- # Net::DNS::RR::A DNS A resource record
12
5
  #
13
- # =Synopsis
6
+ # = IPv4 Address Record (A)
14
7
  #
15
- # require "net/dns/rr"
8
+ # Class for DNS IPv4 Address (A) resource records.
16
9
  #
17
- # =Description
10
+ # The resource data is an IPv4 (i.e. 32 bit long) address,
11
+ # hold in the instance variable +address+.
18
12
  #
19
- # Net::DNS::RR::A is the class to handle resource records of type A, the
20
- # most common in a DNS query. Its resource data is an IPv4 (i.e. 32 bit
21
- # long) address, hold in the instance variable +address+.
22
- # a = Net::DNS::RR::A.new("localhost.movie.edu. 360 IN A 127.0.0.1")
13
+ # a = Net::DNS::RR::A.new("localhost.movie.edu. 360 IN A 127.0.0.1")
23
14
  #
24
- # a = Net::DNS::RR::A.new(:name => "localhost.movie.edu.",
25
- # :ttl => 360,
26
- # :cls => Net::DNS::IN,
27
- # :type => Net::DNS::A,
28
- # :address => "127.0.0.1")
15
+ # a = Net::DNS::RR::A.new(:name => "localhost.movie.edu.",
16
+ # :ttl => 360,
17
+ # :cls => Net::DNS::IN,
18
+ # :type => Net::DNS::A,
19
+ # :address => "127.0.0.1" )
29
20
  #
30
- # When computing binary data to trasmit the RR, the RDATA section is an
21
+ # When computing binary data to transmit the RR, the RDATA section is an
31
22
  # Internet address expressed as four decimal numbers separated by dots
32
- # without any imbedded spaces (e.g.,"10.2.0.52" or "192.0.5.6").
23
+ # without any embedded space (e.g. "10.2.0.52" or "192.0.5.6").
33
24
  #
34
25
  class A < RR
35
-
36
- attr_reader :address
37
-
38
- # Assign to the RR::A object a new IPv4 address, which can be in the
39
- # form of a string or an IPAddr object
26
+
27
+ # Gets the current IPv4 address for this record.
28
+ #
29
+ # Returns an instance of IPAddr.
30
+ def address
31
+ @address
32
+ end
33
+
34
+ # Assigns a new IPv4 address to this record, which can be in the
35
+ # form of a <tt>String</tt> or an <tt>IPAddr</tt> object.
36
+ #
37
+ # Examples
40
38
  #
41
39
  # a.address = "192.168.0.1"
42
40
  # a.address = IPAddr.new("10.0.0.1")
43
41
  #
44
- def address=(addr)
45
- @address = check_address addr
42
+ # Returns the new allocated instance of IPAddr.
43
+ def address=(string_or_ipaddr)
44
+ @address = check_address(string_or_ipaddr)
46
45
  build_pack
46
+ @address
47
+ end
48
+
49
+ # Gets the standardized value for this record,
50
+ # represented by the value of <tt>address</tt>.
51
+ #
52
+ # Returns a String.
53
+ def value
54
+ address.to_s
47
55
  end
48
-
56
+
57
+
49
58
  private
50
-
51
- def check_address(addr)
52
- address = ""
53
- case addr
54
- when String
55
- address = IPAddr.new addr
56
- when Integer # Address in numeric form
57
- tempAddr = [(addr>>24),(addr>>16)&0xFF,(addr>>8)&0xFF,addr&0xFF]
58
- tempAddr = tempAddr.collect {|x| x.to_s}.join(".")
59
- address = IPAddr.new tempAddr
60
- when IPAddr
61
- address = addr
62
- else
63
- raise ArgumentError, "Unknown address type `#{addr}'"
59
+
60
+ def subclass_new_from_hash(options)
61
+ if options.has_key?(:address)
62
+ @address = check_address(options[:address])
63
+ elsif options.has_key?(:rdata)
64
+ @address = check_address(options[:rdata])
65
+ else
66
+ raise ArgumentError, ":address or :rdata field is mandatory"
67
+ end
64
68
  end
65
- raise ArgumentError, "Must specify an IPv4 address" unless address.ipv4?
66
- address
67
- rescue ::ArgumentError
68
- raise ArgumentError, "Invalid address `#{addr}'"
69
- end
70
-
71
- def build_pack
72
- @address_pack = @address.hton
73
- @rdlength = @address_pack.size
74
- end
75
-
76
- def get_data
77
- @address_pack
78
- end
79
69
 
80
- def get_inspect
81
- "#@address"
82
- end
83
-
84
- def subclass_new_from_hash(args)
85
- if args.has_key? :address
86
- @address = check_address args[:address]
87
- elsif args.has_key? :rdata
88
- @address = check_address args[:rdata]
89
- else
90
- # Address field is mandatory
91
- raise ArgumentError, ":address field is mandatory but missing"
70
+ def subclass_new_from_string(str)
71
+ @address = check_address(str)
92
72
  end
93
- end
94
-
95
- def subclass_new_from_string(str)
96
- @address = check_address(str)
97
- end
98
-
99
- def subclass_new_from_binary(data,offset)
100
- a,b,c,d = data.unpack("@#{offset} CCCC")
101
- @address = IPAddr.new "#{a}.#{b}.#{c}.#{d}"
102
- return offset + 4
103
- end
104
-
105
- private
106
-
73
+
74
+ def subclass_new_from_binary(data, offset)
75
+ a, b, c, d = data.unpack("@#{offset} CCCC")
76
+ @address = IPAddr.new("#{a}.#{b}.#{c}.#{d}")
77
+ offset + 4
78
+ end
79
+
80
+
107
81
  def set_type
108
82
  @type = Net::DNS::RR::Types.new("A")
109
83
  end
110
-
84
+
85
+ def get_inspect
86
+ value
87
+ end
88
+
89
+
90
+ def check_address(input)
91
+ address = case input
92
+ when IPAddr
93
+ input
94
+ when Integer # Address in numeric form
95
+ tmp = [(input >> 24), (input >> 16) & 0xFF, (input >> 8) & 0xFF, input & 0xFF]
96
+ tmp = tmp.collect { |x| x.to_s }.join(".")
97
+ IPAddr.new(tmp)
98
+ when String
99
+ IPAddr.new(input)
100
+ else
101
+ raise ArgumentError, "Invalid IP address `#{input}'"
102
+ end
103
+
104
+ if !address.ipv4?
105
+ raise(ArgumentError, "Must specify an IPv4 address")
106
+ end
107
+
108
+ address
109
+ end
110
+
111
+ def build_pack
112
+ @address_pack = @address.hton
113
+ @rdlength = @address_pack.size
114
+ end
115
+
116
+ def get_data
117
+ @address_pack
118
+ end
119
+
111
120
  end
112
-
121
+
113
122
  end
114
123
  end
115
- end
124
+ end