better_ipaddr 0.2.3 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +2 -0
- data/lib/better_ipaddr/classes.rb +29 -4
- data/lib/better_ipaddr/constants.rb +103 -0
- data/lib/better_ipaddr/kernel_method.rb +7 -0
- data/lib/better_ipaddr/methods.rb +1 -46
- data/lib/better_ipaddr/version.rb +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 77e832f6c7d7f6dc51281e3a00dbc4ac43c582c7
|
4
|
+
data.tar.gz: 57d339efecf6b8d195faf516438e9dbe6df63a6f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: feded15fc34a564ddbab41eb3d1d0306b20ffd53125e2fd259be970b3dd034b7d6ae34056f71b985635e64020b508aae5fea82a5a606e9affee552c178cf115c
|
7
|
+
data.tar.gz: cf706c0395daef99367fad7dbdd70b6fbf701f4f33f740845556c66b5f7b876ecfd324ca601127809904c52d82d8fd79c71662144e6c41fc30230ec1e6ba2c57
|
data/README.md
CHANGED
@@ -90,6 +90,8 @@ Another way is to `require "better_ipaddr/methods"` and mix
|
|
90
90
|
`BetterIpaddr::InstanceMethods` into your own class which implements
|
91
91
|
the rest of the `IPAddr` API, or into individual `IPAddr` objects.
|
92
92
|
|
93
|
+
The `Kernel#IPAddr` conversion method (in the spirit of `Kernel#Array`, `Kernel#Integer`, etc), is added to `Kernel` via `require "better_ipaddr/kernel_method"`. It delegates to `IPAddr::Base.from`.
|
94
|
+
|
93
95
|
`BetterIpaddr::Space`, a collection class for dealing with sets of network addresses, is also available but not loaded by default.
|
94
96
|
|
95
97
|
```ruby
|
@@ -1,3 +1,4 @@
|
|
1
|
+
require "better_ipaddr/constants"
|
1
2
|
require "better_ipaddr/methods"
|
2
3
|
|
3
4
|
class IPAddr
|
@@ -7,10 +8,6 @@ class IPAddr
|
|
7
8
|
include Comparable
|
8
9
|
include Enumerable
|
9
10
|
|
10
|
-
def inherited(cls)
|
11
|
-
cls.extend BetterIpaddr::ClassMethods
|
12
|
-
end
|
13
|
-
|
14
11
|
# Create an IPAddr from the given object.
|
15
12
|
#
|
16
13
|
# Returns nil if the object is of a type that can't be converted to an
|
@@ -33,6 +30,29 @@ class IPAddr
|
|
33
30
|
end
|
34
31
|
end
|
35
32
|
|
33
|
+
# Create an IPAddr from the given object, guessing the type of address given
|
34
|
+
# based on its type and content.
|
35
|
+
#
|
36
|
+
# Note that an Integer that corresponds to an IPv4 address will be converted
|
37
|
+
# to an IPAddr::V4, even though all such Integers also correspond to valid
|
38
|
+
# IPv6 addresses.
|
39
|
+
#
|
40
|
+
# Returns nil if the object can't be converted based on its type and
|
41
|
+
# content.
|
42
|
+
#
|
43
|
+
# @param address [Integer, IPAddr, String]
|
44
|
+
# @return [IPAddr, Nil]
|
45
|
+
def self.from(address)
|
46
|
+
case address
|
47
|
+
when IPAddr
|
48
|
+
specialize address
|
49
|
+
when Regex::IPV4, 0..V4::MAX_INT
|
50
|
+
V4[address]
|
51
|
+
when Regex::IPV6, 0..V6::MAX_INT
|
52
|
+
V6[address]
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
36
56
|
# Create an IPAddr from an Integer.
|
37
57
|
#
|
38
58
|
# @param address [Integer]
|
@@ -172,6 +192,7 @@ class IPAddr
|
|
172
192
|
NETMASK_TO_PREFIX_LENGTH.fetch(self::FAMILY))
|
173
193
|
const_set(:PREFIX_LENGTH_TO_NETMASK,
|
174
194
|
PREFIX_LENGTH_TO_NETMASK.fetch(self::FAMILY))
|
195
|
+
const_set(:MAX_INT, 2**self::BIT_LENGTH - 1)
|
175
196
|
end
|
176
197
|
|
177
198
|
def address_family_bit_length
|
@@ -189,10 +210,14 @@ class IPAddr
|
|
189
210
|
|
190
211
|
class V4 < Base
|
191
212
|
specialize_constants Family::IPV4
|
213
|
+
|
214
|
+
REGEX = Regex::IPV4
|
192
215
|
end
|
193
216
|
|
194
217
|
class V6 < Base
|
195
218
|
specialize_constants Family::IPV6
|
219
|
+
|
220
|
+
REGEX = Regex::IPV6
|
196
221
|
end
|
197
222
|
|
198
223
|
class MAC < Base
|
@@ -0,0 +1,103 @@
|
|
1
|
+
require "socket"
|
2
|
+
|
3
|
+
module BetterIpaddr
|
4
|
+
module Constants
|
5
|
+
# Integer codes representing supported address clases.
|
6
|
+
# Reuse values from Socket namespace where possible.
|
7
|
+
module Family
|
8
|
+
IPV4 = Socket::AF_INET
|
9
|
+
IPV6 = Socket::AF_INET6
|
10
|
+
EUI48 = 48
|
11
|
+
EUI64 = 64
|
12
|
+
end
|
13
|
+
|
14
|
+
module Regex
|
15
|
+
OCTET = Regexp.union(
|
16
|
+
/25[0-5]/,
|
17
|
+
/2[0-4][0-9]/,
|
18
|
+
/1[0-9][0-9]/,
|
19
|
+
/[1-9][0-9]/,
|
20
|
+
/[0-9]/
|
21
|
+
)
|
22
|
+
|
23
|
+
TRAILING_OCTET = /\.#{OCTET}/
|
24
|
+
|
25
|
+
IPV4_PL = Regexp.union(
|
26
|
+
/3[0-2]/,
|
27
|
+
/[1-2][0-9]/,
|
28
|
+
/[0-9]/
|
29
|
+
)
|
30
|
+
|
31
|
+
IPV4 = /\A#{OCTET}#{TRAILING_OCTET}{3}(?:\/#{IPV4_PL})?\z/
|
32
|
+
|
33
|
+
# IPv6 regex adapted from http://stackoverflow.com/a/17871737
|
34
|
+
QUAD = /[0-9a-zA-Z]{1,4}/
|
35
|
+
LEADING_QUAD = /[0-9a-zA-Z]{1,4}:/
|
36
|
+
TRAILING_QUAD = /:[0-9a-zA-Z]{1,4}/
|
37
|
+
|
38
|
+
IPV6_PL = Regexp.union(
|
39
|
+
/[0-9]/,
|
40
|
+
/[1-9][0-9]/,
|
41
|
+
/1[0-1][0-9]/,
|
42
|
+
/12[0-8]/
|
43
|
+
)
|
44
|
+
|
45
|
+
IPV6_ADDRESS = Regexp.union(
|
46
|
+
# full
|
47
|
+
/#{LEADING_QUAD}{7,7}#{QUAD}/,
|
48
|
+
|
49
|
+
# zero-compressed
|
50
|
+
/#{LEADING_QUAD}{1,7}:/,
|
51
|
+
/:#{TRAILING_QUAD}{1,7}/,
|
52
|
+
/#{LEADING_QUAD}{1,6}#{TRAILING_QUAD}{1,1}/,
|
53
|
+
/#{LEADING_QUAD}{1,5}#{TRAILING_QUAD}{1,2}/,
|
54
|
+
/#{LEADING_QUAD}{1,4}#{TRAILING_QUAD}{1,3}/,
|
55
|
+
/#{LEADING_QUAD}{1,3}#{TRAILING_QUAD}{1,4}/,
|
56
|
+
/#{LEADING_QUAD}{1,2}#{TRAILING_QUAD}{1,5}/,
|
57
|
+
/#{LEADING_QUAD}{1,1}#{TRAILING_QUAD}{1,6}}/,
|
58
|
+
|
59
|
+
# IPv4-mapped / -translated
|
60
|
+
/::(ffff(:0{1,4}){0,1}:){0,1}#{IPV4}/,
|
61
|
+
|
62
|
+
# IPv4 embedded
|
63
|
+
/#{LEADING_QUAD}{1,4}:#{IPV4}/
|
64
|
+
)
|
65
|
+
|
66
|
+
IPV6 = /\A#{IPV6_ADDRESS}(?:\/#{IPV6_PL})?\z/
|
67
|
+
end
|
68
|
+
|
69
|
+
# Map well known address family names to constants.
|
70
|
+
SYMBOL_TO_FAMILY = {
|
71
|
+
ipv4: Family::IPV4,
|
72
|
+
ipv6: Family::IPV6,
|
73
|
+
eui48: Family::EUI48,
|
74
|
+
eui64: Family::EUI64,
|
75
|
+
mac: Family::EUI48
|
76
|
+
}
|
77
|
+
|
78
|
+
# Map each address family to the size of its address space, in bits.
|
79
|
+
FAMILY_TO_BIT_LENGTH = {
|
80
|
+
Family::IPV4 => 32,
|
81
|
+
Family::IPV6 => 128,
|
82
|
+
Family::EUI48 => 48,
|
83
|
+
Family::EUI64 => 64
|
84
|
+
}
|
85
|
+
|
86
|
+
# Map all possible prefix lengths to the corresponding netmasks.
|
87
|
+
PREFIX_LENGTH_TO_NETMASK = {}
|
88
|
+
FAMILY_TO_BIT_LENGTH.each_pair do |family, size|
|
89
|
+
netmasks = []
|
90
|
+
(0..size).each do |prefix_length|
|
91
|
+
netmasks[prefix_length] = 2**size - 2**(size - prefix_length)
|
92
|
+
end
|
93
|
+
PREFIX_LENGTH_TO_NETMASK[family] = netmasks
|
94
|
+
end
|
95
|
+
|
96
|
+
# Map all possible netmasks to the corresponding prefix lengths.
|
97
|
+
NETMASK_TO_PREFIX_LENGTH = {}
|
98
|
+
PREFIX_LENGTH_TO_NETMASK.each_pair do |family, hash|
|
99
|
+
NETMASK_TO_PREFIX_LENGTH[family] =
|
100
|
+
Hash[hash.map.with_index { |e, i| [e, i] }]
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
@@ -1,52 +1,7 @@
|
|
1
1
|
require "ipaddr"
|
2
|
-
require "
|
2
|
+
require "better_ipaddr/constants"
|
3
3
|
|
4
4
|
module BetterIpaddr
|
5
|
-
module Constants
|
6
|
-
# Integer codes representing supported address clases.
|
7
|
-
# Reuse values from Socket namespace where possible.
|
8
|
-
module Family
|
9
|
-
IPV4 = Socket::AF_INET
|
10
|
-
IPV6 = Socket::AF_INET6
|
11
|
-
EUI48 = 48
|
12
|
-
EUI64 = 64
|
13
|
-
end
|
14
|
-
|
15
|
-
# Map well known address family names to constants.
|
16
|
-
SYMBOL_TO_FAMILY = {
|
17
|
-
ipv4: Family::IPV4,
|
18
|
-
ipv6: Family::IPV6,
|
19
|
-
eui48: Family::EUI48,
|
20
|
-
eui64: Family::EUI64,
|
21
|
-
mac: Family::EUI48
|
22
|
-
}
|
23
|
-
|
24
|
-
# Map each address family to the size of its address space, in bits.
|
25
|
-
FAMILY_TO_BIT_LENGTH = {
|
26
|
-
Family::IPV4 => 32,
|
27
|
-
Family::IPV6 => 128,
|
28
|
-
Family::EUI48 => 48,
|
29
|
-
Family::EUI64 => 64
|
30
|
-
}
|
31
|
-
|
32
|
-
# Map all possible prefix lengths to the corresponding netmasks.
|
33
|
-
PREFIX_LENGTH_TO_NETMASK = {}
|
34
|
-
FAMILY_TO_BIT_LENGTH.each_pair do |family, size|
|
35
|
-
netmasks = []
|
36
|
-
(0..size).each do |prefix_length|
|
37
|
-
netmasks[prefix_length] = 2**size - 2**(size - prefix_length)
|
38
|
-
end
|
39
|
-
PREFIX_LENGTH_TO_NETMASK[family] = netmasks
|
40
|
-
end
|
41
|
-
|
42
|
-
# Map all possible netmasks to the corresponding prefix lengths.
|
43
|
-
NETMASK_TO_PREFIX_LENGTH = {}
|
44
|
-
PREFIX_LENGTH_TO_NETMASK.each_pair do |family, hash|
|
45
|
-
NETMASK_TO_PREFIX_LENGTH[family] =
|
46
|
-
Hash[hash.map.with_index { |e, i| [e, i] }]
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
5
|
module ClassMethods
|
51
6
|
include Constants
|
52
7
|
|
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.3.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: 2016-
|
11
|
+
date: 2016-11-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -71,7 +71,9 @@ files:
|
|
71
71
|
- bin/setup
|
72
72
|
- lib/better_ipaddr.rb
|
73
73
|
- lib/better_ipaddr/classes.rb
|
74
|
+
- lib/better_ipaddr/constants.rb
|
74
75
|
- lib/better_ipaddr/core_extension.rb
|
76
|
+
- lib/better_ipaddr/kernel_method.rb
|
75
77
|
- lib/better_ipaddr/methods.rb
|
76
78
|
- lib/better_ipaddr/space.rb
|
77
79
|
- lib/better_ipaddr/version.rb
|