diff options
Diffstat (limited to 'lib/ipaddr.rb')
| -rw-r--r-- | lib/ipaddr.rb | 78 |
1 files changed, 60 insertions, 18 deletions
diff --git a/lib/ipaddr.rb b/lib/ipaddr.rb index c1073ecd2b..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.6" + # 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 @@ -227,6 +242,28 @@ class IPAddr return str end + # Returns a string containing the IP address representation with prefix. + def as_json(*) + if ipv4? && prefix == 32 + to_s + elsif ipv6? && prefix == 128 + to_s + else + cidr + end + end + + # Returns a json string containing the IP address representation. + def to_json(*a) + %Q{"#{as_json(*a)}"} + end + + # Returns a string containing the IP address representation in + # cidr notation + def cidr + "#{to_s}/#{prefix}" + end + # Returns a network byte ordered string form of the IP address. def hton case @family @@ -260,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 @@ -281,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" @@ -302,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 @@ -321,7 +358,7 @@ class IPAddr _ipv4_compat? end - def _ipv4_compat? + def _ipv4_compat? # :nodoc: if !ipv6? || (@addr >> 32) != 0 return false end @@ -335,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) @@ -347,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 @@ -378,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 @@ -386,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 @@ -511,6 +550,7 @@ class IPAddr end protected + # :stopdoc: def begin_addr @addr & @mask_addr @@ -526,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, @@ -667,6 +708,7 @@ class IPAddr end end + # :stopdoc: def coerce_other(other) case other when IPAddr @@ -687,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 @@ -705,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(':') @@ -778,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 |
