summaryrefslogtreecommitdiff
diff options
authorSimon Quigley <tsimonq2@debian.org>2025-10-14 12:49:11 -0500
committergit-ubuntu importer <ubuntu-devel-discuss@lists.ubuntu.com>2025-10-14 22:44:42 +0000
commit26565ebcfe983dbe110b5defa29a9ca4f9086c93 (patch)
tree2c48522cf612df1c68f5e1207a2266524367a520
parent73c89b2f3d04eb20ae3cc0f4d4548e82e3745f19 (diff)
parentab6a564f39c9c4e1e85537f5ae104a1bfb3088ab (diff)
Imported using git-ubuntu import.
-rw-r--r--README.md2
-rw-r--r--debian/changelog8
-rw-r--r--debian/control2
-rw-r--r--debian/gbp.conf4
-rw-r--r--debian/salsa-ci.yml3
-rw-r--r--lib/ipaddr.rb126
6 files changed, 107 insertions, 38 deletions
diff --git a/README.md b/README.md
index 8c2fd7b..edb2533 100644
--- a/README.md
+++ b/README.md
@@ -3,7 +3,7 @@
IPAddr provides a set of methods to manipulate an IP address. Both
IPv4 and IPv6 are supported.
-[![Build Status](https://travis-ci.org/ruby/ipaddr.svg?branch=master)](https://travis-ci.org/ruby/ipaddr)
+[![build](https://github.com/ruby/ipaddr/actions/workflows/test.yml/badge.svg)](https://github.com/ruby/ipaddr/actions/workflows/test.yml)
## Installation
diff --git a/debian/changelog b/debian/changelog
index 6563606..5ed45cf 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,11 @@
+ruby-ipaddr (1.2.7-1) unstable; urgency=medium
+
+ * Team upload.
+ * New upstream release.
+ * Update Standards-Version to 4.7.2, no changes needed.
+
+ -- Simon Quigley <tsimonq2@debian.org> Tue, 14 Oct 2025 12:49:11 -0500
+
ruby-ipaddr (1.2.5-1) unstable; urgency=medium
* Team Upload
diff --git a/debian/control b/debian/control
index 2df56ee..0b3c733 100644
--- a/debian/control
+++ b/debian/control
@@ -5,7 +5,7 @@ Maintainer: Debian Ruby Team <pkg-ruby-extras-maintainers@lists.alioth.debian.or
Uploaders: Vinay Keshava <vinaykeshava@disroot.org>
Build-Depends: debhelper-compat (= 13),
gem2deb (>= 2.1~)
-Standards-Version: 4.6.2
+Standards-Version: 4.7.2
Vcs-Git: https://salsa.debian.org/ruby-team/ruby-ipaddr.git
Vcs-Browser: https://salsa.debian.org/ruby-team/ruby-ipaddr
Homepage: https://github.com/ruby/ipaddr
diff --git a/debian/gbp.conf b/debian/gbp.conf
new file mode 100644
index 0000000..6b65fe0
--- /dev/null
+++ b/debian/gbp.conf
@@ -0,0 +1,4 @@
+[DEFAULT]
+debian-branch = debian/latest
+upstream-branch = upstream/latest
+pristine-tar = True
diff --git a/debian/salsa-ci.yml b/debian/salsa-ci.yml
index 33c3a64..7b5d2f7 100644
--- a/debian/salsa-ci.yml
+++ b/debian/salsa-ci.yml
@@ -1,4 +1,3 @@
---
include:
- - https://salsa.debian.org/salsa-ci-team/pipeline/raw/master/salsa-ci.yml
- - https://salsa.debian.org/salsa-ci-team/pipeline/raw/master/pipeline-jobs.yml
+ - https://salsa.debian.org/ruby-team/meta/raw/master/salsa-ci.yml
diff --git a/lib/ipaddr.rb b/lib/ipaddr.rb
index 7a5cf94..a450554 100644
--- a/lib/ipaddr.rb
+++ b/lib/ipaddr.rb
@@ -40,7 +40,7 @@ require 'socket'
# p ipaddr3 #=> #<IPAddr: IPv4:192.168.2.0/255.255.255.0>
class IPAddr
- VERSION = "1.2.5"
+ VERSION = "1.2.7"
# 32 bit mask for IPv4
IN4MASK = 0xffffffff
@@ -52,7 +52,7 @@ class IPAddr
# Regexp _internally_ used for parsing IPv4 address.
RE_IPV4ADDRLIKE = %r{
\A
- (\d+) \. (\d+) \. (\d+) \. (\d+)
+ \d+ \. \d+ \. \d+ \. \d+
\z
}x
@@ -110,8 +110,13 @@ class IPAddr
# Convert a network byte ordered string form of an IP address into
# human readable form.
+ # It expects the string to be encoded in Encoding::ASCII_8BIT (BINARY).
def self.ntop(addr)
- case addr.size
+ if addr.is_a?(String) && addr.encoding != Encoding::BINARY
+ raise InvalidAddressError, "invalid encoding (given #{addr.encoding}, expected BINARY)"
+ end
+
+ case addr.bytesize
when 4
addr.unpack('C4').join('.')
when 16
@@ -176,9 +181,7 @@ class IPAddr
def include?(other)
other = coerce_other(other)
return false unless other.family == family
- range = to_range
- other = other.to_range
- range.begin <= other.begin && range.end >= other.end
+ begin_addr <= other.begin_addr && end_addr >= other.end_addr
end
alias === include?
@@ -224,6 +227,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
@@ -249,12 +274,17 @@ class IPAddr
end
# Returns true if the ipaddr is a loopback address.
+ # Loopback IPv4 addresses in the IPv4-mapped IPv6
+ # address range are also considered as loopback addresses.
def loopback?
case @family
when Socket::AF_INET
- @addr & 0xff000000 == 0x7f000000
+ @addr & 0xff000000 == 0x7f000000 # 127.0.0.1/8
when Socket::AF_INET6
- @addr == 1
+ @addr == 1 || # ::1
+ (@addr & 0xffff_0000_0000 == 0xffff_0000_0000 && (
+ @addr & 0xff000000 == 0x7f000000 # ::ffff:127.0.0.1/8
+ ))
else
raise AddressFamilyError, "unsupported address family"
end
@@ -263,7 +293,8 @@ class IPAddr
# Returns true if the ipaddr is a private address. IPv4 addresses
# in 10.0.0.0/8, 172.16.0.0/12 and 192.168.0.0/16 as defined in RFC
# 1918 and IPv6 Unique Local Addresses in fc00::/7 as defined in RFC
- # 4193 are considered private.
+ # 4193 are considered private. Private IPv4 addresses in the
+ # IPv4-mapped IPv6 address range are also considered private.
def private?
case @family
when Socket::AF_INET
@@ -271,22 +302,31 @@ class IPAddr
@addr & 0xfff00000 == 0xac100000 || # 172.16.0.0/12
@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 & 0xfe00_0000_0000_0000_0000_0000_0000_0000 == 0xfc00_0000_0000_0000_0000_0000_0000_0000 ||
+ (@addr & 0xffff_0000_0000 == 0xffff_0000_0000 && (
+ @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
+ ))
else
raise AddressFamilyError, "unsupported address family"
end
end
# Returns true if the ipaddr is a link-local address. IPv4
- # addresses in 169.254.0.0/16 reserved by RFC 3927 and Link-Local
+ # 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.
+ # considered link-local. Link-local IPv4 addresses in the
+ # IPv4-mapped IPv6 address range are also considered link-local.
def link_local?
case @family
when Socket::AF_INET
@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
+ @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 & 0xffff0000 == 0xa9fe0000 # ::ffff:169.254.0.0/16
+ ))
else
raise AddressFamilyError, "unsupported address family"
end
@@ -400,17 +440,6 @@ class IPAddr
# Creates a Range object for the network address.
def to_range
- begin_addr = (@addr & @mask_addr)
-
- case @family
- when Socket::AF_INET
- end_addr = (@addr | (IN4MASK ^ @mask_addr))
- when Socket::AF_INET6
- end_addr = (@addr | (IN6MASK ^ @mask_addr))
- else
- raise AddressFamilyError, "unsupported address family"
- end
-
self.class.new(begin_addr, @family)..self.class.new(end_addr, @family)
end
@@ -439,7 +468,7 @@ class IPAddr
when Integer
mask!(prefix)
else
- raise InvalidPrefixError, "prefix must be an integer: #{@addr}"
+ raise InvalidPrefixError, "prefix must be an integer"
end
end
@@ -464,6 +493,20 @@ class IPAddr
_to_string(@mask_addr)
end
+ # Returns the wildcard mask in string format e.g. 0.0.255.255
+ def wildcard_mask
+ case @family
+ when Socket::AF_INET
+ mask = IN4MASK ^ @mask_addr
+ when Socket::AF_INET6
+ mask = IN6MASK ^ @mask_addr
+ else
+ raise AddressFamilyError, "unsupported address family"
+ end
+
+ _to_string(mask)
+ end
+
# Returns the IPv6 zone identifier, if present.
# Raises InvalidAddressError if not an IPv6 address.
def zone_id
@@ -491,6 +534,21 @@ class IPAddr
protected
+ def begin_addr
+ @addr & @mask_addr
+ end
+
+ def end_addr
+ case @family
+ when Socket::AF_INET
+ @addr | (IN4MASK ^ @mask_addr)
+ when Socket::AF_INET6
+ @addr | (IN6MASK ^ @mask_addr)
+ else
+ raise AddressFamilyError, "unsupported address family"
+ end
+ end
+
# Set +@addr+, the internal stored ip address, to given +addr+. The
# parameter +addr+ is validated using the first +family+ member,
# which is +Socket::AF_INET+ or +Socket::AF_INET6+.
@@ -498,11 +556,11 @@ class IPAddr
case family[0] ? family[0] : @family
when Socket::AF_INET
if addr < 0 || addr > IN4MASK
- raise InvalidAddressError, "invalid address: #{@addr}"
+ raise InvalidAddressError, "invalid address: #{addr}"
end
when Socket::AF_INET6
if addr < 0 || addr > IN6MASK
- raise InvalidAddressError, "invalid address: #{@addr}"
+ raise InvalidAddressError, "invalid address: #{addr}"
end
else
raise AddressFamilyError, "unsupported address family"
@@ -529,12 +587,12 @@ class IPAddr
else
m = IPAddr.new(mask)
if m.family != @family
- raise InvalidPrefixError, "address family is not same: #{@addr}"
+ raise InvalidPrefixError, "address family is not same"
end
@mask_addr = m.to_i
n = @mask_addr ^ m.instance_variable_get(:@mask_addr)
unless ((n + 1) & n).zero?
- raise InvalidPrefixError, "invalid mask #{mask}: #{@addr}"
+ raise InvalidPrefixError, "invalid mask #{mask}"
end
@addr &= @mask_addr
return self
@@ -545,13 +603,13 @@ class IPAddr
case @family
when Socket::AF_INET
if prefixlen < 0 || prefixlen > 32
- raise InvalidPrefixError, "invalid length: #{@addr}"
+ raise InvalidPrefixError, "invalid length"
end
masklen = 32 - prefixlen
@mask_addr = ((IN4MASK >> masklen) << masklen)
when Socket::AF_INET6
if prefixlen < 0 || prefixlen > 128
- raise InvalidPrefixError, "invalid length: #{@addr}"
+ raise InvalidPrefixError, "invalid length"
end
masklen = 128 - prefixlen
@mask_addr = ((IN6MASK >> masklen) << masklen)
@@ -647,12 +705,12 @@ class IPAddr
when Array
octets = addr
else
- m = RE_IPV4ADDRLIKE.match(addr) or return nil
- octets = m.captures
+ RE_IPV4ADDRLIKE.match?(addr) or return nil
+ octets = addr.split('.')
end
octets.inject(0) { |i, s|
(n = s.to_i) < 256 or raise InvalidAddressError, "invalid address: #{@addr}"
- s.match(/\A0./) and raise InvalidAddressError, "zero-filled number in IPv4 address is ambiguous: #{@addr}"
+ (s != '0') && s.start_with?('0') and raise InvalidAddressError, "zero-filled number in IPv4 address is ambiguous: #{@addr}"
i << 8 | n
}
end