ruby-ip 0.9.1 → 0.9.3
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 +7 -0
- data/README.rdoc +19 -0
- data/lib/ip/base.rb +80 -6
- data/test/ip_test.rb +65 -1
- metadata +20 -39
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 97b94276cb0106a57dda469aa8d5ac6b930c6c48
|
4
|
+
data.tar.gz: 1597755efb6569844d8b0d659f9b836a155eaf99
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 68be79249a2c3e1bdca7574e7c2006b6d6dc503fedb408a71da4eedfd765ef65d0feb08ee1b5c893f2e073a29060d3d040395f48744730368bc7c041a7c8c9ea
|
7
|
+
data.tar.gz: f25236b45eb5a3fad698935032ed79c1e490dc7a91512a7b3fbcb789b711f31d40cda38788b59afc15d045b1f0de5778d1715b6c0ed00521a88b4d1d052e608a
|
data/README.rdoc
CHANGED
@@ -16,8 +16,10 @@ Docs:: http://deploy2.github.com/ruby-ip/
|
|
16
16
|
ip = IP.new("192.0.2.53/24")
|
17
17
|
ip.to_s # "192.0.2.53/24"
|
18
18
|
ip.to_i # 3221226037
|
19
|
+
ip.to_b # 11000000000000000000001000110101
|
19
20
|
ip.to_hex # "c0000235"
|
20
21
|
ip.to_addr # "192.0.2.53"
|
22
|
+
ip.to_arpa # "53.2.0.192.in-addr.arpa."
|
21
23
|
ip.pfxlen # 24
|
22
24
|
|
23
25
|
* Qualify IP address with "routing context" (VRF)
|
@@ -67,6 +69,23 @@ Docs:: http://deploy2.github.com/ruby-ip/
|
|
67
69
|
ip ^ 7 #<IP::V4 192.0.2.50/24>
|
68
70
|
~ip #<IP::V4 63.255.253.202/24>
|
69
71
|
|
72
|
+
* Advanced Subnet Operations
|
73
|
+
sn = IP.new('192.168.0.0/24')
|
74
|
+
ip = IP.new('192.168.0.48/32')
|
75
|
+
sn.split [#<IP::V4 192.168.0.0/25>,
|
76
|
+
#<IP::V4 192.168.0.128/25>] (2 evenly divided subnets)
|
77
|
+
sn.divide_by_subnets(3) [#<IP::V4 192.168.0.0/26>,
|
78
|
+
#<IP::V4 192.168.0.64/26>,
|
79
|
+
#<IP::V4 192.168.0.128/26>,
|
80
|
+
#<IP::V4 192.168.0.192/26>] (4 evenly divided subnets)
|
81
|
+
#keep in mind this always takes into account a network and broadcast address
|
82
|
+
sn.divide_by_hosts(100) [#<IP::V4 192.168.0.0/25>,
|
83
|
+
#<IP::V4 192.168.0.128/25>] (128 hosts each)
|
84
|
+
ip = IP.new('192.168.0.48/32')
|
85
|
+
ip.is_in?(sn)
|
86
|
+
=> true
|
87
|
+
|
88
|
+
|
70
89
|
* Convert to and from a compact Array representation
|
71
90
|
|
72
91
|
ip1 = IP.new("192.0.2.53/24@cust1")
|
data/lib/ip/base.rb
CHANGED
@@ -76,7 +76,10 @@ class IP
|
|
76
76
|
def to_i
|
77
77
|
@addr
|
78
78
|
end
|
79
|
-
|
79
|
+
# returns the address in Binary
|
80
|
+
def to_b
|
81
|
+
@addr.to_s(2).to_i
|
82
|
+
end
|
80
83
|
# Return the address as a hexadecimal string (8 or 32 digits)
|
81
84
|
def to_hex
|
82
85
|
@addr.to_s(16).rjust(self.class::ADDR_BITS>>2,"0")
|
@@ -187,6 +190,55 @@ class IP
|
|
187
190
|
self.class.new(@addr & ~mask, self.class::ADDR_BITS, @ctx) ..
|
188
191
|
self.class.new(@addr | mask, self.class::ADDR_BITS, @ctx)
|
189
192
|
end
|
193
|
+
# test if the address is in the provided subnet
|
194
|
+
def is_in?(subnet)
|
195
|
+
return subnet.network.to_i <= self.network.to_i &&
|
196
|
+
subnet.broadcast.to_i >= self.broadcast.to_i
|
197
|
+
end
|
198
|
+
#this function sub-divides a subnet into two subnets of equal size
|
199
|
+
def split
|
200
|
+
nets = Array.new
|
201
|
+
if self.pfxlen < self.class::ADDR_BITS
|
202
|
+
if self.class::ADDR_BITS == 32
|
203
|
+
new_base = IP::V4.new(self.network.to_i, (self.pfxlen + 1))
|
204
|
+
nets = [new_base, IP::V4.new((new_base.broadcast + 1).to_i, (self.pfxlen + 1))]
|
205
|
+
end
|
206
|
+
if self.class::ADDR_BITS == 128
|
207
|
+
new_base = IP::V6.new(self.network.to_i, (self.pfxlen + 1))
|
208
|
+
nets = [new_base, IP::V6.new((new_base.broadcast + 1).to_i, (self.pfxlen + 1))]
|
209
|
+
end
|
210
|
+
end
|
211
|
+
return nets
|
212
|
+
end
|
213
|
+
|
214
|
+
# subdivide a larger subnet into smaller subnets by number of subnets of equal size,
|
215
|
+
# stop when subnets reach their smallest possible size (i.e. 31 for IP4)
|
216
|
+
def divide_by_subnets(number_subnets)
|
217
|
+
nets = Array.new
|
218
|
+
nets << self
|
219
|
+
begin
|
220
|
+
new_nets = Array.new
|
221
|
+
nets.each do |net|
|
222
|
+
new_nets = new_nets | net.split
|
223
|
+
end
|
224
|
+
nets = new_nets
|
225
|
+
end until number_subnets <= nets.length && nets[0].pfxlen <= (self.class::ADDR_BITS - 1)
|
226
|
+
return nets
|
227
|
+
end
|
228
|
+
|
229
|
+
# subdivide a larger subnet into smaller subnets by number of hosts
|
230
|
+
def divide_by_hosts(number_hosts)
|
231
|
+
nets = Array.new
|
232
|
+
nets << self
|
233
|
+
while number_hosts <= (nets[0].split[0].size - 2) && nets[0].pfxlen <= (self.class::ADDR_BITS - 1)
|
234
|
+
new_nets = Array.new
|
235
|
+
nets.each do |net|
|
236
|
+
new_nets = new_nets | net.split
|
237
|
+
end
|
238
|
+
nets = new_nets
|
239
|
+
end
|
240
|
+
return nets
|
241
|
+
end
|
190
242
|
|
191
243
|
# The number of IP addresses in subnet
|
192
244
|
# IP.new("1.2.3.4/24").size => 256
|
@@ -195,23 +247,23 @@ class IP
|
|
195
247
|
end
|
196
248
|
|
197
249
|
def +(other)
|
198
|
-
self.class.new(@addr + other.
|
250
|
+
self.class.new(@addr + other.to_i, @pfxlen, @ctx)
|
199
251
|
end
|
200
252
|
|
201
253
|
def -(other)
|
202
|
-
self.class.new(@addr - other.
|
254
|
+
self.class.new(@addr - other.to_i, @pfxlen, @ctx)
|
203
255
|
end
|
204
256
|
|
205
257
|
def &(other)
|
206
|
-
self.class.new(@addr & other.
|
258
|
+
self.class.new(@addr & other.to_i, @pfxlen, @ctx)
|
207
259
|
end
|
208
260
|
|
209
261
|
def |(other)
|
210
|
-
self.class.new(@addr | other.
|
262
|
+
self.class.new(@addr | other.to_i, @pfxlen, @ctx)
|
211
263
|
end
|
212
264
|
|
213
265
|
def ^(other)
|
214
|
-
self.class.new(@addr ^ other.
|
266
|
+
self.class.new(@addr ^ other.to_i, @pfxlen, @ctx)
|
215
267
|
end
|
216
268
|
|
217
269
|
def ~
|
@@ -286,6 +338,11 @@ class IP
|
|
286
338
|
sprintf("%d.%d.%d.%d",
|
287
339
|
(@addr>>24)&0xff, (@addr>>16)&0xff, (@addr>>8)&0xff, @addr&0xff)
|
288
340
|
end
|
341
|
+
#return the arpa version of the address for reverse DNS: http://en.wikipedia.org/wiki/Reverse_DNS_lookup
|
342
|
+
def to_arpa
|
343
|
+
sprintf("%d.%d.%d.%d.in-addr.arpa.",
|
344
|
+
@addr&0xff, (@addr>>8)&0xff, (@addr>>16)&0xff,(@addr>>24)&0xff)
|
345
|
+
end
|
289
346
|
end
|
290
347
|
|
291
348
|
class V6 < IP
|
@@ -357,6 +414,23 @@ class IP
|
|
357
414
|
end
|
358
415
|
end
|
359
416
|
|
417
|
+
# Return just the address in non-compact form, required for reverse IP.
|
418
|
+
def to_addr_full
|
419
|
+
if ipv4_compat?
|
420
|
+
"::#{native.to_addr}"
|
421
|
+
elsif ipv4_mapped?
|
422
|
+
"::ffff:#{native.to_addr}"
|
423
|
+
elsif @addr.zero?
|
424
|
+
"::"
|
425
|
+
else
|
426
|
+
return to_hex.scan(/..../).join(':')
|
427
|
+
end
|
428
|
+
end
|
429
|
+
#return the arpa version of the address for reverse DNS: http://en.wikipedia.org/wiki/Reverse_DNS_lookup
|
430
|
+
def to_arpa
|
431
|
+
return self.to_addr_full.reverse.gsub(':','').split(//).join('.') + ".ip6.arpa"
|
432
|
+
end
|
433
|
+
|
360
434
|
def ipv4_mapped?
|
361
435
|
(@addr >> 32) == 0xffff
|
362
436
|
end
|
data/test/ip_test.rb
CHANGED
@@ -9,6 +9,7 @@ class IPTest < Test::Unit::TestCase
|
|
9
9
|
assert_equal "1.2.3.4/26", res.to_s
|
10
10
|
assert_equal "1.2.3.4/26", res.to_addrlen
|
11
11
|
assert_equal 0x01020304, res.to_i
|
12
|
+
assert_equal 1000000100000001100000100, res.to_b
|
12
13
|
assert_equal 26, res.pfxlen
|
13
14
|
assert_nil res.ctx
|
14
15
|
end
|
@@ -75,7 +76,22 @@ class IPTest < Test::Unit::TestCase
|
|
75
76
|
should "disallow invalid pfxlen" do
|
76
77
|
assert_raises(ArgumentError) { IP.new("1.2.3.4/33") }
|
77
78
|
end
|
78
|
-
|
79
|
+
|
80
|
+
context "ip math" do
|
81
|
+
setup do
|
82
|
+
@addr1 = IP.new("1.2.3.4/24@foo")
|
83
|
+
@addr2 = IP.new("1.2.3.5/24@foo")
|
84
|
+
end
|
85
|
+
|
86
|
+
should "add to ip address" do
|
87
|
+
assert_equal @addr2, (@addr1 + 1)
|
88
|
+
end
|
89
|
+
|
90
|
+
should "subtract from ip address" do
|
91
|
+
assert_equal @addr1, (@addr2 - 1)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
79
95
|
context "address not on subnet boundary" do
|
80
96
|
setup do
|
81
97
|
@addr = IP.new("1.2.3.4/24@foo")
|
@@ -93,6 +109,10 @@ class IPTest < Test::Unit::TestCase
|
|
93
109
|
assert_equal "1.2.3.4", @addr.to_addr
|
94
110
|
end
|
95
111
|
|
112
|
+
should "have to_arpa" do
|
113
|
+
assert_equal "4.3.2.1.in-addr.arpa.", @addr.to_arpa
|
114
|
+
end
|
115
|
+
|
96
116
|
should "have to_i" do
|
97
117
|
assert_equal 0x01020304, @addr.to_i
|
98
118
|
end
|
@@ -128,6 +148,47 @@ class IPTest < Test::Unit::TestCase
|
|
128
148
|
should "have to_range" do
|
129
149
|
assert_equal IP.new("1.2.3.0@foo")..IP.new("1.2.3.255@foo"), @addr.to_range
|
130
150
|
end
|
151
|
+
|
152
|
+
should "have is_in?" do
|
153
|
+
assert_equal IP.new("1.2.3.0/25").is_in?(IP.new("1.2.3.0/24")), true
|
154
|
+
end
|
155
|
+
|
156
|
+
should "find whether an IP is included in a range" do
|
157
|
+
assert_equal IP.new("1.2.3.1").is_in?(IP.new("1.2.3.0/24")), true
|
158
|
+
end
|
159
|
+
|
160
|
+
should "find whether an IP is not included a range" do
|
161
|
+
assert_equal IP.new("1.2.4.1").is_in?(IP.new("1.2.3.0/24")), false
|
162
|
+
end
|
163
|
+
|
164
|
+
should "find when a subnet is included in a range" do
|
165
|
+
assert_equal IP.new("1.2.3.0/30").is_in?(IP.new("1.2.3.0/24")), true
|
166
|
+
end
|
167
|
+
|
168
|
+
should "find when a subnet is not included in a range" do
|
169
|
+
assert_equal IP.new("1.2.4.0/30").is_in?(IP.new("1.2.3.0/24")), false
|
170
|
+
end
|
171
|
+
|
172
|
+
should "have split" do
|
173
|
+
assert_equal IP.new("1.2.3.0/24").split, [IP.new("1.2.3.0/25"), IP.new("1.2.3.128/25")]
|
174
|
+
end
|
175
|
+
|
176
|
+
should "have divide_by_subnets be exact" do
|
177
|
+
assert_equal IP.new("1.2.3.0/24").divide_by_subnets(4), [IP.new("1.2.3.0/26"), IP.new("1.2.3.64/26"),IP.new("1.2.3.128/26"), IP.new("1.2.3.192/26")]
|
178
|
+
end
|
179
|
+
|
180
|
+
should "have divide_by_subnets choose next largest" do
|
181
|
+
assert_equal IP.new("1.2.3.0/24").divide_by_subnets(3), [IP.new("1.2.3.0/26"), IP.new("1.2.3.64/26"),IP.new("1.2.3.128/26"), IP.new("1.2.3.192/26")]
|
182
|
+
end
|
183
|
+
should "have divide_by_hosts subnet boundary" do
|
184
|
+
assert_equal IP.new("1.2.3.0/24").divide_by_hosts(128), [IP.new("1.2.3.0/24")]
|
185
|
+
end
|
186
|
+
should "have divide_by_hosts full subnet" do
|
187
|
+
assert_equal IP.new("1.2.3.0/24").divide_by_hosts(126), [IP.new("1.2.3.0/25"), IP.new("1.2.3.128/25")]
|
188
|
+
end
|
189
|
+
should "have divide_by_hosts partial subnet" do
|
190
|
+
assert_equal IP.new("1.2.3.0/24").divide_by_hosts(68), [IP.new("1.2.3.0/25"), IP.new("1.2.3.128/25")]
|
191
|
+
end
|
131
192
|
|
132
193
|
should "have size" do
|
133
194
|
assert_equal 256, @addr.size
|
@@ -486,7 +547,10 @@ class IPTest < Test::Unit::TestCase
|
|
486
547
|
@addr.to_s
|
487
548
|
@addr.to_addrlen
|
488
549
|
@addr.to_addr
|
550
|
+
@addr.to_arpa
|
489
551
|
@addr.to_i
|
552
|
+
@addr.to_b
|
553
|
+
@addr.split
|
490
554
|
@addr.to_a
|
491
555
|
@addr.to_ah
|
492
556
|
@addr.to_hex
|
metadata
CHANGED
@@ -1,32 +1,22 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby-ip
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
segments:
|
6
|
-
- 0
|
7
|
-
- 9
|
8
|
-
- 1
|
9
|
-
version: 0.9.1
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.9.3
|
10
5
|
platform: ruby
|
11
|
-
authors:
|
6
|
+
authors:
|
12
7
|
- Brian Candler
|
13
8
|
autorequire:
|
14
9
|
bindir: bin
|
15
10
|
cert_chain: []
|
16
|
-
|
17
|
-
date: 2011-12-13 00:00:00 +00:00
|
18
|
-
default_executable:
|
11
|
+
date: 2011-12-13 00:00:00.000000000 Z
|
19
12
|
dependencies: []
|
20
|
-
|
21
13
|
description: IP address manipulation library
|
22
14
|
email: b.candler@pobox.com
|
23
15
|
executables: []
|
24
|
-
|
25
16
|
extensions: []
|
26
|
-
|
27
|
-
extra_rdoc_files:
|
17
|
+
extra_rdoc_files:
|
28
18
|
- README.rdoc
|
29
|
-
files:
|
19
|
+
files:
|
30
20
|
- lib/ip/base.rb
|
31
21
|
- lib/ip/cpal.rb
|
32
22
|
- lib/ip/socket.rb
|
@@ -38,38 +28,29 @@ files:
|
|
38
28
|
- Rakefile
|
39
29
|
- LICENSE.txt
|
40
30
|
- COPYING.txt
|
41
|
-
has_rdoc: true
|
42
31
|
homepage: http://github.com/deploy2/ruby-ip
|
43
32
|
licenses: []
|
44
|
-
|
33
|
+
metadata: {}
|
45
34
|
post_install_message:
|
46
|
-
rdoc_options:
|
35
|
+
rdoc_options:
|
47
36
|
- --inline-source
|
48
37
|
- --charset=UTF-8
|
49
|
-
require_paths:
|
38
|
+
require_paths:
|
50
39
|
- lib
|
51
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
52
|
-
requirements:
|
53
|
-
- -
|
54
|
-
- !ruby/object:Gem::Version
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
- - ">="
|
61
|
-
- !ruby/object:Gem::Version
|
62
|
-
segments:
|
63
|
-
- 1
|
64
|
-
- 3
|
65
|
-
- 6
|
40
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
41
|
+
requirements:
|
42
|
+
- - '>='
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: '0'
|
45
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
46
|
+
requirements:
|
47
|
+
- - '>='
|
48
|
+
- !ruby/object:Gem::Version
|
66
49
|
version: 1.3.6
|
67
50
|
requirements: []
|
68
|
-
|
69
51
|
rubyforge_project: ruby-ip
|
70
|
-
rubygems_version:
|
52
|
+
rubygems_version: 2.0.14
|
71
53
|
signing_key:
|
72
54
|
specification_version: 2
|
73
55
|
summary: IP address manipulation library
|
74
56
|
test_files: []
|
75
|
-
|