ip 0.3.0 → 0.3.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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: c3086640a7e7397faa00f2ba00d9e819dcbc0283
4
+ data.tar.gz: 500578f6568f2efffa81e5059e0a1bf0c5161189
5
+ SHA512:
6
+ metadata.gz: af8209509af45f35f3047d876e7a6417527d2c489f4ce6c17323fe1903a2a50fdc08f62e8b114e216c7b112897defbe197f2be0d8b28d807910989fdc63df22d
7
+ data.tar.gz: ac60f52cd2982a6445438cbd6ada38ca2ac814e8ec738e71485689f99b4ad8fcbfa1e544d83c6924f0ae6a2a35b91285757abd7700f18eef61a19d11482c2a97
data/lib/ip.rb CHANGED
@@ -3,7 +3,7 @@
3
3
  #
4
4
  # Version:: 0.3.0
5
5
  # Author:: Erik Hollensbe
6
- # License:: BSD
6
+ # License:: MIT
7
7
  # Contact:: erik@hollensbe.org
8
8
  # Copyright:: Copyright (c) 2005-2006 Erik Hollensbe
9
9
  #
@@ -30,36 +30,9 @@
30
30
  # 'trial by fire' as this package came out of it's shell. Writing new
31
31
  # methods that made code easier to understand and/or clearer, and
32
32
  # making plenty of suggestions made creating this module much easier.
33
- #
34
- #--
35
- #
36
- # The compilation of software known as ip.rb is distributed under the
37
- # following terms:
38
- # Copyright (C) 2005-2006 Erik Hollensbe. All rights reserved.
39
- #
40
- # Redistribution and use in source form, with or without
41
- # modification, are permitted provided that the following conditions
42
- # are met:
43
- # 1. Redistributions of source code must retain the above copyright
44
- # notice, this list of conditions and the following disclaimer.
45
- #
46
- # THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
47
- # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
48
- # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
49
- # ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
50
- # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
51
- # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
52
- # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
53
- # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
54
- # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
55
- # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
56
- # SUCH DAMAGE.
57
- #
58
- #++
59
33
 
60
34
  class IP
61
-
62
- VERSION = "0.3.0"
35
+ VERSION = "0.3.1"
63
36
 
64
37
  #
65
38
  # A IP::AddressException is thrown when an IP address cannot be
@@ -10,7 +10,7 @@ class IP::Address
10
10
  attr_reader :ip_address
11
11
  #
12
12
  # This returns an Array of Integer which contains the octets of
13
- # the IP, in descending order.
13
+ # the IP, in descending order.
14
14
  #
15
15
  attr_reader :octets
16
16
 
@@ -24,12 +24,12 @@ class IP::Address
24
24
  end
25
25
  return @octets[num]
26
26
  end
27
-
27
+
28
28
  #
29
29
  # See [].
30
30
  #
31
31
  alias_method :octet, :[]
32
-
32
+
33
33
  #
34
34
  # Returns a 128-bit integer representing the address.
35
35
  #
@@ -66,42 +66,42 @@ class IP::Address::IPv4 < IP::Address
66
66
  # unpack to generate a string, and parse that.
67
67
  # overwrites 'ip_address'
68
68
  # horribly inefficient, but general.
69
-
69
+
70
70
  raw = IP::Address::Util.raw_unpack(ip_address)[0..1]
71
71
  octets = []
72
-
72
+
73
73
  2.times do |x|
74
74
  octets.push(raw[x] & 0x00FF)
75
75
  octets.push((raw[x] & 0xFF00) >> 8)
76
76
  end
77
-
77
+
78
78
  ip_address = octets.reverse.join(".")
79
79
  end
80
-
80
+
81
81
  if ! ip_address.kind_of? String
82
82
  raise IP::AddressException.new("Fed IP address '#{ip_address}' is not String or Fixnum")
83
83
  end
84
-
84
+
85
85
  @ip_address = ip_address
86
-
86
+
87
87
  #
88
88
  # Unbeknowest by me, to_i will not throw an exception if the string
89
89
  # can't be converted cleanly - it just truncates, similar to atoi() and perl's int().
90
90
  #
91
91
  # Code below does a final sanity check.
92
92
  #
93
-
93
+
94
94
  octets = ip_address.split(/\./)
95
95
  octets_i = octets.collect { |x| x.to_i }
96
-
96
+
97
97
  0.upto(octets.length - 1) do |octet|
98
98
  if octets[octet] != octets_i[octet].to_s
99
99
  raise IP::AddressException.new("Integer conversion failed")
100
100
  end
101
101
  end
102
-
102
+
103
103
  @octets = octets_i
104
-
104
+
105
105
  # I made a design decision to allow 0.0.0.0 here.
106
106
  if @octets.length != 4 or @octets.find_all { |x| x > 255 }.length > 0
107
107
  raise IP::AddressException.new("IP address is improperly formed")
@@ -116,14 +116,14 @@ class IP::Address::IPv4 < IP::Address
116
116
  # that the IP address is of a certain size and has certain numeric limits.
117
117
  myip = self.octets
118
118
  packval = [0] * 6
119
-
119
+
120
120
  #
121
121
  # this ensures that the octets are 8 bit, and combines the octets in order to
122
122
  # form two 16-bit integers suitable for pushing into the last places in 'packval'
123
123
  #
124
-
124
+
125
125
  (0..3).step(2) { |x| packval.push(((myip[x] & 0xFF) << 8) | (myip[x+1] & 0xFF)) }
126
-
126
+
127
127
  return IP::Address::Util.raw_pack(packval)
128
128
  end
129
129
 
@@ -151,7 +151,7 @@ class IP::Address::IPv6 < IP::Address
151
151
  #
152
152
  # * A string which contains a valid, RFC4291-compliant IPv6 address
153
153
  # (all forms are supported, including the
154
- # backwards-compatibility IPv4 methods)
154
+ # backwards-compatibility IPv4 methods)
155
155
  #
156
156
  # * A 128-bit integer which is a sum of all the octets, left-most
157
157
  # octet being the highest 32-bit portion (see IP::Address::Util
@@ -163,20 +163,20 @@ class IP::Address::IPv6 < IP::Address
163
163
  # unpack to generate a string, and parse that.
164
164
  # overwrites 'ip_address'
165
165
  # horribly inefficient, but general.
166
-
166
+
167
167
  raw = IP::Address::Util.raw_unpack(ip_address)
168
-
168
+
169
169
  ip_address = format_address(raw.reverse)
170
170
  end
171
-
171
+
172
172
  if ! ip_address.kind_of? String
173
173
  raise IP::AddressException.new("Fed IP address '#{ip_address}' is not String or Fixnum")
174
174
  end
175
-
175
+
176
176
  @ip_address = ip_address
177
-
177
+
178
178
  octets = parse_address(ip_address)
179
-
179
+
180
180
  if octets.length != 8
181
181
  raise IP::AddressException.new("IPv6 address '#{ip_address}' does not have 8 octets or a floating range specifier")
182
182
  end
@@ -185,14 +185,14 @@ class IP::Address::IPv6 < IP::Address
185
185
  # Now we check the contents of the address, to be sure we have
186
186
  # proper hexidecimal values
187
187
  #
188
-
188
+
189
189
  @octets = octets_atoi(octets)
190
190
  end
191
-
191
+
192
192
  #
193
- # parses an ip address and stores it as the current object.
193
+ # parses an ip address and stores it as the current object.
194
194
  #
195
-
195
+
196
196
  def IPv6.parse(ip_address)
197
197
  return IP::Address::IPv6.new(ip_address)
198
198
  end
@@ -212,7 +212,7 @@ class IP::Address::IPv6 < IP::Address
212
212
  #
213
213
  # IP::Address::IPv6.new("DEAD::BEEF").long_address => "DEAD:0:0:0:0:0:0:BEEF"
214
214
  #
215
-
215
+
216
216
  def long_address
217
217
  return format_address
218
218
  end
@@ -220,7 +220,7 @@ class IP::Address::IPv6 < IP::Address
220
220
  #
221
221
  # Returns a shortened address using the :: range specifier.
222
222
  #
223
- # This will replace any sequential octets that are equal to '0' with '::'.
223
+ # This will replace any sequential octets that are equal to '0' with '::'.
224
224
  # It does this searching from right to left, looking for a sequence
225
225
  # of them. Per specification, only one sequence can be replaced in
226
226
  # this fashion. It will return a long address if it can't find
@@ -235,13 +235,13 @@ class IP::Address::IPv6 < IP::Address
235
235
 
236
236
  # short circuit: if less than 2 octets are equal to 0, don't
237
237
  # bother - return a long address.
238
-
238
+
239
239
  if octets.find_all { |x| x == 0 }.length < 2
240
240
  return format_address(octets)
241
241
  end
242
242
 
243
243
  filling = false
244
-
244
+
245
245
  left = []
246
246
  right = []
247
247
 
@@ -259,18 +259,18 @@ class IP::Address::IPv6 < IP::Address
259
259
  right.push(octets[x])
260
260
  end
261
261
  end
262
-
262
+
263
263
  return format_address(left.reverse) + "::" + format_address(right.reverse)
264
-
264
+
265
265
  end
266
-
266
+
267
267
  #
268
268
  # Returns a 128-bit integer representing the address.
269
269
  #
270
270
  def pack
271
271
  return IP::Address::Util.raw_pack(self.octets.dup)
272
272
  end
273
-
273
+
274
274
  #
275
275
  # An IP Address is equal if the ip address match
276
276
  #
@@ -317,35 +317,35 @@ class IP::Address::IPv6 < IP::Address
317
317
  octets = address.split(":")
318
318
 
319
319
  if octets.length < 8
320
-
320
+
321
321
  if octets[-1].index(".").nil? and address.match(/::/)
322
322
  octets = handle_wildcard_in_address(octets)
323
323
  elsif octets[-1].index(".")
324
324
  # we have a dotted quad IPv4 compatibility address.
325
325
  # create an IPv4 object, get the raw value and stuff it into
326
326
  # the lower two octets.
327
-
327
+
328
328
  raw = IP::Address::IPv4.new(octets.pop).pack
329
329
  raw = raw & 0xFFFFFFFF
330
330
  low = raw & 0xFFFF
331
331
  high = (raw >> 16) & 0xFFFF
332
332
  octets = handle_wildcard_in_address(octets)[0..5] + ([high, low].collect { |x| format_octet(x) })
333
- else
333
+ else
334
334
  raise IP::AddressException.new("IPv6 address '#{address}' has less than 8 octets")
335
335
  end
336
-
336
+
337
337
  elsif octets.length > 8
338
338
  raise IP::AddressException.new("IPv6 address '#{address}' has more than 8 octets")
339
339
  end
340
-
340
+
341
341
  return octets
342
342
  end
343
-
343
+
344
344
 
345
345
  #
346
346
  # This handles :: addressing in IPv6 and generates a full set of
347
347
  # octets in response.
348
- #
348
+ #
349
349
  # The series of octets handed to this routine are expected to be the
350
350
  # result of splitting the address by ':'.
351
351
  #
@@ -353,9 +353,9 @@ class IP::Address::IPv6 < IP::Address
353
353
  def handle_wildcard_in_address(octets)
354
354
  lhs = []
355
355
  rhs = []
356
-
356
+
357
357
  i = octets.index("") # find ::
358
-
358
+
359
359
  # easy out for xxxx:xxxx:: and so on
360
360
  if i.nil?
361
361
  lhs = octets.dup
@@ -367,14 +367,14 @@ class IP::Address::IPv6 < IP::Address
367
367
  lhs = octets[0..(i-1)]
368
368
  rhs = octets[(i+1)..-1]
369
369
  end
370
-
370
+
371
371
  unless rhs.index("").nil?
372
372
  raise IP::AddressException.new("IPv6 address '#{ip_address}' has more than one floating range ('::') specifier")
373
373
  end
374
-
374
+
375
375
  missing = (8 - (lhs.length + rhs.length))
376
376
  missing.times { lhs.push("0") }
377
-
377
+
378
378
  octets = lhs + rhs
379
379
 
380
380
  return octets
@@ -386,7 +386,7 @@ class IP::Address::IPv6 < IP::Address
386
386
 
387
387
  def octets_atoi(octets)
388
388
  new_octets = []
389
-
389
+
390
390
  octets.each do |x|
391
391
  if x.length > 4
392
392
  raise IP::AddressException.new("IPv6 address '#{ip_address}' has an octet that is larger than 32 bits")
@@ -395,7 +395,7 @@ class IP::Address::IPv6 < IP::Address
395
395
  octet = x.hex
396
396
 
397
397
  # normalize the octet to 4 places with leading zeroes, uppercase.
398
- x = ("0" * (4 - x.length)) + x.upcase
398
+ x = ("0" * (4 - x.length)) + x.upcase
399
399
 
400
400
  unless ("%0.4X" % octet) == x
401
401
  raise IP::AddressException.new("IPv6 address '#{ip_address}' has octets that contain non-hexidecimal data")
@@ -403,7 +403,7 @@ class IP::Address::IPv6 < IP::Address
403
403
 
404
404
  new_octets.push(octet)
405
405
  end
406
-
406
+
407
407
  return new_octets
408
408
 
409
409
  end
@@ -18,7 +18,7 @@ class IP::CIDR
18
18
  # integer.
19
19
  #
20
20
  attr_reader :mask
21
-
21
+
22
22
  #
23
23
  # Given a string of format X.X.X.X/X, in standard CIDR notation,
24
24
  # this will construct a IP::CIDR object.
@@ -27,7 +27,7 @@ class IP::CIDR
27
27
  if !cidr.kind_of? String
28
28
  raise IP::AddressException.new("CIDR value is not of type String")
29
29
  end
30
-
30
+
31
31
  @cidr = cidr
32
32
  @ip, @mask = cidr.split(/\//, 2)
33
33
 
@@ -36,8 +36,8 @@ class IP::CIDR
36
36
  if @ip.nil? or @mask.nil?
37
37
  raise IP::AddressException.new("CIDR is not valid - invalid format")
38
38
  end
39
-
40
- if @mask.length == 0 or /[^0-9.]/.match @mask or
39
+
40
+ if @mask.length == 0 or /[^0-9.]/.match @mask or
41
41
  (@ip.kind_of? IP::Address::IPv6 and @mask.to_i.to_s != @mask)
42
42
  raise IP::AddressException.new("CIDR RHS is not valid - #{@mask}")
43
43
  end
@@ -46,15 +46,15 @@ class IP::CIDR
46
46
  # get the short netmask for IPv4 - this will throw an exception if the netmask is malformed.
47
47
  @mask = IP::Address::Util.short_netmask(IP::Address::IPv4.new(@mask))
48
48
  end
49
-
49
+
50
50
  @mask = @mask.to_i
51
51
  end
52
-
52
+
53
53
  def netmask
54
54
  warn "IP::CIDR#netmask is deprecated. Please use IP::CIDR#long_netmask instead."
55
55
  return self.long_netmask
56
56
  end
57
-
57
+
58
58
  #
59
59
  # This produces the long netmask (eg. 255.255.255.255) of the CIDR in an
60
60
  # IP::Address object.
@@ -65,19 +65,19 @@ class IP::CIDR
65
65
  if @ip.kind_of? IP::Address::IPv6
66
66
  raise IP::AddressException.new("IPv6 does not support a long netmask.")
67
67
  end
68
-
68
+
69
69
  return IP::Address::Util.long_netmask_ipv4(@mask)
70
70
  end
71
-
71
+
72
72
  #
73
73
  # This produces the short netmask (eg. 32) of the CIDR in an IP::Address
74
74
  # object.
75
75
  #
76
-
76
+
77
77
  def short_netmask
78
78
  return @mask
79
79
  end
80
-
80
+
81
81
  #
82
82
  # This produces a range ala IP::Range, but only for the subnet
83
83
  # defined by the CIDR object.
@@ -85,18 +85,18 @@ class IP::CIDR
85
85
  def range
86
86
  return IP::Range[self.first_ip, self.last_ip]
87
87
  end
88
-
88
+
89
89
  #
90
90
  # This returns the first ip address of the cidr as an IP::Address object.
91
91
  #
92
92
  def first_ip
93
- rawip = @ip.pack
94
-
93
+ rawip = @ip.pack
94
+
95
95
  #
96
96
  # since our actual mask calculation is done with the full 128 bits,
97
97
  # we have to shift calculations that we want in IPv4 to the left to
98
98
  # get proper return values.
99
- #
99
+ #
100
100
 
101
101
  if @ip.kind_of? IP::Address::IPv4
102
102
  rawip = rawip << 96
@@ -120,13 +120,13 @@ class IP::CIDR
120
120
  end
121
121
 
122
122
  end
123
-
123
+
124
124
  #
125
125
  # This returns the last ip address of the cidr as an IP::Address object.
126
126
  #
127
127
  def last_ip
128
128
  rawip = @ip.pack
129
-
129
+
130
130
  # see #first_ip for the reason that we shift this way for IPv4.
131
131
  if @ip.kind_of? IP::Address::IPv4
132
132
  rawip = rawip << 96
@@ -149,7 +149,7 @@ class IP::CIDR
149
149
  raise IP::AddressException.new("Cannot determine type of IP address")
150
150
  end
151
151
  end
152
-
152
+
153
153
  #
154
154
  # This will take another IP::CIDR object as an argument and check to see
155
155
  # if it overlaps with this cidr object. Returns true/false on overlap.
@@ -158,13 +158,13 @@ class IP::CIDR
158
158
  #
159
159
  def overlaps?(other_cidr)
160
160
  raise TypeError.new("Expected object of type IP::CIDR") unless(other_cidr.kind_of?(IP::CIDR))
161
-
161
+
162
162
  myfirst = self.first_ip.pack
163
163
  mylast = self.last_ip.pack
164
-
164
+
165
165
  otherfirst = other_cidr.first_ip.pack
166
166
  otherlast = other_cidr.last_ip.pack
167
-
167
+
168
168
  return ((myfirst >= otherfirst && myfirst <= otherlast) ||
169
169
  (mylast <= otherlast && mylast >= otherfirst) ||
170
170
  (otherfirst >= myfirst && otherfirst <= mylast)) ? true : false;
@@ -185,7 +185,7 @@ class IP::CIDR
185
185
  raw = address.pack
186
186
  first = first_ip.pack
187
187
  last = last_ip.pack
188
-
188
+
189
189
  return (raw >= first) && (raw <= last)
190
190
  end
191
191
 
@@ -14,22 +14,22 @@
14
14
  #
15
15
 
16
16
  class IP::Range
17
-
17
+
18
18
  #
19
19
  # See the documentation for IP::Range for more information on this
20
20
  # method.
21
21
  #
22
-
22
+
23
23
  def self.[](addr1, addr2)
24
24
  raw1, raw2 = [nil, nil]
25
25
  tmpip = nil
26
-
26
+
27
27
  if addr1.kind_of? String
28
28
  addr1 = IP::Address::Util.string_to_ip(addr1)
29
29
  elsif ! addr1.kind_of? IP::Address
30
30
  raise IP::AddressException.new("IP Address is not type String or IP::Address")
31
31
  end
32
-
32
+
33
33
  if addr2.kind_of? String
34
34
  addr2 = IP::Address::Util.string_to_ip(addr2)
35
35
  elsif ! addr2.kind_of? IP::Address
@@ -39,12 +39,12 @@ class IP::Range
39
39
  if addr2.class.name != addr1.class.name
40
40
  raise IP::AddressException.new("First and Second IP in range are not of the same type")
41
41
  end
42
-
42
+
43
43
  raw1 = addr1.pack
44
44
  raw2 = addr2.pack
45
45
 
46
46
  range = []
47
-
47
+
48
48
  # use the class we were given to force certain results, instead
49
49
  # of relying on the fairly inaccurate unpack facility.
50
50
  range = (raw1..raw2).collect { |x| addr1.class.new(x) }
@@ -8,13 +8,13 @@ module IP::Address::Util
8
8
  # 'FixNum' type. Can take both IP::Address::IPv4 and
9
9
  # IP::Address::IPv6 objects.
10
10
  #
11
-
11
+
12
12
  def pack(ip)
13
13
  return ip.pack
14
14
  end
15
-
15
+
16
16
  module_function :pack
17
-
17
+
18
18
  #
19
19
  # This routine takes an array of integers which are intended to be
20
20
  # an IP address, and joins them into a single integer used for easy
@@ -23,16 +23,16 @@ module IP::Address::Util
23
23
  # IPv4 and IPv6 objects are packed into the same size, a 128-bit
24
24
  # integer. This is done for easier processing within the library.
25
25
  #
26
-
26
+
27
27
  def raw_pack(array)
28
28
  ret = 0
29
29
  myip = array.reverse
30
30
  8.times { |x| ret = ret | myip[x] << 16*x }
31
31
  return ret
32
32
  end
33
-
33
+
34
34
  module_function :raw_pack
35
-
35
+
36
36
  #
37
37
  # Take an 'Integer' type and return an IP::Address object.
38
38
  #
@@ -46,31 +46,31 @@ module IP::Address::Util
46
46
  #
47
47
  def unpack(ip)
48
48
  ret = raw_unpack(ip)
49
-
49
+
50
50
  # any IPv6 address should meet this criteria.
51
51
  if ret[2..8].any? { |x| x > 0 }
52
52
  return IP::Address::IPv6.new(ip)
53
53
  end
54
-
54
+
55
55
  return IP::Address::IPv4.new(ip)
56
56
  end
57
-
57
+
58
58
  module_function :unpack
59
-
59
+
60
60
  #
61
61
  # Take a 'FixNum' and return it's in-place octet
62
62
  # representation. This is mostly a helper method for the unpack
63
63
  # routines.
64
64
  #
65
-
65
+
66
66
  def raw_unpack(ip)
67
67
  ret = []
68
68
  8.times { |x| ret.push((ip >> 16*x) & 0xFFFF) }
69
69
  return ret
70
70
  end
71
-
71
+
72
72
  module_function :raw_unpack
73
-
73
+
74
74
  #
75
75
  # Returns a short subnet mask - works for all IP::Address objects.
76
76
  #
@@ -78,7 +78,7 @@ module IP::Address::Util
78
78
  # short_netmask(IP::Address::IPv4.new("255.255.255.255")) => 32
79
79
  # short_netmask(IP::Address::IPv6.new("2001:0DB8:0000:CD30:0000:0000:0000:0000")) => 60
80
80
  #
81
-
81
+
82
82
  def short_netmask(ip)
83
83
  #
84
84
  # This method handles 128-bit integers better for both types of
@@ -86,7 +86,7 @@ module IP::Address::Util
86
86
  #
87
87
  # TODO: there really is probably a better way to do this.
88
88
  #
89
-
89
+
90
90
  s = ip.pack.to_s(2)
91
91
 
92
92
  pad = 0
@@ -102,16 +102,16 @@ module IP::Address::Util
102
102
 
103
103
  return s.rindex("1") + 1
104
104
  end
105
-
105
+
106
106
  module_function :short_netmask
107
-
107
+
108
108
  def long_netmask(short)
109
109
  warn "This function is deprecated, please use IP::Address::Util.long_netmask_ipv4 instead."
110
110
  return long_netmask_ipv4(short)
111
111
  end
112
-
112
+
113
113
  module_function :long_netmask
114
-
114
+
115
115
  #
116
116
  # Given a CIDR-notation "short" netmask, returns a IP::Address object containing
117
117
  # the equivalent "long" netmask.
@@ -120,14 +120,14 @@ module IP::Address::Util
120
120
  # long_netmask(32) => IP::Address object of "255.255.255.255"
121
121
  # long_netmask(28) => IP::Address object of "255.255.255.240"
122
122
  #
123
-
123
+
124
124
  def long_netmask_ipv4(short)
125
125
  raw = (0xFFFFFFFF << (32 - short)) & 0xFFFFFFFF
126
126
  return IP::Address::Util.unpack(raw)
127
127
  end
128
-
128
+
129
129
  module_function :long_netmask_ipv4
130
-
130
+
131
131
  #
132
132
  # This takes a string which supposedly contains an IP address, and
133
133
  # tries to figure out if it is a IPv6 or IPv4 address. Returns a
metadata CHANGED
@@ -1,15 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ip
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
5
- prerelease:
4
+ version: 0.3.1
6
5
  platform: ruby
7
6
  authors:
8
7
  - Erik Hollensbe
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2012-04-11 00:00:00.000000000 Z
11
+ date: 2014-01-21 00:00:00.000000000 Z
13
12
  dependencies: []
14
13
  description:
15
14
  email: erik@hollensbe.org
@@ -17,38 +16,33 @@ executables: []
17
16
  extensions: []
18
17
  extra_rdoc_files: []
19
18
  files:
20
- - Rakefile
21
- - examples/check-included.rb
22
- - examples/check-overlap.rb
23
- - examples/generate-a-records.rb
24
19
  - lib/ip.rb
25
- - test/test_ip.rb
26
20
  - lib/ip/address.rb
27
21
  - lib/ip/cidr.rb
28
22
  - lib/ip/range.rb
29
23
  - lib/ip/util.rb
30
24
  homepage: http://github.com/erikh/ip
31
- licenses: []
25
+ licenses:
26
+ - MIT
27
+ metadata: {}
32
28
  post_install_message:
33
29
  rdoc_options: []
34
30
  require_paths:
35
31
  - lib
36
32
  required_ruby_version: !ruby/object:Gem::Requirement
37
- none: false
38
33
  requirements:
39
- - - ! '>='
34
+ - - '>='
40
35
  - !ruby/object:Gem::Version
41
36
  version: '0'
42
37
  required_rubygems_version: !ruby/object:Gem::Requirement
43
- none: false
44
38
  requirements:
45
- - - ! '>='
39
+ - - '>='
46
40
  - !ruby/object:Gem::Version
47
41
  version: '0'
48
42
  requirements: []
49
43
  rubyforge_project: ip-address
50
- rubygems_version: 1.8.15
44
+ rubygems_version: 2.1.10
51
45
  signing_key:
52
- specification_version: 3
46
+ specification_version: 4
53
47
  summary: Ruby classes to work with IP address, ranges, and netmasks
54
48
  test_files: []
data/Rakefile DELETED
@@ -1,76 +0,0 @@
1
- #
2
- # Please see the COPYING file in the source distribution for copyright information.
3
- #
4
-
5
- begin
6
- require 'rubygems'
7
- gem 'test-unit'
8
- rescue LoadError
9
- end
10
-
11
- $:.unshift 'lib'
12
- require 'rake/testtask'
13
- require 'rake/packagetask'
14
- require 'rake/gempackagetask'
15
- require 'rake/rdoctask'
16
- require 'ip'
17
-
18
- task :default => [ :dist ]
19
-
20
- #
21
- # Tests
22
- #
23
-
24
- Rake::TestTask.new do |t|
25
- t.libs << 'lib'
26
- t.test_files = FileList['test/test*.rb']
27
- t.verbose = true
28
- end
29
-
30
- #
31
- # Distribution
32
- #
33
-
34
- task :dist => [:test, :repackage, :gem, :rdoc]
35
- task :distclean => [:clobber_package, :clobber_rdoc]
36
- task :clean => [:distclean]
37
-
38
- #
39
- # Documentation
40
- #
41
-
42
- Rake::RDocTask.new do |rd|
43
- rd.rdoc_dir = "rdoc"
44
- rd.main = "IP"
45
- rd.rdoc_files.include("./lib/**/*.rb")
46
- rd.options = %w(-ap)
47
- end
48
-
49
- #
50
- # Packaging
51
- #
52
-
53
- spec = Gem::Specification.new do |s|
54
- s.name = "ip"
55
- s.version = IP::VERSION
56
- s.author = "Erik Hollensbe"
57
- s.email = "erik@hollensbe.org"
58
- s.summary = "Ruby classes to work with IP address, ranges, and netmasks"
59
- s.has_rdoc = true
60
- s.files = Dir['Rakefile'] + Dir['examples/*.rb'] + Dir['lib/*.rb'] + Dir['test/*.rb'] + Dir['lib/ip/*.rb']
61
- s.rubyforge_project = 'ip-address'
62
- s.homepage = "http://github.com/erikh/ip"
63
- end
64
-
65
- Rake::GemPackageTask.new(spec) do |s|
66
- end
67
-
68
- Rake::PackageTask.new(spec.name, spec.version) do |p|
69
- p.need_tar_gz = true
70
- p.need_zip = true
71
- p.package_files.include("./setup.rb")
72
- p.package_files.include("./Rakefile")
73
- p.package_files.include("./examples/**/*.rb")
74
- p.package_files.include("./lib/**/*.rb")
75
- p.package_files.include("./test/**/*")
76
- end
@@ -1,27 +0,0 @@
1
- #!/usr/bin/env ruby
2
- #
3
- # Checks if a given IP address exists in a subnet.
4
- #
5
- # Takes either IPv6 or IPv4.
6
- #
7
-
8
- begin
9
- require 'rubygems'
10
- rescue LoadError => e
11
- end
12
-
13
- require 'ip'
14
-
15
- if !ARGV[0] or !ARGV[1]
16
- $stderr.puts "usage: #{File.basename($0)} <cidr> <ip>"
17
- exit -1
18
- end
19
-
20
- if IP::CIDR.new(ARGV[0]).includes? IP::Address::Util.string_to_ip(ARGV[1])
21
- $stderr.puts "IP #{ARGV[1]} exists in the #{ARGV[0]} subnet"
22
- exit 0
23
- else
24
- $stderr.puts "IP #{ARGV[1]} does not exist in the #{ARGV[0]} subnet"
25
- exit 1
26
- end
27
-
@@ -1,26 +0,0 @@
1
- #!/usr/bin/env ruby
2
- #
3
- # given two CIDR formatted addresses, check for overlaps.
4
- #
5
- # Takes either IPv6 or IPv4.
6
- #
7
-
8
- begin
9
- require 'rubygems'
10
- rescue LoadError => e
11
- end
12
-
13
- require 'ip'
14
-
15
- if !ARGV[0] or !ARGV[1]
16
- $stderr.puts "usage: #{File.basename($0)} <cidr> <cidr>"
17
- exit -1
18
- end
19
-
20
- if IP::CIDR.new(ARGV[0]).overlaps? IP::CIDR.new(ARGV[1])
21
- $stderr.puts "These address ranges overlap."
22
- exit 1
23
- else
24
- $stderr.puts "No overlaps"
25
- exit 0
26
- end
@@ -1,26 +0,0 @@
1
- #!/usr/bin/env ruby
2
- #
3
- # Generate a set of A records suitable for inclusion in a
4
- # zone.
5
- #
6
- # Takes two IP addresses as a range to generate.
7
- #
8
-
9
- begin
10
- require 'rubygems'
11
- rescue LoadError => e
12
- end
13
-
14
- require 'ip'
15
-
16
- if !ARGV[0] or !ARGV[1]
17
- $stderr.puts "usage: #{File.basename($0)} <start ip> <end ip>"
18
- exit -1
19
- end
20
-
21
- $fmt = "%15.15s IN A %15.15s"
22
-
23
- IP::Range[ARGV[0], ARGV[1]].each do |ip|
24
- hostname = ip.ip_address.gsub(/\./, "-")
25
- puts ($fmt % [hostname, ip.ip_address])
26
- end
@@ -1,313 +0,0 @@
1
- begin
2
- require 'rubygems'
3
- gem 'test-unit'
4
- rescue LoadError => e
5
- end
6
-
7
- require 'test/unit'
8
- load 'lib/ip.rb'
9
-
10
- class CIDRTest < Test::Unit::TestCase
11
-
12
- def name
13
- return "IP::CIDR tests"
14
- end
15
-
16
- def test_init_generic
17
- assert_raise(IP::AddressException) { IP::CIDR.new(Hash.new) }
18
- assert_raise(IP::AddressException) { IP::CIDR.new("foomatic_wootmaster/32") }
19
- end
20
-
21
- def test_init_ipv6
22
- assert_raise(IP::AddressException) { IP::CIDR.new("F00F:DEAD:BEEF::") }
23
- assert_raise(IP::AddressException) { IP::CIDR.new("F00F:DEAD:BEEF::/") }
24
- assert_raise(IP::AddressException) { IP::CIDR.new("F00F:DEAD:BEEF::/asdf/32") }
25
- assert_raise(IP::AddressException) { IP::CIDR.new("F00F:DEAD:BEEF::/foomatic_wootmaster") }
26
- assert_raise(IP::AddressException) { IP::CIDR.new("F00F:DEAD:BEEF::/255.255.255.255") }
27
-
28
- cidr = nil
29
- assert_nothing_raised() { cidr = IP::CIDR.new("F00F:DEAD:BEEF::0001/128") }
30
-
31
- # this sort of indirectly tests the ipv6 address manipulation.
32
- assert_equal("F00F:DEAD:BEEF::1", cidr.ip.short_address, "ipv6 object constructed clean")
33
- assert_equal(128, cidr.mask, "mask is set properly")
34
- assert_equal("F00F:DEAD:BEEF::0001/128", cidr.cidr, "original CIDR preserved")
35
- end
36
-
37
- def test_init_ipv4
38
- assert_raise(IP::AddressException) { IP::CIDR.new("10.0.0.1") }
39
- assert_raise(IP::AddressException) { IP::CIDR.new("10.0.0.1/") }
40
- assert_raise(IP::AddressException) { IP::CIDR.new("10.0.0.1/asdf/32") }
41
- assert_raise(IP::AddressException) { IP::CIDR.new("10.0.0.1/foomatic_wootmaster") }
42
- assert_raise(IP::AddressException) { IP::CIDR.new("10.0.0.1/255") }
43
-
44
- cidr = nil
45
-
46
- assert_nothing_raised() { cidr = IP::CIDR.new("10.0.0.1/32") }
47
-
48
- assert_equal("10.0.0.1", cidr.ip.ip_address, "ipv4 data integrity test #1")
49
- assert_equal(32, cidr.mask, "ipv4 data integrity test #2")
50
- assert_equal("10.0.0.1/32", cidr.cidr, "ipv4 data integrity test #3")
51
-
52
- assert_nothing_raised() { cidr = IP::CIDR.new("10.0.0.1/255.255.255.255") }
53
-
54
- assert_equal("10.0.0.1", cidr.ip.ip_address, "ipv4 data integrity test #4")
55
- assert_equal(32, cidr.mask, "ipv4 data integrity test #5")
56
- assert_equal("10.0.0.1/255.255.255.255", cidr.cidr, "ipv4 data integrity test #6")
57
- end
58
-
59
- def test_netmasks
60
- cidr = nil
61
- assert_nothing_raised() { cidr = IP::CIDR.new("10.0.0.1/32") }
62
- assert_equal(32, cidr.short_netmask, "ipv4 netmask test #1")
63
- assert_equal("255.255.255.255", cidr.long_netmask.ip_address, "ipv4 netmask test #2")
64
-
65
- assert_nothing_raised() { cidr = IP::CIDR.new("10.0.0.1/255.255.255.248") }
66
- assert_equal(29, cidr.short_netmask, "ipv4 netmask test #3")
67
- assert_equal("255.255.255.248", cidr.long_netmask.ip_address, "ipv4 netmask test #4")
68
-
69
- assert_nothing_raised() { cidr = IP::CIDR.new("F00F:DEAD::/16") }
70
- assert_equal(16, cidr.short_netmask, "ipv6 has proper short netmask")
71
- assert_raise(IP::AddressException) { cidr.long_netmask }
72
- end
73
-
74
- def test_first_last
75
- cidr = nil
76
- assert_nothing_raised() { cidr = IP::CIDR.new("10.0.0.2/24") }
77
- assert_equal("10.0.0.0", cidr.first_ip.ip_address, "ipv4 first/last test #1")
78
- assert_equal("10.0.0.255", cidr.last_ip.ip_address, "ipv4 first/last test #2")
79
- end
80
-
81
- def test_range
82
- cidr = nil
83
- assert_nothing_raised() { cidr = IP::CIDR.new("10.0.0.2/24") }
84
- assert_equal(1, cidr.range.find_all { |x| x.ip_address == "10.0.0.1" }.length, "ipv4 range test #1")
85
- assert_equal(0, cidr.range.find_all { |x| x.ip_address == "10.0.1.0" }.length, "ipv4 range test #2")
86
-
87
- assert_nothing_raised() { cidr = IP::CIDR.new("::0001/120") }
88
- assert_equal(1, cidr.range.find_all { |x| x.ip_address == "0:0:0:0:0:0:0:00FF" }.length, "ipv6 range test (included)")
89
- assert_equal(0, cidr.range.find_all { |x| x.ip_address ==" 0:0:0:0:0:0:0:0F00" }.length, "ipv6 range test (not included)")
90
- end
91
-
92
- def test_overlaps
93
- cidr, cidr2 = [nil, nil]
94
-
95
- assert_nothing_raised() do
96
- cidr = IP::CIDR.new("10.0.0.2/24")
97
- cidr2 = IP::CIDR.new("10.0.0.1/29")
98
- end
99
-
100
- assert(cidr.overlaps?(cidr2), "ipv4 overlaps test #1")
101
-
102
- assert_nothing_raised() { cidr2 = IP::CIDR.new("10.0.0.1/16") }
103
-
104
- assert(cidr2.overlaps?(cidr), "ipv4 overlaps test #2")
105
- assert(cidr.overlaps?(cidr2), "ipv4 overlaps test #3")
106
-
107
- assert_nothing_raised() do
108
- cidr = IP::CIDR.new("F00F:DEAD::/16")
109
- cidr2 = IP::CIDR.new("F00F:BEEF::/16")
110
- end
111
-
112
- assert(cidr.overlaps?(cidr2), "ipv6 #overlaps? reports correctly #1")
113
- assert(cidr2.overlaps?(cidr), "ipv6 #overlaps? reports correctly #2")
114
- end
115
-
116
- def test_includes
117
- cidr, ip = [nil, nil]
118
- assert_nothing_raised() do
119
- cidr = IP::CIDR.new("10.0.0.2/24")
120
- ip = IP::Address::IPv4.new("10.0.0.1")
121
- end
122
-
123
- assert(cidr.includes?(ip), "ipv4 #includes? reports correctly (included)")
124
-
125
- assert_nothing_raised() { ip = IP::Address::IPv4.new("10.0.1.0") }
126
-
127
- assert(!cidr.includes?(ip), "ipv4 #includes? reports correctly (not included)")
128
-
129
- assert_nothing_raised() do
130
- cidr = IP::CIDR.new("FF00::/16")
131
- ip = IP::Address::IPv6.new("FF00::DEAD")
132
- end
133
- assert(cidr.includes?(ip), "ipv6 #includes? reports correctly (included)")
134
-
135
- assert_nothing_raised() { ip = IP::Address::IPv6.new("F000::DEAD") }
136
-
137
- assert(!cidr.includes?(ip), "ipv6 #includes? reports correctly (not included)")
138
- end
139
-
140
- end
141
-
142
- class RangeTest < Test::Unit::TestCase
143
- def name
144
- return "IP::Range tests"
145
- end
146
-
147
- def test_range_generic
148
- assert_raise(IP::AddressException) { IP::Range[Hash.new, ""] }
149
- assert_raise(IP::AddressException) { IP::Range["", Hash.new] }
150
- assert_raise(IP::AddressException) { IP::Range[IP::Address::IPv6.new("F00F::"), IP::Address::IPv4.new("10.0.0.1")] }
151
- assert_raise(IP::AddressException) { IP::Range[IP::Address::IPv4.new("10.0.0.1"), IP::Address::IPv6.new("F00F::")] }
152
- end
153
-
154
- def test_range_ipv6
155
- assert_nothing_raised() do
156
- IP::Range["::0001", "::00F0"]
157
- IP::Range[IP::Address::IPv6.new("::0001"), IP::Address::IPv6.new("::00F0")]
158
- end
159
-
160
- range = nil
161
-
162
- assert_nothing_raised() { range = IP::Range["::0001", "::0010"] }
163
-
164
- assert_equal(1, range.find_all { |x| x.short_address == "::1" }.length, "ipv6 range check #1")
165
- assert_equal(1, range.find_all { |x| x.short_address == "::0010" }.length, "ipv6 range check #2")
166
- assert_equal(1, range.find_all { |x| x.short_address == "::000A" }.length, "ipv6 range check #3")
167
- assert_equal(0, range.find_all { |x| x.short_address == "::0011" }.length, "ipv6 range check #4")
168
- end
169
-
170
- def test_range_ipv4
171
- assert_nothing_raised() do
172
- IP::Range["10.0.0.1", "10.0.0.2"]
173
- IP::Range[IP::Address::IPv4.new("10.0.0.1"), IP::Address::IPv4.new("10.0.0.2")]
174
- end
175
-
176
- range = nil
177
- assert_nothing_raised() { range = IP::Range["10.0.0.1", "10.0.0.10"] }
178
-
179
- assert_equal(1, range.find_all { |x| x.ip_address == "10.0.0.1" }.length, "ipv4 range check #1")
180
- assert_equal(1, range.find_all { |x| x.ip_address == "10.0.0.10" }.length, "ipv4 range check #2")
181
- assert_equal(1, range.find_all { |x| x.ip_address == "10.0.0.7" }.length, "ipv4 range check #3")
182
- assert_equal(0, range.find_all { |x| x.ip_address == "10.0.0.11" }.length, "ipv4 range check #4")
183
- end
184
-
185
- end
186
-
187
- class IPv6AddressTest < Test::Unit::TestCase
188
- def name
189
- return "IP::Address::IPv6 tests"
190
- end
191
-
192
- def test_init
193
- assert_nothing_raised() do
194
- IP::Address::IPv6.new("0000:0000:0000:0000:0000:0000:0000:0001")
195
- IP::Address::IPv6.new("::0001")
196
- IP::Address::IPv6.new("FF00::")
197
- IP::Address::IPv6.new("FF00::0001")
198
- IP::Address::IPv6.new("FF00:BEEF::0001")
199
- IP::Address::IPv6.new("FF00::BEEF:0001")
200
- IP::Address::IPv6.new("::1.2.3.4")
201
- IP::Address::IPv6.new("FFFF::1.2.3.4")
202
- IP::Address::IPv6.new("FFFF:0000:0000:0000:0000:0000:1.2.3.4")
203
- end
204
-
205
- # now, the tests that should fail
206
-
207
- assert_raise(IP::AddressException) { IP::Address::IPv6.new("FF00:BEEF:") }
208
- assert_raise(IP::AddressException) { IP::Address::IPv6.new("FF00::BEEF::") }
209
- assert_raise(IP::AddressException) { IP::Address::IPv6.new("FF00::BEEF::DEAD") }
210
- assert_raise(IP::AddressException) { IP::Address::IPv6.new("HF00::0001") }
211
- assert_raise(IP::AddressException) { IP::Address::IPv6.new("1.2.3.4::0001") }
212
- end
213
-
214
- def test_accessors
215
- ip = nil
216
- assert_nothing_raised() { ip = IP::Address::IPv6.new("F00F::DEAD:BEEF") }
217
-
218
- assert_equal(ip[0], ip.octet(0), "ip[0] eq ip.octet(0)")
219
- assert_equal(61455, ip[0], "ip[0] is correct")
220
- assert_equal("F00F", ip.octet_as_hex(0), "octet converts to hex properly")
221
- assert_equal("F00F::DEAD:BEEF", ip.ip_address, '#ip_address preserves original address')
222
- end
223
-
224
- def test_address
225
- ip = nil
226
- assert_nothing_raised() { ip = IP::Address::IPv6.new("F00F::DEAD:BEEF") }
227
- assert_equal("F00F::DEAD:BEEF", ip.short_address, 'wildcard left - #short_address returns a compressed version')
228
- assert_equal("F00F:0:0:0:0:0:DEAD:BEEF", ip.long_address, 'wildcard left - #long_address returns the right thing')
229
-
230
- assert_nothing_raised() { ip = IP::Address::IPv6.new("F00F:DEAD::BEEF") }
231
- assert_equal("F00F:DEAD::BEEF", ip.short_address, 'wildcard right - #short_address returns a compressed version')
232
- assert_equal("F00F:DEAD:0:0:0:0:0:BEEF", ip.long_address, 'wildcard right - #long_address returns the right thing')
233
-
234
- assert_nothing_raised() { ip = IP::Address::IPv6.new("F00F:DEAD:0:0:0:0:0:BEEF") }
235
- assert_equal("F00F:DEAD::BEEF", ip.short_address, 'no wildcard - #short_address returns a compressed version')
236
- assert_equal("F00F:DEAD:0:0:0:0:0:BEEF", ip.long_address, 'no wildcard - #long_address returns the right thing')
237
-
238
- assert_nothing_raised() { ip = IP::Address::IPv6.new("F00F::DEAD:BEEF:0:0") }
239
- assert_equal("F00F:0:0:0:DEAD:BEEF::", ip.short_address, '#short_address returns a compressed version with wildcard @ right')
240
- end
241
-
242
- def test_equal
243
- assert_equal(IP::Address::IPv6.new("F00F::DEAD:BEEF"),IP::Address::IPv6.new("F00F::DEAD:BEEF"))
244
- assert_equal(IP::Address::IPv6.new("F00F::DEAD:BEEF"), "F00F::DEAD:BEEF")
245
- assert_equal(IP::Address::IPv6.new("F00F::DEAD:BEEF"), "F00F:0:0:0:0:0:DEAD:BEEF")
246
- assert_equal(IP::Address::IPv6.new("F00F::DEAD:BEEF"), 319092603441257831911341651915956928239)
247
- assert !(IP::Address::IPv6.new("F00D::DEAD:BEEF") == IP::Address::IPv6.new("F00F::DEAD:BEEF"))
248
- assert !(IP::Address::IPv6.new("F00D::DEAD:BEEF") == :someting_else)
249
- end
250
- end
251
-
252
-
253
- class IPv4AddressTest < Test::Unit::TestCase
254
- def name
255
- return "IP::Address::IPv4 tests"
256
- end
257
-
258
- def test_init
259
- assert_raise(IP::AddressException) { IP::Address::IPv4.new(Hash.new) }
260
- assert_raise(IP::AddressException) { IP::Address::IPv4.new("asdf") }
261
- assert_raise(IP::AddressException) { IP::Address::IPv4.new("0.0.0") }
262
- assert_raise(IP::AddressException) { IP::Address::IPv4.new("256.255.255.255") }
263
- assert_raise(IP::AddressException) { IP::Address::IPv4.new("255.255.255.255aaaa") }
264
- assert_raise(IP::AddressException) { IP::Address::IPv4.new("255.255.255.") }
265
- end
266
-
267
- def test_accessor
268
- ip = nil
269
- assert_nothing_raised() { ip = IP::Address::IPv4.new("10.1.2.3") }
270
- assert_equal("10.1.2.3", ip.ip_address, "accessor test #1")
271
- assert_equal(10, ip.octets[0], "accessor test #2")
272
- assert_equal(3, ip.octets[3], "accessor test #3")
273
- assert_equal(nil, ip.octets[4], "accessor test #4")
274
-
275
- assert_equal(ip.octet(1), ip[1], "accessor test #5")
276
- assert_equal(1, ip[1], "accessor test #5")
277
-
278
- assert_raise(IP::BoundaryException) { ip[4] }
279
- end
280
-
281
- end
282
-
283
- class UtilTest < Test::Unit::TestCase
284
- def name
285
- return "IP::Address::Util tests"
286
- end
287
-
288
- def test_pack_unpack
289
- address = "10.0.0.1"
290
- assert_equal("10.0.0.1", IP::Address::Util.unpack(IP::Address::Util.pack(IP::Address::IPv4.new(address))).ip_address, "pack/unpack test")
291
- end
292
-
293
- def test_short_netmask
294
- ip = nil
295
- assert_nothing_raised() { ip = IP::Address::IPv4.new("255.255.255.255") }
296
- assert_equal(32, IP::Address::Util.short_netmask(ip), "Short Netmask Test #1")
297
- assert_nothing_raised() { ip = IP::Address::IPv4.new("255.255.255.248") }
298
- assert_equal(29, IP::Address::Util.short_netmask(ip), "Short Netmask Test #2")
299
- end
300
-
301
- def test_long_netmask
302
- assert_equal("255.255.255.255", IP::Address::Util.long_netmask_ipv4(32).ip_address, "Long Netmask Test #1")
303
- assert_equal("255.255.255.248", IP::Address::Util.long_netmask_ipv4(29).ip_address, "Long Netmask Test #2")
304
- end
305
-
306
- def test_equal
307
- assert_equal(IP::Address::IPv4.new("255.255.255.255"),IP::Address::IPv4.new("255.255.255.255"))
308
- assert_equal(IP::Address::IPv4.new("255.255.255.255"), "255.255.255.255")
309
- assert_equal(IP::Address::IPv4.new("255.255.255.255"), 4294967295) # 255.255.255.255
310
- assert !(IP::Address::IPv4.new("255.255.255.255") == IP::Address::IPv4.new("255.255.255.254"))
311
- assert !(IP::Address::IPv4.new("255.255.255.255") == :something_else)
312
- end
313
- end