mirror of
https://github.com/ruby/ruby.git
synced 2026-10-28 16:36:20 +08:00
[ruby/ipaddr] extra multicast/unicast predicates
This adds the following predicate methods to IPAddr objects: * `#multicast?`: whether the ip address is multicast * `#link_local_multicast?`: whether the ip address is a link-local multicast it also alias `IPAddr#link_local?` as `IPAddr#link_local_unicast?`, which is more accurate (whether the original should be deprecated is probably a separate discussion). https://github.com/ruby/ipaddr/commit/332ae1ffbf
This commit is contained in:
1 parent
06d4c1d1a5
commit
bb472c530a
2 files changed
+84
-1
No files matched your search
+39
-1
@@ -328,7 +328,7 @@ class IPAddr
|
||||
end
|
||||
end
|
||||
|
||||
# Returns true if the ipaddr is a link-local address. IPv4
|
||||
# Returns true if the ipaddr is a link-local unicast address. IPv4
|
||||
# addresses in 169.254.0.0/16 reserved by RFC 3927 and link-local
|
||||
# IPv6 Unicast Addresses in fe80::/10 reserved by RFC 4291 are
|
||||
# considered link-local. Link-local IPv4 addresses in the
|
||||
@@ -347,6 +347,44 @@ class IPAddr
|
||||
end
|
||||
end
|
||||
|
||||
alias link_local_unicast? link_local?
|
||||
|
||||
# Returns true if the ipaddr is a multicast address. IPv4
|
||||
# addresses in 224.0.0.0/4 and IPv6 multicast addresses
|
||||
# in ff00::/8 are considered multicast. Multicast IPv4 addresses in the
|
||||
# IPv4-mapped IPv6 address range are also considered multicast.
|
||||
def multicast?
|
||||
case @family
|
||||
when Socket::AF_INET
|
||||
@addr & 0xf0000000 == 0xe0000000 # 224.0.0.0/4
|
||||
when Socket::AF_INET6
|
||||
@addr & 0xff00_0000_0000_0000_0000_0000_0000_0000 == 0xff00_0000_0000_0000_0000_0000_0000_0000 || # ff00::/8
|
||||
(@addr >> 32 == 0xffff &&
|
||||
@addr & 0xf0000000 == 0xe0000000 # ::ffff:224.0.0.0/4
|
||||
)
|
||||
else
|
||||
raise AddressFamilyError, "unsupported address family"
|
||||
end
|
||||
end
|
||||
|
||||
# Returns true if the ipaddr is a link-local multicast address. IPv4
|
||||
# addresses in 224.0.0.0/24 and link-local IPv6 Multicast Addresses in ff02::/16
|
||||
# are considered link-local multicast. Link-local multicast IPv4 addresses in the
|
||||
# IPv4-mapped IPv6 address range are also considered link-local multicast.
|
||||
def link_local_multicast?
|
||||
case @family
|
||||
when Socket::AF_INET
|
||||
@addr & 0xffffff00 == 0xe0000000 # 224.0.0.0/24 Local Network Control Block
|
||||
when Socket::AF_INET6
|
||||
@addr & 0xffff_0000_0000_0000_0000_0000_0000_0000 == 0xff02_0000_0000_0000_0000_0000_0000_0000 || # ff02::/16
|
||||
(@addr >> 32 == 0xffff && (
|
||||
@addr & 0xffff0000 == 0xe0000000 # ::ffff:224.0.0.0/24
|
||||
))
|
||||
else
|
||||
raise AddressFamilyError, "unsupported address family"
|
||||
end
|
||||
end
|
||||
|
||||
# Returns true if the ipaddr is an IPv4-mapped IPv6 address.
|
||||
def ipv4_mapped?
|
||||
return ipv6? && (@addr >> 32) == 0xffff
|
||||
|
||||
@@ -623,6 +623,51 @@ class TC_Operator < Test::Unit::TestCase
|
||||
assert_equal(false, IPAddr.new('2001:db8:1:1:0:ffff:a9fe:101').link_local?)
|
||||
end
|
||||
|
||||
def test_multicast?
|
||||
assert_equal(false, IPAddr.new('192.168.0.0').multicast?)
|
||||
assert_equal(false, IPAddr.new('169.254.1.1').multicast?)
|
||||
assert_equal(false, IPAddr.new('169.254.254.255').multicast?)
|
||||
|
||||
# notable ipv4 multicast addresses
|
||||
assert_equal(true, IPAddr.new('224.0.0.0').multicast?)
|
||||
assert_equal(true, IPAddr.new('224.0.0.1').multicast?)
|
||||
assert_equal(true, IPAddr.new('224.0.0.6').multicast?)
|
||||
assert_equal(true, IPAddr.new('224.0.1.41').multicast?)
|
||||
assert_equal(true, IPAddr.new('224.0.1.129').multicast?)
|
||||
assert_equal(true, IPAddr.new('224.0.23.12').multicast?)
|
||||
assert_equal(true, IPAddr.new('239.255.255.250').multicast?)
|
||||
assert_equal(true, IPAddr.new('239.255.255.253').multicast?)
|
||||
|
||||
assert_equal(false, IPAddr.new('::1').multicast?)
|
||||
assert_equal(false, IPAddr.new('::').multicast?)
|
||||
assert_equal(false, IPAddr.new('fb84:8bf7:e905::1').multicast?)
|
||||
|
||||
# notable ipv6 multicast addresses
|
||||
assert_equal(true, IPAddr.new('ff02::1').multicast?)
|
||||
assert_equal(true, IPAddr.new('ff02::2').multicast?)
|
||||
assert_equal(true, IPAddr.new('ff02::5').multicast?)
|
||||
assert_equal(true, IPAddr.new('ff02::6').multicast?)
|
||||
assert_equal(true, IPAddr.new('ff02::8').multicast?)
|
||||
assert_equal(true, IPAddr.new('ff02::1:2').multicast?)
|
||||
assert_equal(true, IPAddr.new('ff02::1:3').multicast?)
|
||||
assert_equal(true, IPAddr.new('ff05::101').multicast?)
|
||||
end
|
||||
|
||||
def test_link_local_multicast?
|
||||
assert_equal(false, IPAddr.new('192.168.0.0').link_local_multicast?)
|
||||
assert_equal(false, IPAddr.new('169.254.1.1').link_local_multicast?)
|
||||
assert_equal(false, IPAddr.new('169.254.254.255').link_local_multicast?)
|
||||
assert_equal(false, IPAddr.new('239.0.0.0').link_local_multicast?)
|
||||
|
||||
assert_equal(true, IPAddr.new('224.0.0.0').link_local_multicast?)
|
||||
|
||||
assert_equal(false, IPAddr.new('::1').link_local_multicast?)
|
||||
assert_equal(false, IPAddr.new('::').link_local_multicast?)
|
||||
assert_equal(false, IPAddr.new('ff05::1').link_local_multicast?)
|
||||
assert_equal(true, IPAddr.new('ff02::1').link_local_multicast?)
|
||||
assert_equal(true, IPAddr.new('ff02::2').link_local_multicast?)
|
||||
end
|
||||
|
||||
def test_hash
|
||||
a1 = IPAddr.new('192.168.2.0')
|
||||
a2 = IPAddr.new('192.168.2.0')
|
||||
|
||||
Reference in new issue
Block a user