summaryrefslogtreecommitdiff
path: root/lib/ipaddr.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ipaddr.rb')
-rw-r--r--lib/ipaddr.rb56
1 files changed, 38 insertions, 18 deletions
diff --git a/lib/ipaddr.rb b/lib/ipaddr.rb
index a45055496c..70b804f642 100644
--- a/lib/ipaddr.rb
+++ b/lib/ipaddr.rb
@@ -40,7 +40,8 @@ require 'socket'
# p ipaddr3 #=> #<IPAddr: IPv4:192.168.2.0/255.255.255.0>
class IPAddr
- VERSION = "1.2.7"
+ # The version string
+ VERSION = "1.2.9"
# 32 bit mask for IPv4
IN4MASK = 0xffffffff
@@ -151,8 +152,22 @@ class IPAddr
return self.clone.set(addr_mask(~@addr))
end
+ # Returns a new ipaddr greater than the original address by offset
+ def +(offset)
+ self.clone.set(@addr + offset, @family)
+ end
+
+ # Returns a new ipaddr less than the original address by offset
+ def -(offset)
+ self.clone.set(@addr - offset, @family)
+ end
+
# Returns true if two ipaddrs are equal.
def ==(other)
+ if other.nil?
+ return false
+ end
+
other = coerce_other(other)
rescue
false
@@ -282,7 +297,7 @@ class IPAddr
@addr & 0xff000000 == 0x7f000000 # 127.0.0.1/8
when Socket::AF_INET6
@addr == 1 || # ::1
- (@addr & 0xffff_0000_0000 == 0xffff_0000_0000 && (
+ (@addr >> 32 == 0xffff && (
@addr & 0xff000000 == 0x7f000000 # ::ffff:127.0.0.1/8
))
else
@@ -303,10 +318,10 @@ class IPAddr
@addr & 0xffff0000 == 0xc0a80000 # 192.168.0.0/16
when Socket::AF_INET6
@addr & 0xfe00_0000_0000_0000_0000_0000_0000_0000 == 0xfc00_0000_0000_0000_0000_0000_0000_0000 ||
- (@addr & 0xffff_0000_0000 == 0xffff_0000_0000 && (
+ (@addr >> 32 == 0xffff && (
@addr & 0xff000000 == 0x0a000000 || # ::ffff:10.0.0.0/8
- @addr & 0xfff00000 == 0xac100000 || # ::ffff::172.16.0.0/12
- @addr & 0xffff0000 == 0xc0a80000 # ::ffff::192.168.0.0/16
+ @addr & 0xfff00000 == 0xac100000 || # ::ffff:172.16.0.0/12
+ @addr & 0xffff0000 == 0xc0a80000 # ::ffff:192.168.0.0/16
))
else
raise AddressFamilyError, "unsupported address family"
@@ -324,7 +339,7 @@ class IPAddr
@addr & 0xffff0000 == 0xa9fe0000 # 169.254.0.0/16
when Socket::AF_INET6
@addr & 0xffc0_0000_0000_0000_0000_0000_0000_0000 == 0xfe80_0000_0000_0000_0000_0000_0000_0000 || # fe80::/10
- (@addr & 0xffff_0000_0000 == 0xffff_0000_0000 && (
+ (@addr >> 32 == 0xffff && (
@addr & 0xffff0000 == 0xa9fe0000 # ::ffff:169.254.0.0/16
))
else
@@ -343,7 +358,7 @@ class IPAddr
_ipv4_compat?
end
- def _ipv4_compat?
+ def _ipv4_compat? # :nodoc:
if !ipv6? || (@addr >> 32) != 0
return false
end
@@ -357,7 +372,7 @@ class IPAddr
# into an IPv4-mapped IPv6 address.
def ipv4_mapped
if !ipv4?
- raise InvalidAddressError, "not an IPv4 address: #{@addr}"
+ raise InvalidAddressError, "not an IPv4 address: #{to_s}"
end
clone = self.clone.set(@addr | 0xffff00000000, Socket::AF_INET6)
clone.instance_variable_set(:@mask_addr, @mask_addr | 0xffffffffffffffffffffffff00000000)
@@ -369,9 +384,11 @@ class IPAddr
def ipv4_compat
warn "IPAddr\##{__callee__} is obsolete", uplevel: 1 if $VERBOSE
if !ipv4?
- raise InvalidAddressError, "not an IPv4 address: #{@addr}"
+ raise InvalidAddressError, "not an IPv4 address: #{to_s}"
end
- return self.clone.set(@addr, Socket::AF_INET6)
+ clone = self.clone.set(@addr, Socket::AF_INET6)
+ clone.instance_variable_set(:@mask_addr, @mask_addr | 0xffffffffffffffffffffffff00000000)
+ clone
end
# Returns a new ipaddr built by converting the IPv6 address into a
@@ -400,7 +417,7 @@ class IPAddr
# Returns a string for DNS reverse lookup compatible with RFC3172.
def ip6_arpa
if !ipv6?
- raise InvalidAddressError, "not an IPv6 address: #{@addr}"
+ raise InvalidAddressError, "not an IPv6 address: #{to_s}"
end
return _reverse + ".ip6.arpa"
end
@@ -408,7 +425,7 @@ class IPAddr
# Returns a string for DNS reverse lookup compatible with RFC1886.
def ip6_int
if !ipv6?
- raise InvalidAddressError, "not an IPv6 address: #{@addr}"
+ raise InvalidAddressError, "not an IPv6 address: #{to_s}"
end
return _reverse + ".ip6.int"
end
@@ -533,6 +550,7 @@ class IPAddr
end
protected
+ # :stopdoc:
def begin_addr
@addr & @mask_addr
@@ -548,6 +566,7 @@ class IPAddr
raise AddressFamilyError, "unsupported address family"
end
end
+ #:startdoc:
# Set +@addr+, the internal stored ip address, to given +addr+. The
# parameter +addr+ is validated using the first +family+ member,
@@ -689,6 +708,7 @@ class IPAddr
end
end
+ # :stopdoc:
def coerce_other(other)
case other
when IPAddr
@@ -709,8 +729,8 @@ class IPAddr
octets = addr.split('.')
end
octets.inject(0) { |i, s|
- (n = s.to_i) < 256 or raise InvalidAddressError, "invalid address: #{@addr}"
- (s != '0') && s.start_with?('0') and raise InvalidAddressError, "zero-filled number in IPv4 address is ambiguous: #{@addr}"
+ (n = s.to_i) < 256 or raise InvalidAddressError, "invalid address: #{addr}"
+ (s != '0') && s.start_with?('0') and raise InvalidAddressError, "zero-filled number in IPv4 address is ambiguous: #{addr}"
i << 8 | n
}
end
@@ -727,19 +747,19 @@ class IPAddr
right = ''
when RE_IPV6ADDRLIKE_COMPRESSED
if $4
- left.count(':') <= 6 or raise InvalidAddressError, "invalid address: #{@addr}"
+ left.count(':') <= 6 or raise InvalidAddressError, "invalid address: #{left}"
addr = in_addr($~[4,4])
left = $1
right = $3 + '0:0'
else
left.count(':') <= ($1.empty? || $2.empty? ? 8 : 7) or
- raise InvalidAddressError, "invalid address: #{@addr}"
+ raise InvalidAddressError, "invalid address: #{left}"
left = $1
right = $2
addr = 0
end
else
- raise InvalidAddressError, "invalid address: #{@addr}"
+ raise InvalidAddressError, "invalid address: #{left}"
end
l = left.split(':')
r = right.split(':')
@@ -800,7 +820,7 @@ unless Socket.const_defined? :AF_INET6
class << IPSocket
private
- def valid_v6?(addr)
+ def valid_v6?(addr) # :nodoc:
case addr
when IPAddr::RE_IPV6ADDRLIKE_FULL
if $2