better_ipaddr 0.5.0 → 0.6.0
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.
- checksums.yaml +5 -5
- data/.rubocop.yml +60 -0
- data/.travis.yml +6 -3
- data/README.md +12 -0
- data/Rakefile +6 -1
- data/better_ipaddr.gemspec +9 -5
- data/lib/better_ipaddr/classes.rb +78 -11
- data/lib/better_ipaddr/constants.rb +7 -4
- data/lib/better_ipaddr/core_extension.rb +0 -1
- data/lib/better_ipaddr/host_methods.rb +1 -0
- data/lib/better_ipaddr/kernel_method.rb +29 -4
- data/lib/better_ipaddr/methods.rb +5 -43
- data/lib/better_ipaddr/space.rb +4 -3
- data/lib/better_ipaddr/version.rb +1 -1
- metadata +49 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 5cd953909cfae8bb5422a297acdd4592ec96957c262072587add707a78ca9dd3
|
4
|
+
data.tar.gz: 32ff0ee9fb1aa6fc91a1fd2db3802add0d9b10af29c97ecbb066b3805ca5dcf3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4ac0277a9876f20973dd0418547093ec41342ecbd1186c2da235c2463a0cd70f9cf39c623242ebad8cb2aa2156528a1d9735317c82a04310385ae93624beec75
|
7
|
+
data.tar.gz: 2d8f9e58dc03ea59d6af81995345e37395fd259bb1a615ef6ad9cd0d6e19a5b9cfb5f1ef3cc2891574861e99ae9280ee72288ed5d29308483b4d909041f7dba1
|
data/.rubocop.yml
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
AllCops:
|
2
|
+
Exclude:
|
3
|
+
- 'spec/extra/**/*'
|
4
|
+
|
5
|
+
Layout/EmptyLinesAroundArguments:
|
6
|
+
Enabled: false
|
7
|
+
|
8
|
+
Lint/UnusedMethodArgument:
|
9
|
+
AllowUnusedKeywordArguments: true
|
10
|
+
|
11
|
+
Metrics/AbcSize:
|
12
|
+
Max: 20
|
13
|
+
|
14
|
+
Metrics/BlockLength:
|
15
|
+
Exclude:
|
16
|
+
- 'spec/**/*'
|
17
|
+
|
18
|
+
Metrics/ClassLength:
|
19
|
+
Exclude:
|
20
|
+
- 'lib/better_ipaddr/classes.rb'
|
21
|
+
- 'lib/better_ipaddr/space.rb'
|
22
|
+
|
23
|
+
Metrics/MethodLength:
|
24
|
+
Max: 15
|
25
|
+
|
26
|
+
Metrics/ModuleLength:
|
27
|
+
Exclude:
|
28
|
+
- 'lib/better_ipaddr/methods.rb'
|
29
|
+
|
30
|
+
Naming/BinaryOperatorParameterName:
|
31
|
+
Enabled: false
|
32
|
+
|
33
|
+
Naming/MethodName:
|
34
|
+
Exclude:
|
35
|
+
- 'lib/better_ipaddr/kernel_method.rb'
|
36
|
+
|
37
|
+
Style/Alias:
|
38
|
+
EnforcedStyle: prefer_alias_method
|
39
|
+
|
40
|
+
Style/CommentedKeyword:
|
41
|
+
Enabled: false
|
42
|
+
|
43
|
+
Style/Documentation:
|
44
|
+
Exclude:
|
45
|
+
- 'lib/better_ipaddr/core_extension.rb'
|
46
|
+
- 'lib/better_ipaddr/kernel_method.rb'
|
47
|
+
- 'spec/**/*'
|
48
|
+
|
49
|
+
Style/MutableConstant:
|
50
|
+
Exclude:
|
51
|
+
- 'lib/better_ipaddr/constants.rb'
|
52
|
+
|
53
|
+
Style/NumericPredicate:
|
54
|
+
EnforcedStyle: comparison
|
55
|
+
|
56
|
+
Style/StringLiterals:
|
57
|
+
Enabled: false
|
58
|
+
|
59
|
+
Style/YodaCondition:
|
60
|
+
Enabled: false
|
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -10,6 +10,8 @@ require "better_ipaddr"
|
|
10
10
|
addr = IPAddr::V4[some_source] # shortcut for .new, because your test suite
|
11
11
|
# contains a zillion IP addresses and you're
|
12
12
|
# tired of typing Socket::AF_INET
|
13
|
+
addr.inspect #
|
14
|
+
#=> "IPAddr::V4['1.2.3.0/24']" # inspect emits readable, copy-pastable ruby code
|
13
15
|
addr.host? # is it a host address?
|
14
16
|
addr.network? # or a network address?
|
15
17
|
addr.cidr # what is the CIDR representation?
|
@@ -77,6 +79,16 @@ class_c = addr << 8 # => IPAddr::V4["1.0.0.0/24"]
|
|
77
79
|
IPAddr.new("1.0.0.0/24").summarize_with(IPAddr["1.0.1.0/24"]) # => IPAddr::V4["1.0.0.0/23"]
|
78
80
|
```
|
79
81
|
|
82
|
+
This approach introduces at least one incompatibility: addresses that differ
|
83
|
+
only in their netmask are considered equal in ipaddr, but not in better_ipaddr:
|
84
|
+
|
85
|
+
```ruby
|
86
|
+
require 'ipaddr'
|
87
|
+
IPAddr.new('1.0.0.0/32') == IPAddr.new('1.0.0.0/8') # => true
|
88
|
+
require 'better_ipaddr/core_extension'
|
89
|
+
IPAddr.new('1.0.0.0/32') == IPAddr.new('1.0.0.0/8') # => false
|
90
|
+
```
|
91
|
+
|
80
92
|
The recommended way is to `require "better_ipaddr"` and use
|
81
93
|
the `IPAddr` subclasses explicitly.
|
82
94
|
|
data/Rakefile
CHANGED
@@ -7,4 +7,9 @@ Rake::TestTask.new(:spec) do |t|
|
|
7
7
|
t.test_files = FileList["spec/**/*_spec.rb"]
|
8
8
|
end
|
9
9
|
|
10
|
-
|
10
|
+
Rake::TestTask.new(:spec_ipaddr) do |t|
|
11
|
+
t.libs << "lib"
|
12
|
+
t.test_files = FileList["spec/extra/**/test_ipaddr.rb"]
|
13
|
+
end
|
14
|
+
|
15
|
+
task default: %i[spec spec_ipaddr]
|
data/better_ipaddr.gemspec
CHANGED
@@ -1,5 +1,4 @@
|
|
1
|
-
|
2
|
-
lib = File.expand_path('../lib', __FILE__)
|
1
|
+
lib = File.expand_path('lib', __dir__)
|
3
2
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
3
|
require 'better_ipaddr/version'
|
5
4
|
|
@@ -13,13 +12,18 @@ Gem::Specification.new do |spec|
|
|
13
12
|
spec.homepage = "https://github.com/bjmllr/better_ipaddr"
|
14
13
|
spec.license = "GPL-3.0"
|
15
14
|
|
16
|
-
spec.files = `git ls-files -z
|
15
|
+
spec.files = `git ls-files -z`
|
16
|
+
.split("\x0")
|
17
17
|
.reject { |f| f.match(%r{^(test|spec|features)/}) }
|
18
|
+
|
18
19
|
spec.bindir = "exe"
|
19
|
-
spec.executables = spec.files.grep(%r
|
20
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
20
21
|
spec.require_paths = ["lib"]
|
21
22
|
|
22
23
|
spec.add_development_dependency "bundler", "~> 1.0"
|
23
|
-
spec.add_development_dependency "
|
24
|
+
spec.add_development_dependency "ipaddr", ">= 1.2.0"
|
24
25
|
spec.add_development_dependency "minitest", "~> 5.0"
|
26
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
27
|
+
spec.add_development_dependency "rubocop", "~> 0.54" if RUBY_VERSION > '2.1'
|
28
|
+
spec.add_development_dependency "test-unit"
|
25
29
|
end
|
@@ -3,6 +3,7 @@ require "better_ipaddr/methods"
|
|
3
3
|
require "better_ipaddr/host_methods"
|
4
4
|
|
5
5
|
class IPAddr
|
6
|
+
# An intermediate superclass for all BetterIpaddr classes
|
6
7
|
class Base < IPAddr
|
7
8
|
include BetterIpaddr::Constants
|
8
9
|
include BetterIpaddr::InstanceMethods
|
@@ -17,8 +18,9 @@ class IPAddr
|
|
17
18
|
# @param address [Integer, IPAddr, String]
|
18
19
|
# @param mask [Integer, IPAddr, String, Nil]
|
19
20
|
# @param family [Integer]
|
21
|
+
# @param classful [Boolean] see Base.from_string
|
20
22
|
# @return [IPAddr, Nil]
|
21
|
-
def self.[](address, mask = nil, family: self::FAMILY)
|
23
|
+
def self.[](address, mask = nil, family: self::FAMILY, classful: false)
|
22
24
|
prefix_length = mask && object_to_prefix_length(mask, family)
|
23
25
|
|
24
26
|
case address
|
@@ -27,7 +29,7 @@ class IPAddr
|
|
27
29
|
when IPAddr
|
28
30
|
from_ipaddr(address, prefix_length, family: family)
|
29
31
|
when String
|
30
|
-
from_string(address, prefix_length, family: family)
|
32
|
+
from_string(address, prefix_length, family: family, classful: classful)
|
31
33
|
end
|
32
34
|
end
|
33
35
|
|
@@ -42,16 +44,24 @@ class IPAddr
|
|
42
44
|
# content.
|
43
45
|
#
|
44
46
|
# @param address [Integer, IPAddr, String]
|
47
|
+
# @param exception [Boolean] If true, then when the given object can't be
|
48
|
+
# converted to an IPAddr, a TypeError will be raise rather than returning
|
49
|
+
# nil.
|
50
|
+
# @param classful [Boolean] see Base.from_string
|
45
51
|
# @return [IPAddr, Nil]
|
46
|
-
def self.from(address)
|
52
|
+
def self.from(address, exception: false, classful: false)
|
47
53
|
case address
|
48
54
|
when IPAddr
|
49
55
|
specialize address
|
50
56
|
when Regex::IPV4, 0..V4::MAX_INT
|
51
|
-
V4[address]
|
57
|
+
V4[address, classful: classful]
|
52
58
|
when Regex::IPV6, 0..V6::MAX_INT
|
53
59
|
V6[address]
|
54
|
-
end
|
60
|
+
end || (
|
61
|
+
if exception
|
62
|
+
raise TypeError, "can't convert #{address.inspect} to #{self}"
|
63
|
+
end
|
64
|
+
)
|
55
65
|
end
|
56
66
|
|
57
67
|
# Create an IPAddr host subclass from the given object, guessing the type of
|
@@ -59,12 +69,16 @@ class IPAddr
|
|
59
69
|
#
|
60
70
|
# Uses .from internally, so the same concerns apply, though the returned
|
61
71
|
# object is guaranteed to be of a Host class or nil.
|
72
|
+
#
|
73
|
+
# @param address [Integer, IPAddr, String]
|
74
|
+
# @param exception [Boolean] See IPAddr::Base.from
|
75
|
+
# @return [IPAddr::Host, Nil]
|
62
76
|
|
63
|
-
def self.host_from(address)
|
64
|
-
ip = from(address)
|
65
|
-
if ip.ipv4?
|
77
|
+
def self.host_from(address, exception: false)
|
78
|
+
ip = from(address, exception: exception)
|
79
|
+
if ip && ip.ipv4?
|
66
80
|
V4::Host[ip]
|
67
|
-
elsif ip.ipv6?
|
81
|
+
elsif ip && ip.ipv6?
|
68
82
|
V6::Host[ip]
|
69
83
|
end
|
70
84
|
end
|
@@ -95,12 +109,26 @@ class IPAddr
|
|
95
109
|
# @param address [String]
|
96
110
|
# @param mask [Integer, String] a netmask or prefix length
|
97
111
|
# @param family [Integer, Nil]
|
112
|
+
# @param classful [Boolean] controls the conversion of IPv4 addresses
|
113
|
+
# without a prefix length in CIDR notation. When false, these are assumed
|
114
|
+
# to be host networks (/32). When true, these are assumed to be classful
|
115
|
+
# (rfc791) networks, with an implicit prefix length. Has no effect on IPv6
|
116
|
+
# addresses.
|
98
117
|
# @return [IPAddr]
|
99
|
-
def self.from_string(
|
118
|
+
def self.from_string(
|
119
|
+
address,
|
120
|
+
mask = nil,
|
121
|
+
family: self::FAMILY,
|
122
|
+
classful: false
|
123
|
+
)
|
100
124
|
if mask
|
101
125
|
new(address, family).mask(mask)
|
102
|
-
|
126
|
+
elsif !classful || address.include?('/')
|
103
127
|
new(address, family)
|
128
|
+
else
|
129
|
+
ipaddr = new(address, family)
|
130
|
+
return ipaddr unless ipaddr.ipv4?
|
131
|
+
ipaddr.classful || ipaddr
|
104
132
|
end
|
105
133
|
end
|
106
134
|
|
@@ -230,26 +258,65 @@ class IPAddr
|
|
230
258
|
end
|
231
259
|
end
|
232
260
|
|
261
|
+
# An IPv4 address, 32 bits
|
233
262
|
class V4 < Base
|
234
263
|
specialize_constants Family::IPV4
|
235
264
|
|
236
265
|
REGEX = Regex::IPV4
|
237
266
|
|
267
|
+
NETWORK_CLASSES = {
|
268
|
+
new('0.0.0.0/1') => 8, # A
|
269
|
+
new('128.0.0.0/2') => 16, # B
|
270
|
+
new('192.0.0.0/3') => 24 # C
|
271
|
+
}.freeze
|
272
|
+
|
273
|
+
# If the address falls in one of the address classes defined in rfc791,
|
274
|
+
# return a new IPAddr with the appropriate prefix length, otherwise return
|
275
|
+
# nil.
|
276
|
+
#
|
277
|
+
# * Class A: networks of 16,777,216 addresses each,
|
278
|
+
# from 0.0.0.0/8 to 127.0.0.0/8
|
279
|
+
# * Class B: networks of 65,537 addresses each,
|
280
|
+
# from 128.0.0.0/16 to 191.255.0.0/16
|
281
|
+
# * Class C: networks of 256 addresses each,
|
282
|
+
# from 192.0.0.0/24 to 223.255.255.0/24
|
283
|
+
#
|
284
|
+
# @return [IPAddr::V4, nil]
|
285
|
+
def classful
|
286
|
+
prefix_length = classful_prefix_length || return
|
287
|
+
mask(prefix_length)
|
288
|
+
end
|
289
|
+
|
290
|
+
# If the address falls in one of the address classes defined in rfc791,
|
291
|
+
# return the corresponding prefix length, otherwise return nil.
|
292
|
+
#
|
293
|
+
# @return [Integer, nil]
|
294
|
+
def classful_prefix_length
|
295
|
+
key = NETWORK_CLASSES.keys.find do |block|
|
296
|
+
block.to_range(&:to_i).cover?(to_i)
|
297
|
+
end
|
298
|
+
NETWORK_CLASSES[key]
|
299
|
+
end
|
300
|
+
|
301
|
+
# An IPv4 host address, 32 bits
|
238
302
|
class Host < V4
|
239
303
|
include BetterIpaddr::HostMethods
|
240
304
|
end
|
241
305
|
end
|
242
306
|
|
307
|
+
# An IPv6 address, 128 bits
|
243
308
|
class V6 < Base
|
244
309
|
specialize_constants Family::IPV6
|
245
310
|
|
246
311
|
REGEX = Regex::IPV6
|
247
312
|
|
313
|
+
# An IPv6 host address, 128 bits
|
248
314
|
class Host < V6
|
249
315
|
include BetterIpaddr::HostMethods
|
250
316
|
end
|
251
317
|
end
|
252
318
|
|
319
|
+
# A MAC address, 48 bits
|
253
320
|
class MAC < Base
|
254
321
|
specialize_constants Family::EUI48
|
255
322
|
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
require "socket"
|
2
2
|
|
3
3
|
module BetterIpaddr
|
4
|
+
# Namespace for constants used by BetterIpaddr
|
4
5
|
module Constants
|
5
6
|
# Integer codes representing supported address clases.
|
6
7
|
# Reuse values from Socket namespace where possible.
|
@@ -28,7 +29,7 @@ module BetterIpaddr
|
|
28
29
|
/[0-9]/
|
29
30
|
)
|
30
31
|
|
31
|
-
IPV4 =
|
32
|
+
IPV4 = %r{\A#{OCTET}#{TRAILING_OCTET}{3}(?:\/#{IPV4_PL})?\z}
|
32
33
|
|
33
34
|
# IPv6 regex adapted from http://stackoverflow.com/a/17871737
|
34
35
|
QUAD = /[0-9a-zA-Z]{1,4}/
|
@@ -64,7 +65,7 @@ module BetterIpaddr
|
|
64
65
|
/#{LEADING_QUAD}{1,4}:#{IPV4}/
|
65
66
|
)
|
66
67
|
|
67
|
-
IPV6 =
|
68
|
+
IPV6 = %r{\A#{IPV6_ADDRESS}(?:\/#{IPV6_PL})?\z}
|
68
69
|
end
|
69
70
|
|
70
71
|
# Map well known address family names to constants.
|
@@ -74,7 +75,7 @@ module BetterIpaddr
|
|
74
75
|
eui48: Family::EUI48,
|
75
76
|
eui64: Family::EUI64,
|
76
77
|
mac: Family::EUI48
|
77
|
-
}
|
78
|
+
}.freeze
|
78
79
|
|
79
80
|
# Map each address family to the size of its address space, in bits.
|
80
81
|
FAMILY_TO_BIT_LENGTH = {
|
@@ -82,7 +83,7 @@ module BetterIpaddr
|
|
82
83
|
Family::IPV6 => 128,
|
83
84
|
Family::EUI48 => 48,
|
84
85
|
Family::EUI64 => 64
|
85
|
-
}
|
86
|
+
}.freeze
|
86
87
|
|
87
88
|
# Map all possible prefix lengths to the corresponding netmasks.
|
88
89
|
PREFIX_LENGTH_TO_NETMASK = {}
|
@@ -93,6 +94,7 @@ module BetterIpaddr
|
|
93
94
|
end
|
94
95
|
PREFIX_LENGTH_TO_NETMASK[family] = netmasks
|
95
96
|
end
|
97
|
+
PREFIX_LENGTH_TO_NETMASK.freeze
|
96
98
|
|
97
99
|
# Map all possible netmasks to the corresponding prefix lengths.
|
98
100
|
NETMASK_TO_PREFIX_LENGTH = {}
|
@@ -100,5 +102,6 @@ module BetterIpaddr
|
|
100
102
|
NETMASK_TO_PREFIX_LENGTH[family] =
|
101
103
|
Hash[hash.map.with_index { |e, i| [e, i] }]
|
102
104
|
end
|
105
|
+
NETMASK_TO_PREFIX_LENGTH.freeze
|
103
106
|
end
|
104
107
|
end
|
@@ -1,13 +1,38 @@
|
|
1
1
|
require "better_ipaddr/classes"
|
2
2
|
|
3
3
|
module Kernel
|
4
|
-
|
5
|
-
|
4
|
+
# @see IPAddr::Base.from
|
5
|
+
def IPAddr(object, exception: false, classful: false)
|
6
|
+
IPAddr::Base.from(object, exception: exception, classful: classful)
|
6
7
|
end
|
7
8
|
end
|
8
9
|
|
9
10
|
class IPAddr
|
10
|
-
|
11
|
-
|
11
|
+
# @see IPAddr::Base.host_from
|
12
|
+
def self.Host(object, exception: false)
|
13
|
+
Base.host_from(object, exception: exception)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
module BetterIpaddr
|
18
|
+
module InstanceMethods
|
19
|
+
# Emits a snippet of ruby code that can be copied and pasted. Uses the
|
20
|
+
# string representation of the address, by default in CIDR notation, instead
|
21
|
+
# of the harder-to-read mask notation.
|
22
|
+
#
|
23
|
+
# @return String
|
24
|
+
def inspect(cidr: true, full: false)
|
25
|
+
"#{self.class}['#{better_to_s(cidr: cidr, full: full)}']"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
module HostMethods
|
30
|
+
# Same as BetterIpaddr::InstanceMethods#inspect but doesn't by default
|
31
|
+
# include the CIDR prefix length.
|
32
|
+
#
|
33
|
+
# @return String
|
34
|
+
def inspect(cidr: false, full: false)
|
35
|
+
"#{self.class}['#{better_to_s(cidr: cidr, full: full)}']"
|
36
|
+
end
|
12
37
|
end
|
13
38
|
end
|
@@ -2,46 +2,7 @@ require "ipaddr"
|
|
2
2
|
require "better_ipaddr/constants"
|
3
3
|
|
4
4
|
module BetterIpaddr
|
5
|
-
|
6
|
-
include Constants
|
7
|
-
|
8
|
-
# @overload [](address, family)
|
9
|
-
# @param address [Integer] the integer representation of the address
|
10
|
-
# @param family [Symbol] a symbol named for the address's
|
11
|
-
# address family, one of +:ipv4+, +:ipv6+, or +:mac+.
|
12
|
-
# @return [IPAddr]
|
13
|
-
# Wrapper for IPAddr.new that accepts a symbolic family name and
|
14
|
-
# returns a specialized IPAddr subclass.
|
15
|
-
#
|
16
|
-
# @overload [](address, family)
|
17
|
-
# @param address [Integer] the integer representation of the address
|
18
|
-
# @param family [Integer] the magic number representing the address's
|
19
|
-
# address family.
|
20
|
-
# @return [IPAddr]
|
21
|
-
# Wrapper for IPAddr.new that accepts a symbolic family name and
|
22
|
-
# returns a specialized IPAddr subclass.
|
23
|
-
#
|
24
|
-
# @overload [](address)
|
25
|
-
# @param address [String] the string representation of the address
|
26
|
-
# @return [IPAddr]
|
27
|
-
# Wrapper for IPAddr.new that accepts the string representation
|
28
|
-
# of an address returns a specialized IPAddr subclass.
|
29
|
-
|
30
|
-
def [](address, family = nil)
|
31
|
-
instance = case family
|
32
|
-
when Symbol
|
33
|
-
self[address, SYMBOL_TO_FAMILY.fetch(family)]
|
34
|
-
when IPAddr
|
35
|
-
address
|
36
|
-
when nil
|
37
|
-
new(address)
|
38
|
-
else
|
39
|
-
new(address, family)
|
40
|
-
end
|
41
|
-
IPAddr::Base.specialize(instance)
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
5
|
+
# Methods included in IPAddr::Base and its descendants
|
45
6
|
module InstanceMethods
|
46
7
|
include Constants
|
47
8
|
|
@@ -85,7 +46,7 @@ module BetterIpaddr
|
|
85
46
|
# @return [IPAddr]
|
86
47
|
|
87
48
|
def -(offset)
|
88
|
-
self +
|
49
|
+
self + -offset
|
89
50
|
end
|
90
51
|
|
91
52
|
# @overload <=>(other)
|
@@ -105,7 +66,7 @@ module BetterIpaddr
|
|
105
66
|
family_difference = family <=> other.family
|
106
67
|
return family_difference unless family_difference == 0
|
107
68
|
elsif !other.is_a?(Integer)
|
108
|
-
|
69
|
+
return nil
|
109
70
|
end
|
110
71
|
|
111
72
|
address_difference = to_i <=> other.to_i
|
@@ -137,7 +98,7 @@ module BetterIpaddr
|
|
137
98
|
# @return [IPAddr] the address at the given index
|
138
99
|
|
139
100
|
def [](offset)
|
140
|
-
return self if offset
|
101
|
+
return self if offset == 0 && host?
|
141
102
|
offset2 = offset >= 0 ? offset : size + offset
|
142
103
|
self.class[to_i + offset2, family: family]
|
143
104
|
end
|
@@ -256,6 +217,7 @@ module BetterIpaddr
|
|
256
217
|
NETMASK_TO_PREFIX_LENGTH[family][mask_addr]
|
257
218
|
end
|
258
219
|
|
220
|
+
alias_method :prefix, :prefix_length unless 1.respond_to?(:positive?)
|
259
221
|
alias_method :prefixlen, :prefix_length
|
260
222
|
|
261
223
|
# Return a new address with the prefix length increased by the
|
data/lib/better_ipaddr/space.rb
CHANGED
@@ -2,6 +2,7 @@ require "ipaddr"
|
|
2
2
|
require "better_ipaddr/classes"
|
3
3
|
|
4
4
|
module BetterIpaddr
|
5
|
+
# Address space utilities
|
5
6
|
class Space
|
6
7
|
include Enumerable
|
7
8
|
|
@@ -14,8 +15,8 @@ module BetterIpaddr
|
|
14
15
|
@space = space
|
15
16
|
outlier = @networks.find { |net| !@space.cover?(net) }
|
16
17
|
return unless outlier
|
17
|
-
|
18
|
-
|
18
|
+
raise ArgumentError, "Address space #{@space.inspect} does not cover "\
|
19
|
+
"network #{outlier.inspect}"
|
19
20
|
end
|
20
21
|
|
21
22
|
def +(other)
|
@@ -96,7 +97,7 @@ module BetterIpaddr
|
|
96
97
|
def infer_address_family(*networks)
|
97
98
|
example = networks.find { |net| net.respond_to?(:family) }
|
98
99
|
return example.family if example
|
99
|
-
|
100
|
+
raise "Unable to infer address family"
|
100
101
|
end
|
101
102
|
|
102
103
|
def export(new_networks, space: nil)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: better_ipaddr
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ben Miller
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2018-08-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -24,6 +24,34 @@ dependencies:
|
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '1.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: ipaddr
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 1.2.0
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 1.2.0
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: minitest
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '5.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '5.0'
|
27
55
|
- !ruby/object:Gem::Dependency
|
28
56
|
name: rake
|
29
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -39,19 +67,33 @@ dependencies:
|
|
39
67
|
- !ruby/object:Gem::Version
|
40
68
|
version: '10.0'
|
41
69
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
70
|
+
name: rubocop
|
43
71
|
requirement: !ruby/object:Gem::Requirement
|
44
72
|
requirements:
|
45
73
|
- - "~>"
|
46
74
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
75
|
+
version: '0.54'
|
48
76
|
type: :development
|
49
77
|
prerelease: false
|
50
78
|
version_requirements: !ruby/object:Gem::Requirement
|
51
79
|
requirements:
|
52
80
|
- - "~>"
|
53
81
|
- !ruby/object:Gem::Version
|
54
|
-
version: '
|
82
|
+
version: '0.54'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: test-unit
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
55
97
|
description:
|
56
98
|
email:
|
57
99
|
- bmiller@rackspace.com
|
@@ -60,6 +102,7 @@ extensions: []
|
|
60
102
|
extra_rdoc_files: []
|
61
103
|
files:
|
62
104
|
- ".gitignore"
|
105
|
+
- ".rubocop.yml"
|
63
106
|
- ".travis.yml"
|
64
107
|
- CODE_OF_CONDUCT.md
|
65
108
|
- Gemfile
|
@@ -98,7 +141,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
98
141
|
version: '0'
|
99
142
|
requirements: []
|
100
143
|
rubyforge_project:
|
101
|
-
rubygems_version: 2.
|
144
|
+
rubygems_version: 2.7.3
|
102
145
|
signing_key:
|
103
146
|
specification_version: 4
|
104
147
|
summary: IPAddr enhancements for network management.
|