ipaddress_2 0.11.0 → 0.14.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 +4 -4
- data/.travis.yml +2 -0
- data/CHANGELOG.md +27 -1
- data/README.rdoc +3 -3
- data/VERSION +1 -1
- data/ipaddress_2.gemspec +2 -2
- data/lib/ipaddress_2/ipv4.rb +129 -3
- data/lib/ipaddress_2/ipv6.rb +204 -4
- data/lib/ipaddress_2/version.rb +1 -1
- data/test/ipaddress_2/ipv4_test.rb +59 -2
- data/test/ipaddress_2/ipv6_test.rb +100 -2
- metadata +8 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 359df425a73931023ee0026c8fdb2819f43117e24e1aa24b5ff7bb3d7f6121f6
|
4
|
+
data.tar.gz: db06b07d89444432225af2e82529a0eca395cda6e42ed59bf0cf443befc914c8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b537db60dfaf772c2162d3c1f52c0066b0737af5811fa0ac1894aa86414ce86950f4bba00c8aa3c3a1c1171937de26848933020ce428f5b7df04611a08bcf19f
|
7
|
+
data.tar.gz: e2632e98d23618da97172f711d1736d7b6845105cb53412c42db5caa6326edc66b9e1f1ec2319f61855d1c54f3fa743df02cd653a6fd86f933b4f5d9944392f3
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,31 @@
|
|
1
1
|
## [Unreleased]
|
2
2
|
|
3
|
+
## 0.14.0
|
4
|
+
|
5
|
+
### Enhancements
|
6
|
+
* include? will now accept a string. Will also work for include_all?
|
7
|
+
|
8
|
+
## 0.13.0
|
9
|
+
|
10
|
+
### Enhancements
|
11
|
+
* Provide arithmetic operations on IPv4 and IPv6
|
12
|
+
|
13
|
+
## 0.12.1
|
14
|
+
|
15
|
+
### Bugfix
|
16
|
+
* Remove dup from IPv6 summarization to slightly improve performance
|
17
|
+
|
18
|
+
## 0.12.0
|
19
|
+
|
20
|
+
### Enhancements
|
21
|
+
* Added 'last' to IPv6
|
22
|
+
* Added 'broadcast' to IPv6
|
23
|
+
|
24
|
+
## 0.11.1
|
25
|
+
|
26
|
+
### Bugfix
|
27
|
+
* Fix prefix change in find\_adjacent
|
28
|
+
|
3
29
|
## 0.11.0
|
4
30
|
|
5
31
|
### Enhancements
|
@@ -26,6 +52,6 @@
|
|
26
52
|
### Bugfix
|
27
53
|
* Removed duplicate link_local? in IPv6
|
28
54
|
|
29
|
-
Please check [CHANGELOG.rdoc](https://github.com/ipaddress2-gem/
|
55
|
+
Please check [CHANGELOG.rdoc](https://github.com/ipaddress2-gem/ipaddress_2/blob/master/CHANGELOG.rdoc) for previous changes.
|
30
56
|
|
31
57
|
|
data/README.rdoc
CHANGED
@@ -16,11 +16,11 @@ examples of typical usage.
|
|
16
16
|
|
17
17
|
* Ruby 1.9.3 or later
|
18
18
|
|
19
|
-
Please refer to {Travis CI}[https://travis-ci.org/ipaddress2-gem/
|
19
|
+
Please refer to {Travis CI}[https://travis-ci.org/ipaddress2-gem/ipaddress_2] for Build Tests on specific versions of Ruby.
|
20
20
|
|
21
|
-
{<img src="https://travis-ci.org/ipaddress2-gem/
|
21
|
+
{<img src="https://travis-ci.org/ipaddress2-gem/ipaddress_2.svg?branch=master" alt="Build Status" />}[https://travis-ci.org/ipaddress2-gem/ipaddress_2] {<img src="https://codeclimate.com/github/ipaddress2-gem/ipaddress_2/badges/gpa.svg" />}[https://codeclimate.com/github/ipaddress2-gem/ipaddress_2]
|
22
22
|
|
23
|
-
If you want to contribute, please refer to {Contributing.md}[https://github.com/ipaddress2-gem/
|
23
|
+
If you want to contribute, please refer to {Contributing.md}[https://github.com/ipaddress2-gem/ipaddress_2/blob/master/CONTRIBUTING.md].
|
24
24
|
|
25
25
|
|
26
26
|
== Installation
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.14.0
|
data/ipaddress_2.gemspec
CHANGED
@@ -9,7 +9,7 @@ Gem::Specification.new do |s|
|
|
9
9
|
s.version = IPAddress::VERSION
|
10
10
|
s.require_paths = ["lib"]
|
11
11
|
s.authors = ["bluemonk", "mikemackintosh"]
|
12
|
-
s.description = "IPAddress2 is a Ruby library designed to make manipulation\n of IPv4 and IPv6 addresses both powerful and simple. It
|
12
|
+
s.description = "IPAddress2 is a Ruby library designed to make manipulation\n of IPv4 and IPv6 addresses both powerful and simple. It maintains\n a layer of compatibility with Ruby's own IPAddr, while\n addressing many of its issues."
|
13
13
|
s.email = "adam@21eleven.com"
|
14
14
|
s.extra_rdoc_files = [
|
15
15
|
"CHANGELOG.rdoc",
|
@@ -17,7 +17,7 @@ Gem::Specification.new do |s|
|
|
17
17
|
"README.rdoc"
|
18
18
|
]
|
19
19
|
s.files = `git ls-files -z`.split("\x0")
|
20
|
-
s.homepage = "https://github.com/ipaddress2-gem/
|
20
|
+
s.homepage = "https://github.com/ipaddress2-gem/ipaddress_2"
|
21
21
|
|
22
22
|
s.add_development_dependency "bundler"
|
23
23
|
s.add_development_dependency "rake"
|
data/lib/ipaddress_2/ipv4.rb
CHANGED
@@ -377,6 +377,18 @@ module IPAddress;
|
|
377
377
|
def network
|
378
378
|
self.class.parse_u32(network_u32, @prefix)
|
379
379
|
end
|
380
|
+
|
381
|
+
#
|
382
|
+
# Returns a new IPv4 object containing only the host part of this IP.
|
383
|
+
#
|
384
|
+
# ip = IPAddress("172.16.10.64/24")
|
385
|
+
#
|
386
|
+
# ip.hostpart.to_s
|
387
|
+
# #=> "0.0.0.64"
|
388
|
+
#
|
389
|
+
def hostpart
|
390
|
+
self.class.parse_u32(hostpart_u32, 32)
|
391
|
+
end
|
380
392
|
|
381
393
|
#
|
382
394
|
# Returns a new IPv4 object with the
|
@@ -600,6 +612,18 @@ module IPAddress;
|
|
600
612
|
def network_u32
|
601
613
|
@u32 & @prefix.to_u32
|
602
614
|
end
|
615
|
+
|
616
|
+
#
|
617
|
+
# Returns this address' host part in unsigned 32bits format
|
618
|
+
#
|
619
|
+
# ip = IPAddress("10.0.0.42/24")
|
620
|
+
#
|
621
|
+
# ip.host_u32
|
622
|
+
# #=> 42
|
623
|
+
#
|
624
|
+
def hostpart_u32
|
625
|
+
@u32 & ~@prefix.to_u32
|
626
|
+
end
|
603
627
|
|
604
628
|
#
|
605
629
|
# Returns the broadcast address in Unsigned 32bits format
|
@@ -616,7 +640,7 @@ module IPAddress;
|
|
616
640
|
#
|
617
641
|
# Checks whether a subnet includes the given IP address.
|
618
642
|
#
|
619
|
-
# Accepts an IPAddress::IPv4 object.
|
643
|
+
# Accepts an IPAddress::IPv4 object or a string.
|
620
644
|
#
|
621
645
|
# ip = IPAddress("192.168.10.100/24")
|
622
646
|
#
|
@@ -628,13 +652,19 @@ module IPAddress;
|
|
628
652
|
# ip.include? IPAddress("172.16.0.48/16")
|
629
653
|
# #=> false
|
630
654
|
#
|
655
|
+
# ip.include? "192.168.10.50"
|
656
|
+
# #=> true
|
657
|
+
#
|
631
658
|
def include?(oth)
|
659
|
+
unless oth.is_a? IPAddress::IPv4
|
660
|
+
oth = IPv4.new(oth)
|
661
|
+
end
|
632
662
|
@prefix <= oth.prefix and network_u32 == (oth.to_u32 & @prefix.to_u32)
|
633
663
|
end
|
634
664
|
|
635
665
|
#
|
636
666
|
# Checks whether a subnet includes all the
|
637
|
-
# given IPv4 objects.
|
667
|
+
# given IPv4 objects or strings.
|
638
668
|
#
|
639
669
|
# ip = IPAddress("192.168.10.100/24")
|
640
670
|
#
|
@@ -644,6 +674,9 @@ module IPAddress;
|
|
644
674
|
# ip.include_all?(addr1,addr2)
|
645
675
|
# #=> true
|
646
676
|
#
|
677
|
+
# ip.include_all?("192.168.10.102/24", "192.168.10.103/24")
|
678
|
+
# #=> true
|
679
|
+
#
|
647
680
|
def include_all?(*others)
|
648
681
|
others.all? {|oth| include?(oth)}
|
649
682
|
end
|
@@ -886,6 +919,97 @@ module IPAddress;
|
|
886
919
|
def +(oth)
|
887
920
|
aggregate(*[self,oth].sort.map{|i| i.network})
|
888
921
|
end
|
922
|
+
|
923
|
+
#
|
924
|
+
# Returns a new IPv4 object which is the result
|
925
|
+
# of advancing this IP address by a given value.
|
926
|
+
# In other words, this arithmetically adds IP addresses.
|
927
|
+
#
|
928
|
+
# Will raise an error if the resulting address is in a different subnet,
|
929
|
+
# except validating is set to false.
|
930
|
+
#
|
931
|
+
# Example:
|
932
|
+
#
|
933
|
+
# ip = IPAddress::IPv4.new("172.16.10.1/24")
|
934
|
+
# ip.add(5).to_string
|
935
|
+
# #=> "172.16.10.6/24"
|
936
|
+
def add(oth, validating=true)
|
937
|
+
oth = oth.to_i if oth.kind_of? IPAddress::IPv4 # oth shall be integer
|
938
|
+
|
939
|
+
new_obj = self.class.parse_u32(self.to_i + oth, prefix)
|
940
|
+
|
941
|
+
if validating and self.network_u32 != new_obj.network_u32
|
942
|
+
raise RuntimeError, "Subnet (/#{@prefix}) is not large enough."
|
943
|
+
end
|
944
|
+
|
945
|
+
new_obj
|
946
|
+
end
|
947
|
+
|
948
|
+
#
|
949
|
+
# Returns a new IPv4 object which is the result
|
950
|
+
# of decreasing this IP address by a given value.
|
951
|
+
# In other words, this arithmetically subtracts IP addresses.
|
952
|
+
#
|
953
|
+
# Will raise an error if the resulting address is in a different subnet,
|
954
|
+
# except validating is set to false.
|
955
|
+
#
|
956
|
+
# Example:
|
957
|
+
#
|
958
|
+
# ip = IPAddress::IPv4.new("172.16.10.10/24")
|
959
|
+
# ip.subtract(5).to_string
|
960
|
+
# #=> "172.16.10.5/24"
|
961
|
+
def subtract(oth, validating=true)
|
962
|
+
oth = oth.to_i if oth.kind_of? IPAddress::IPv4 # oth shall be integer
|
963
|
+
add(-oth, validating)
|
964
|
+
end
|
965
|
+
|
966
|
+
#
|
967
|
+
# Returns the network address of the n-th network succeeding this one.
|
968
|
+
#
|
969
|
+
# Example:
|
970
|
+
#
|
971
|
+
# ip = IPAddress::IPv4.new("172.16.10.0/24")
|
972
|
+
# ip.advance_network(24).to_string
|
973
|
+
# #=> "172.16.52.0/24"
|
974
|
+
def advance_network(amount)
|
975
|
+
IPAddress::IPv4.parse_u32(self.network.u32 + amount*self.size, @prefix)
|
976
|
+
end
|
977
|
+
|
978
|
+
#
|
979
|
+
# Returns the network address of the network succeeding this one.
|
980
|
+
#
|
981
|
+
# Example:
|
982
|
+
#
|
983
|
+
# ip = IPAddress::IPv4.new("172.16.10.0/24")
|
984
|
+
# ip.next_network.to_string
|
985
|
+
# #=> "172.16.11.0/24"
|
986
|
+
def next_network
|
987
|
+
advance_network 1
|
988
|
+
end
|
989
|
+
|
990
|
+
#
|
991
|
+
# Returns the network address of the n-th network preceeding this one.
|
992
|
+
#
|
993
|
+
# Example:
|
994
|
+
#
|
995
|
+
# ip = IPAddress::IPv4.new("172.16.10.0/24")
|
996
|
+
# ip.regress_network(5).to_string
|
997
|
+
# #=> "172.16.5.0/24"
|
998
|
+
def regress_network(amount)
|
999
|
+
advance_network(-amount)
|
1000
|
+
end
|
1001
|
+
|
1002
|
+
#
|
1003
|
+
# Returns the network address of the network preceeding this one.
|
1004
|
+
#
|
1005
|
+
# Example:
|
1006
|
+
#
|
1007
|
+
# ip = IPAddress::IPv4.new("172.16.10.0/24")
|
1008
|
+
# ip.previous_network.to_string
|
1009
|
+
# #=> "172.16.9.0/24"
|
1010
|
+
def previous_network
|
1011
|
+
regress_network 1
|
1012
|
+
end
|
889
1013
|
|
890
1014
|
#
|
891
1015
|
# Checks whether the ip address belongs to a
|
@@ -1164,7 +1288,9 @@ module IPAddress;
|
|
1164
1288
|
return false if prefix == 0
|
1165
1289
|
current_subnet = to_string
|
1166
1290
|
self.prefix = @prefix - 1
|
1167
|
-
(split.map{|i| i.to_string} - [current_subnet])[0]
|
1291
|
+
adjacent_subnet = (split.map{|i| i.to_string} - [current_subnet])[0]
|
1292
|
+
self.prefix = @prefix + 1
|
1293
|
+
return adjacent_subnet
|
1168
1294
|
end
|
1169
1295
|
|
1170
1296
|
#
|
data/lib/ipaddress_2/ipv6.rb
CHANGED
@@ -246,6 +246,63 @@ module IPAddress;
|
|
246
246
|
to_u128 | @prefix.to_u128 == @prefix.to_u128
|
247
247
|
end
|
248
248
|
|
249
|
+
#
|
250
|
+
# Returns a new IPv6 object with the
|
251
|
+
# first host IP address in the range.
|
252
|
+
#
|
253
|
+
# Example: given the 2001:db8:8:800::/64 network, the first
|
254
|
+
# host IP address is 2001:db8:8:800::
|
255
|
+
#
|
256
|
+
# ip = IPAddress("2001:db8:8:800::/64")
|
257
|
+
#
|
258
|
+
# ip.first.to_s
|
259
|
+
# #=> "2001:db8:8:800::"
|
260
|
+
#
|
261
|
+
# The object IP doesn't need to be a network: the method
|
262
|
+
# automatically gets the network number from it
|
263
|
+
#
|
264
|
+
# ip = IPAddress("2001:db8:9:800::2/64")
|
265
|
+
#
|
266
|
+
# ip.first.to_s
|
267
|
+
# #=> "2001:db8:9:800::"
|
268
|
+
#
|
269
|
+
def first
|
270
|
+
if prefix == 128
|
271
|
+
return self
|
272
|
+
else
|
273
|
+
IPAddress::IPv6::parse_u128(network_u128)
|
274
|
+
end
|
275
|
+
end
|
276
|
+
|
277
|
+
#
|
278
|
+
# Like its sibling method IPv4#first, this method
|
279
|
+
# returns a new IPv4 object with the
|
280
|
+
# last host IP address in the range.
|
281
|
+
#
|
282
|
+
# Example: given the 192.168.100.0/24 network, the last
|
283
|
+
# host IP address is 192.168.100.254
|
284
|
+
#
|
285
|
+
# ip = IPAddress("2001:db8:8:800::/64")
|
286
|
+
#
|
287
|
+
# ip.last.to_s
|
288
|
+
# #=> "2001:db8:8:800:ffff:ffff:ffff:ffff"
|
289
|
+
#
|
290
|
+
# The object IP doesn't need to be a network: the method
|
291
|
+
# automatically gets the network number from it
|
292
|
+
#
|
293
|
+
# ip = IPAddress("2001:db8:9:800::2/64")
|
294
|
+
#
|
295
|
+
# ip.last.to_s
|
296
|
+
# #=> "2001:db8:9:800:ffff:ffff:ffff:ffff"
|
297
|
+
#
|
298
|
+
def last
|
299
|
+
if prefix == 128
|
300
|
+
return self
|
301
|
+
else
|
302
|
+
IPAddress::IPv6::parse_u128(broadcast_u128)
|
303
|
+
end
|
304
|
+
end
|
305
|
+
|
249
306
|
#
|
250
307
|
# Returns the 16-bits value specified by index
|
251
308
|
#
|
@@ -337,8 +394,110 @@ module IPAddress;
|
|
337
394
|
to_hex.reverse.gsub(/./){|c| c+"."} + "ip6.arpa"
|
338
395
|
end
|
339
396
|
alias_method :arpa, :reverse
|
397
|
+
|
398
|
+
#
|
399
|
+
# Returns a new IPv6 object which is the result
|
400
|
+
# of advancing this IP address by a given value.
|
401
|
+
# In other words, this arithmetically adds IP addresses.
|
402
|
+
#
|
403
|
+
# Will raise an error if the resulting address is in a different subnet,
|
404
|
+
# except validating is set to false.
|
405
|
+
#
|
406
|
+
# Example:
|
407
|
+
#
|
408
|
+
# ip = IPAddress::IPv6.new("fc42:1337::/64")
|
409
|
+
# ip.add(5).to_string
|
410
|
+
# #=> "fc42:1337::5/64"
|
411
|
+
def add(oth, validating=true)
|
412
|
+
oth = oth.to_i if oth.kind_of? IPAddress::IPv6 # oth shall be integer
|
413
|
+
|
414
|
+
new_obj = self.class.parse_u128(self.to_i + oth, prefix)
|
415
|
+
|
416
|
+
if validating and self.network_u128 != new_obj.network_u128
|
417
|
+
raise RuntimeError, "Subnet (/#{@prefix}) is not large enough."
|
418
|
+
end
|
419
|
+
|
420
|
+
new_obj
|
421
|
+
end
|
422
|
+
|
423
|
+
#
|
424
|
+
# Returns a new IPv6 object which is the result
|
425
|
+
# of decreasing this IP address by a given value.
|
426
|
+
# In other words, this arithmetically subtracts IP addresses.
|
427
|
+
#
|
428
|
+
# Will raise an error if the resulting address is in a different subnet,
|
429
|
+
# except validating is set to false.
|
430
|
+
#
|
431
|
+
# Example:
|
432
|
+
#
|
433
|
+
# ip = IPAddress::IPv6.new("fc42:1337::a/64")
|
434
|
+
# ip.subtract(5).to_string
|
435
|
+
# #=> "fc42:1337::5/64"
|
436
|
+
def subtract(oth, validating=true)
|
437
|
+
oth = oth.to_i if oth.kind_of? IPAddress::IPv6 # oth shall be integer
|
438
|
+
add(-oth, validating)
|
439
|
+
end
|
340
440
|
|
341
441
|
#
|
442
|
+
# Returns the network address of the n-th network succeeding this one.
|
443
|
+
#
|
444
|
+
# Example:
|
445
|
+
#
|
446
|
+
# ip = IPAddress::IPv6.new("fc42:1337:0:0::/64")
|
447
|
+
# ip.advance_network(5).to_string
|
448
|
+
# #=> "fc42:1337:0:5::/64"
|
449
|
+
def advance_network(amount)
|
450
|
+
IPAddress::IPv6.parse_u128(self.network.to_i + amount*self.size, @prefix)
|
451
|
+
end
|
452
|
+
|
453
|
+
#
|
454
|
+
# Returns the network address of the network succeeding this one.
|
455
|
+
#
|
456
|
+
# Example:
|
457
|
+
#
|
458
|
+
# ip = IPAddress::IPv6.new("fc42:1337:0:0::/64")
|
459
|
+
# ip.next_network.to_string
|
460
|
+
# #=> "fc42:1337:0:1::/64"
|
461
|
+
def next_network
|
462
|
+
advance_network 1
|
463
|
+
end
|
464
|
+
|
465
|
+
#
|
466
|
+
# Returns the network address of the n-th network preceeding this one.
|
467
|
+
#
|
468
|
+
# Example:
|
469
|
+
#
|
470
|
+
# ip = IPAddress::IPv6.new("fc42:1337:0:5::/64")
|
471
|
+
# ip.regress_network(4).to_string
|
472
|
+
# #=> "fc42:1337:0:1::/64"
|
473
|
+
def regress_network(amount)
|
474
|
+
advance_network(-amount)
|
475
|
+
end
|
476
|
+
|
477
|
+
#
|
478
|
+
# Returns the network address of the network preceeding this one.
|
479
|
+
#
|
480
|
+
# Example:
|
481
|
+
#
|
482
|
+
# ip = IPAddress::IPv6.new("fc42:1337:0:5::/64")
|
483
|
+
# ip.previous_network.to_string
|
484
|
+
# #=> "fc42:1337:0:4::/64"
|
485
|
+
def previous_network
|
486
|
+
regress_network 1
|
487
|
+
end
|
488
|
+
|
489
|
+
#
|
490
|
+
# Returns a new IPv6 object containing only the host part of this IP.
|
491
|
+
#
|
492
|
+
# ip = IPAddress::IPv6.new("fc42:1337:0:5::7/64")
|
493
|
+
#
|
494
|
+
# ip.hostpart.to_s
|
495
|
+
# #=> "::7"
|
496
|
+
#
|
497
|
+
def hostpart
|
498
|
+
self.class.parse_u128(hostpart_u128, 128)
|
499
|
+
end
|
500
|
+
|
342
501
|
# Splits a network into different subnets
|
343
502
|
#
|
344
503
|
# NOTE: Will allow you to split past /64 against RFC 5375
|
@@ -396,6 +555,18 @@ module IPAddress;
|
|
396
555
|
def network_u128
|
397
556
|
to_u128 & @prefix.to_u128
|
398
557
|
end
|
558
|
+
|
559
|
+
#
|
560
|
+
# Returns this address' host part in unsigned 128bits format
|
561
|
+
#
|
562
|
+
# ip = IPAddress::IPv6.new("fc42:1337:0:5::7/64")
|
563
|
+
#
|
564
|
+
# ip.host_u128
|
565
|
+
# #=> 7
|
566
|
+
#
|
567
|
+
def hostpart_u128
|
568
|
+
to_u128 & ~@prefix.to_u128
|
569
|
+
end
|
399
570
|
|
400
571
|
#
|
401
572
|
# Returns the broadcast address in Unsigned 128bits format
|
@@ -441,13 +612,19 @@ module IPAddress;
|
|
441
612
|
# ip6.include? IPAddress("2001:db8:1::8:800:200c:417a/76")
|
442
613
|
# #=> false
|
443
614
|
#
|
615
|
+
# ip6.include? "2001:db8::8:800:200c:1"
|
616
|
+
# #=> true
|
617
|
+
#
|
444
618
|
def include?(oth)
|
619
|
+
unless oth.is_a? IPAddress::IPv6
|
620
|
+
oth = IPv6.new(oth)
|
621
|
+
end
|
445
622
|
@prefix <= oth.prefix and network_u128 == self.class.new(oth.address+"/#@prefix").network_u128
|
446
623
|
end
|
447
624
|
|
448
625
|
#
|
449
626
|
# Checks whether a subnet includes all the
|
450
|
-
# given IPv4 objects.
|
627
|
+
# given IPv4 objects or strings.
|
451
628
|
#
|
452
629
|
# ip = IPAddress("2001:db8:8:800::1/64")
|
453
630
|
#
|
@@ -457,6 +634,9 @@ module IPAddress;
|
|
457
634
|
# ip.include_all?(addr1,addr2)
|
458
635
|
# #=> true
|
459
636
|
#
|
637
|
+
# ip.include_all?("2001:db8:8:800::2/64", "2001:db8:8:800::8/64")
|
638
|
+
# #=> true
|
639
|
+
#
|
460
640
|
def include_all?(*others)
|
461
641
|
others.all? {|oth| include?(oth)}
|
462
642
|
end
|
@@ -771,6 +951,23 @@ module IPAddress;
|
|
771
951
|
self.class.parse_u128(network_u128, @prefix)
|
772
952
|
end
|
773
953
|
|
954
|
+
#
|
955
|
+
# Returns the broadcast address for the given IP.
|
956
|
+
# As this is IPv6 it is just the last IP
|
957
|
+
#
|
958
|
+
# ip = IPAddress("2001:db8:8:800::/64")
|
959
|
+
#
|
960
|
+
# ip.broadcast.to_s
|
961
|
+
# #=> "2001:db8:8:800::"
|
962
|
+
#
|
963
|
+
def broadcast
|
964
|
+
if prefix == 128
|
965
|
+
return self
|
966
|
+
else
|
967
|
+
IPAddress::IPv6::parse_u128(broadcast_u128)
|
968
|
+
end
|
969
|
+
end
|
970
|
+
|
774
971
|
#
|
775
972
|
# Extract 16 bits groups from a string
|
776
973
|
#
|
@@ -915,9 +1112,10 @@ module IPAddress;
|
|
915
1112
|
def self.summarize(*args)
|
916
1113
|
# one network? no need to summarize
|
917
1114
|
return [args.first.network] if args.size == 1
|
1115
|
+
args_size = args.size
|
918
1116
|
|
919
1117
|
i = 0
|
920
|
-
result = args.
|
1118
|
+
result = args.sort.map{|ip| ip.network}
|
921
1119
|
while i < result.size-1
|
922
1120
|
sum = result[i] + result[i+1]
|
923
1121
|
result[i..i+1] = sum.first if sum.size == 1
|
@@ -925,7 +1123,7 @@ module IPAddress;
|
|
925
1123
|
end
|
926
1124
|
|
927
1125
|
result.flatten!
|
928
|
-
if result.size ==
|
1126
|
+
if result.size == args_size
|
929
1127
|
# nothing more to summarize
|
930
1128
|
return result
|
931
1129
|
else
|
@@ -977,7 +1175,9 @@ module IPAddress;
|
|
977
1175
|
return false if prefix == 0
|
978
1176
|
current_subnet = to_string
|
979
1177
|
self.prefix = @prefix - 1
|
980
|
-
(split.map{|i| i.to_string} - [current_subnet])[0]
|
1178
|
+
adjacent_subnet = (split.map{|i| i.to_string} - [current_subnet])[0]
|
1179
|
+
self.prefix = @prefix + 1
|
1180
|
+
return adjacent_subnet
|
981
1181
|
end
|
982
1182
|
|
983
1183
|
private
|
data/lib/ipaddress_2/version.rb
CHANGED
@@ -327,7 +327,10 @@ class IPv4Test < Minitest::Test
|
|
327
327
|
assert_equal false, ip.include?(@klass.new("5.5.5.5/32"))
|
328
328
|
assert_equal false, ip.include?(@klass.new("11.0.0.0/8"))
|
329
329
|
ip = @klass.new("13.13.0.0/13")
|
330
|
-
assert_equal false, ip.include?(@klass.new("13.16.0.0/32"))
|
330
|
+
assert_equal false, ip.include?(@klass.new("13.16.0.0/32"))
|
331
|
+
ip = @klass.new("10.10.10.0/24")
|
332
|
+
assert_equal true, ip.include?("10.10.10.100")
|
333
|
+
assert_equal false, ip.include?("10.10.9.100")
|
331
334
|
end
|
332
335
|
|
333
336
|
def test_method_include_all?
|
@@ -336,6 +339,8 @@ class IPv4Test < Minitest::Test
|
|
336
339
|
addr2 = @klass.new("192.168.10.103/24")
|
337
340
|
assert_equal true, ip.include_all?(addr1,addr2)
|
338
341
|
assert_equal false, ip.include_all?(addr1, @klass.new("13.16.0.0/32"))
|
342
|
+
assert_equal true, ip.include_all?("192.168.10.102/24", "192.168.10.103/24")
|
343
|
+
assert_equal false, ip.include_all?(addr1, "13.16.0.0/32")
|
339
344
|
end
|
340
345
|
|
341
346
|
def test_method_ipv4?
|
@@ -455,7 +460,7 @@ class IPv4Test < Minitest::Test
|
|
455
460
|
|
456
461
|
ip2 = @klass.new("172.16.12.2/24")
|
457
462
|
assert_equal [ip1.network.to_string, ip2.network.to_string],
|
458
|
-
|
463
|
+
(ip1 + ip2).map{|i| i.to_string}
|
459
464
|
|
460
465
|
ip1 = @klass.new("10.0.0.0/23")
|
461
466
|
ip2 = @klass.new("10.0.2.0/24")
|
@@ -533,6 +538,57 @@ class IPv4Test < Minitest::Test
|
|
533
538
|
assert_equal "172.16.8.0/22", @ip.supernet(22).to_string
|
534
539
|
end
|
535
540
|
|
541
|
+
def test_method_add
|
542
|
+
ip = IPAddress::IPv4.new("172.16.10.1/24")
|
543
|
+
assert_equal ip.add(5), IPAddress::IPv4.new("172.16.10.6/24")
|
544
|
+
assert_equal ip.add(IPAddress::IPv4.new("0.0.0.5/6")), IPAddress::IPv4.new("172.16.10.6/24")
|
545
|
+
assert_equal ip.add(50), IPAddress::IPv4.new("172.16.10.51/24")
|
546
|
+
assert_equal ip.add(254), IPAddress::IPv4.new("172.16.10.255/24")
|
547
|
+
assert_raises(RuntimeError) {ip.add(255)}
|
548
|
+
assert_equal ip.add(255, false), IPAddress::IPv4.new("172.16.11.0/24")
|
549
|
+
assert_raises(RuntimeError) {ip.add(1000)}
|
550
|
+
ip = IPAddress::IPv4.new("172.16.10.1/30")
|
551
|
+
assert_equal ip.add(2), IPAddress::IPv4.new("172.16.10.3/30")
|
552
|
+
assert_raises(RuntimeError) {ip.add(3)}
|
553
|
+
end
|
554
|
+
|
555
|
+
def test_method_subtract
|
556
|
+
ip = IPAddress::IPv4.new("172.16.10.10/24")
|
557
|
+
assert_equal ip.subtract(5), IPAddress::IPv4.new("172.16.10.5/24")
|
558
|
+
assert_equal ip.subtract(IPAddress::IPv4.new("0.0.0.5/32")), IPAddress::IPv4.new("172.16.10.5/24")
|
559
|
+
assert_equal ip.subtract(10), IPAddress::IPv4.new("172.16.10.0/24")
|
560
|
+
assert_raises(RuntimeError) {ip.subtract(11)}
|
561
|
+
assert_equal ip.subtract(11, false), IPAddress::IPv4.new("172.16.9.255/24")
|
562
|
+
assert_raises(RuntimeError) {ip.subtract(IPAddress::IPv4.new("0.0.0.11/16"))}
|
563
|
+
end
|
564
|
+
|
565
|
+
def test_method_hostpart
|
566
|
+
ip = IPAddress::IPv4.new("172.16.10.64/24")
|
567
|
+
assert_equal ip.hostpart.to_s, "0.0.0.64"
|
568
|
+
ip = IPAddress::IPv4.new("172.16.10.130/25")
|
569
|
+
assert_equal ip.hostpart.to_s, "0.0.0.2"
|
570
|
+
end
|
571
|
+
|
572
|
+
def test_method_advance_network
|
573
|
+
ip = IPAddress::IPv4.new("172.16.10.64/24")
|
574
|
+
assert_equal ip.advance_network(42), IPAddress::IPv4.new("172.16.52.0/24")
|
575
|
+
end
|
576
|
+
|
577
|
+
def test_method_next_network
|
578
|
+
ip = IPAddress::IPv4.new("172.16.10.64/24")
|
579
|
+
assert_equal ip.next_network, IPAddress::IPv4.new("172.16.11.0/24")
|
580
|
+
end
|
581
|
+
|
582
|
+
def test_method_regress_network
|
583
|
+
ip = IPAddress::IPv4.new("172.16.10.64/24")
|
584
|
+
assert_equal ip.regress_network(5), IPAddress::IPv4.new("172.16.5.0/24")
|
585
|
+
end
|
586
|
+
|
587
|
+
def test_method_previous_network
|
588
|
+
ip = IPAddress::IPv4.new("172.16.10.64/24")
|
589
|
+
assert_equal ip.previous_network, IPAddress::IPv4.new("172.16.9.0/24")
|
590
|
+
end
|
591
|
+
|
536
592
|
def test_classmethod_parse_u32
|
537
593
|
@decimal_values.each do |addr,int|
|
538
594
|
ip = @klass.parse_u32(int)
|
@@ -689,6 +745,7 @@ class IPv4Test < Minitest::Test
|
|
689
745
|
def test_finds_adjacent_subnet
|
690
746
|
ip = @klass.new("10.0.0.0/24")
|
691
747
|
assert_equal "10.0.1.0/24", ip.find_adjacent_subnet
|
748
|
+
assert_equal 24, ip.prefix
|
692
749
|
refute @klass.new("10.0.0.0/0").find_adjacent_subnet
|
693
750
|
assert_equal "10.0.0.0/8", @klass.new("11.0.0.0/8").find_adjacent_subnet
|
694
751
|
assert_equal "172.16.0.0/16", @klass.new("172.17.0.0/16").find_adjacent_subnet
|
@@ -128,6 +128,36 @@ class IPv6Test < Minitest::Test
|
|
128
128
|
assert_equal bits, @ip.bits
|
129
129
|
end
|
130
130
|
|
131
|
+
def test_method_first
|
132
|
+
ip = @klass.new("2001:db8:8:800::/64")
|
133
|
+
assert_instance_of @klass, ip.first
|
134
|
+
assert_equal "2001:db8:8:800::", ip.first.to_s
|
135
|
+
ip = @klass.new("2001:db8:8::/48")
|
136
|
+
assert_instance_of @klass, ip.first
|
137
|
+
assert_equal "2001:db8:8::", ip.first.to_s
|
138
|
+
ip = @klass.new("2001:db8::/32")
|
139
|
+
assert_instance_of @klass, ip.first
|
140
|
+
assert_equal "2001:db8::", ip.first.to_s
|
141
|
+
ip = @klass.new("2001:db8::8:800:200c:417a/64")
|
142
|
+
assert_instance_of @klass, ip.first
|
143
|
+
assert_equal "2001:db8::", ip.first.to_s
|
144
|
+
end
|
145
|
+
|
146
|
+
def test_method_last
|
147
|
+
ip = @klass.new("2001:db8:8:800::/64")
|
148
|
+
assert_instance_of @klass, ip.last
|
149
|
+
assert_equal "2001:db8:8:800:ffff:ffff:ffff:ffff", ip.last.to_s
|
150
|
+
ip = @klass.new("2001:db8:8::/48")
|
151
|
+
assert_instance_of @klass, ip.last
|
152
|
+
assert_equal "2001:db8:8:ffff:ffff:ffff:ffff:ffff", ip.last.to_s
|
153
|
+
ip = @klass.new("2001:db8::/32")
|
154
|
+
assert_instance_of @klass, ip.last
|
155
|
+
assert_equal "2001:db8:ffff:ffff:ffff:ffff:ffff:ffff", ip.last.to_s
|
156
|
+
ip = @klass.new("2001:db8::8:800:200c:417a/64")
|
157
|
+
assert_instance_of @klass, ip.last
|
158
|
+
assert_equal "2001:db8::ffff:ffff:ffff:ffff", ip.last.to_s
|
159
|
+
end
|
160
|
+
|
131
161
|
def test_method_prefix=()
|
132
162
|
ip = @klass.new "2001:db8::8:800:200c:417a"
|
133
163
|
assert_equal 128, ip.prefix
|
@@ -322,6 +352,9 @@ class IPv6Test < Minitest::Test
|
|
322
352
|
not_included = @klass.new "2001:db8:1::8:800:200c:417a/76"
|
323
353
|
assert_equal true, @ip.include?(included)
|
324
354
|
assert_equal false, @ip.include?(not_included)
|
355
|
+
# string test
|
356
|
+
assert_equal true, @ip.include?("2001:db8::8:800:200c:2")
|
357
|
+
assert_equal false, @ip.include?("2001:db8:1::8:800:200c:417a")
|
325
358
|
end
|
326
359
|
|
327
360
|
def test_method_include_all?
|
@@ -330,6 +363,8 @@ class IPv6Test < Minitest::Test
|
|
330
363
|
addr2 = @klass.new("2001:db8:8:800::8/64")
|
331
364
|
assert_equal true, ip.include_all?(addr1,addr2)
|
332
365
|
assert_equal false, ip.include_all?(addr1, @klass.new("2002:db8:8:800::2/64"))
|
366
|
+
assert_equal true, ip.include_all?("2001:db8:8:800::2/64", "2001:db8:8:800::8/64")
|
367
|
+
assert_equal false, ip.include_all?(addr1, "2002:db8:8:800::2/64")
|
333
368
|
end
|
334
369
|
|
335
370
|
def test_method_to_hex
|
@@ -399,6 +434,21 @@ class IPv6Test < Minitest::Test
|
|
399
434
|
end
|
400
435
|
end
|
401
436
|
|
437
|
+
def test_method_broadcast
|
438
|
+
ip = @klass.new("2001:db8:8:800::/64")
|
439
|
+
assert_instance_of @klass, ip.broadcast
|
440
|
+
assert_equal "2001:db8:8:800:ffff:ffff:ffff:ffff", ip.broadcast.to_s
|
441
|
+
ip = @klass.new("2001:db8:8::/48")
|
442
|
+
assert_instance_of @klass, ip.broadcast
|
443
|
+
assert_equal "2001:db8:8:ffff:ffff:ffff:ffff:ffff", ip.broadcast.to_s
|
444
|
+
ip = @klass.new("2001:db8::/32")
|
445
|
+
assert_instance_of @klass, ip.broadcast
|
446
|
+
assert_equal "2001:db8:ffff:ffff:ffff:ffff:ffff:ffff", ip.broadcast.to_s
|
447
|
+
ip = @klass.new("2001:db8::8:800:200c:417a/64")
|
448
|
+
assert_instance_of @klass, ip.broadcast
|
449
|
+
assert_equal "2001:db8::ffff:ffff:ffff:ffff", ip.broadcast.to_s
|
450
|
+
end
|
451
|
+
|
402
452
|
def test_method_network
|
403
453
|
@networks.each do |addr,net|
|
404
454
|
ip = @klass.new addr
|
@@ -572,13 +622,61 @@ class IPv6Test < Minitest::Test
|
|
572
622
|
|
573
623
|
def test_finds_adjacent_subnet
|
574
624
|
refute @klass.new("::/0").find_adjacent_subnet
|
625
|
+
|
626
|
+
ip = @klass.new("2001:db8::/32")
|
627
|
+
assert_equal "2001:db9::/32", ip.find_adjacent_subnet
|
628
|
+
assert_equal 32, ip.prefix
|
629
|
+
|
575
630
|
assert_equal "2001:db9::/32", @klass.new("2001:db8::/32").find_adjacent_subnet
|
576
631
|
assert_equal "2001:db8:0:1::/64", @klass.new("2001:db8::/64").find_adjacent_subnet
|
577
632
|
assert_equal "2001:db8:8:2000::/51", @klass.new("2001:db8:8::/51").find_adjacent_subnet
|
578
|
-
# assert_equal "", @klass.new("").find_adjacent_subnet
|
579
|
-
# assert_equal "", @klass.new("").find_adjacent_subnet
|
580
633
|
end
|
581
634
|
|
635
|
+
def test_method_add
|
636
|
+
ip = IPAddress::IPv6.new("fc42:1337::/64")
|
637
|
+
assert_equal ip.add(5), IPAddress::IPv6.new("fc42:1337::5/64")
|
638
|
+
assert_equal ip.add(IPAddress::IPv6.new("::5/42")), IPAddress::IPv6.new("fc42:1337::5/64")
|
639
|
+
assert_equal ip.add(50), IPAddress::IPv6.new("fc42:1337::32/64")
|
640
|
+
ip = IPAddress::IPv6.new("fc42:1337::/120")
|
641
|
+
assert_equal ip.add(2), IPAddress::IPv6.new("fc42:1337::2/120")
|
642
|
+
assert_raises(RuntimeError) {ip.add(256)}
|
643
|
+
assert_equal ip.add(256, false), IPAddress::IPv6.new("fc42:1337::100/120")
|
644
|
+
end
|
645
|
+
|
646
|
+
def test_method_subtract
|
647
|
+
ip = IPAddress::IPv6.new("fc42:1337::5/64")
|
648
|
+
assert_equal ip.subtract(5), IPAddress::IPv6.new("fc42:1337::/64")
|
649
|
+
assert_equal ip.subtract(IPAddress::IPv6.new("::5/12")), IPAddress::IPv6.new("fc42:1337::0/64")
|
650
|
+
assert_raises(RuntimeError) {ip.subtract(11)}
|
651
|
+
assert_raises(RuntimeError) {ip.subtract(IPAddress::IPv6.new("::11/66"))}
|
652
|
+
end
|
653
|
+
|
654
|
+
def test_method_hostpart
|
655
|
+
ip = IPAddress::IPv6.new("fc42:1337:0:5::7/64")
|
656
|
+
assert_equal ip.hostpart.to_s, "::7"
|
657
|
+
end
|
658
|
+
|
659
|
+
def test_method_advance_network
|
660
|
+
ip = IPAddress::IPv6.new("fc42:1337:0:0::/64")
|
661
|
+
assert_equal ip.advance_network(5), IPAddress::IPv6.new("fc42:1337:0:5::/64")
|
662
|
+
end
|
663
|
+
|
664
|
+
def test_method_next_network
|
665
|
+
ip = IPAddress::IPv6.new("fc42:1337:0:0::/64")
|
666
|
+
assert_equal ip.next_network, IPAddress::IPv6.new("fc42:1337:0:1::/64")
|
667
|
+
end
|
668
|
+
|
669
|
+
def test_method_regress_network
|
670
|
+
ip = IPAddress::IPv6.new("fc42:1337:0:5::/64")
|
671
|
+
assert_equal ip.regress_network(4), IPAddress::IPv6.new("fc42:1337:0:1::/64")
|
672
|
+
end
|
673
|
+
|
674
|
+
def test_method_previous_network
|
675
|
+
ip = IPAddress::IPv6.new("fc42:1337:0:5::/64")
|
676
|
+
assert_equal ip.previous_network, IPAddress::IPv6.new("fc42:1337:0:4::/64")
|
677
|
+
end
|
678
|
+
|
679
|
+
|
582
680
|
end # class IPv6Test
|
583
681
|
|
584
682
|
class IPv6UnspecifiedTest < Minitest::Test
|
metadata
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ipaddress_2
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.14.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- bluemonk
|
8
8
|
- mikemackintosh
|
9
|
-
autorequire:
|
9
|
+
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2021-07-04 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
@@ -131,7 +131,7 @@ dependencies:
|
|
131
131
|
version: '0'
|
132
132
|
description: |-
|
133
133
|
IPAddress2 is a Ruby library designed to make manipulation
|
134
|
-
of IPv4 and IPv6 addresses both powerful and simple. It
|
134
|
+
of IPv4 and IPv6 addresses both powerful and simple. It maintains
|
135
135
|
a layer of compatibility with Ruby's own IPAddr, while
|
136
136
|
addressing many of its issues.
|
137
137
|
email: adam@21eleven.com
|
@@ -168,11 +168,11 @@ files:
|
|
168
168
|
- test/ipaddress_2/prefix_test.rb
|
169
169
|
- test/ipaddress_2_test.rb
|
170
170
|
- test/test_helper.rb
|
171
|
-
homepage: https://github.com/ipaddress2-gem/
|
171
|
+
homepage: https://github.com/ipaddress2-gem/ipaddress_2
|
172
172
|
licenses:
|
173
173
|
- MIT
|
174
174
|
metadata: {}
|
175
|
-
post_install_message:
|
175
|
+
post_install_message:
|
176
176
|
rdoc_options: []
|
177
177
|
require_paths:
|
178
178
|
- lib
|
@@ -187,9 +187,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
187
187
|
- !ruby/object:Gem::Version
|
188
188
|
version: '0'
|
189
189
|
requirements: []
|
190
|
-
|
191
|
-
|
192
|
-
signing_key:
|
190
|
+
rubygems_version: 3.2.3
|
191
|
+
signing_key:
|
193
192
|
specification_version: 4
|
194
193
|
summary: IPv4/IPv6 address manipulation library
|
195
194
|
test_files: []
|