ipaddr 1.2.5 → 1.2.7
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/README.md +1 -1
- data/lib/ipaddr.rb +92 -34
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 566f76e26928f5a6014a11f985f08d1299dd06e7cb273cbc90b2553182b90006
|
4
|
+
data.tar.gz: f966e0490212bdb9194d05e6ee1d7e8df85ce622ed3692c46b2539c648e0315f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 02e29f8adc3da01f5db2c02101dab218015ab78c9b628060945bbbf328e10391962afd254c0ce5cb9d6a86d68486120f9298673ca9ff133325fd7df700804af6
|
7
|
+
data.tar.gz: b14fd4218bfdb839dee0fa22a334a217a39a8493ea9e7977684a0418819a337386727d0c47f67868848d018e7f7659f52dabeef686e20ad948a462683915d69c
|
data/README.md
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
IPAddr provides a set of methods to manipulate an IP address. Both
|
4
4
|
IPv4 and IPv6 are supported.
|
5
5
|
|
6
|
-
[](https://github.com/ruby/ipaddr/actions/workflows/test.yml)
|
7
7
|
|
8
8
|
## Installation
|
9
9
|
|
data/lib/ipaddr.rb
CHANGED
@@ -40,7 +40,7 @@ require 'socket'
|
|
40
40
|
# p ipaddr3 #=> #<IPAddr: IPv4:192.168.2.0/255.255.255.0>
|
41
41
|
|
42
42
|
class IPAddr
|
43
|
-
VERSION = "1.2.
|
43
|
+
VERSION = "1.2.7"
|
44
44
|
|
45
45
|
# 32 bit mask for IPv4
|
46
46
|
IN4MASK = 0xffffffff
|
@@ -52,7 +52,7 @@ class IPAddr
|
|
52
52
|
# Regexp _internally_ used for parsing IPv4 address.
|
53
53
|
RE_IPV4ADDRLIKE = %r{
|
54
54
|
\A
|
55
|
-
|
55
|
+
\d+ \. \d+ \. \d+ \. \d+
|
56
56
|
\z
|
57
57
|
}x
|
58
58
|
|
@@ -110,8 +110,13 @@ class IPAddr
|
|
110
110
|
|
111
111
|
# Convert a network byte ordered string form of an IP address into
|
112
112
|
# human readable form.
|
113
|
+
# It expects the string to be encoded in Encoding::ASCII_8BIT (BINARY).
|
113
114
|
def self.ntop(addr)
|
114
|
-
|
115
|
+
if addr.is_a?(String) && addr.encoding != Encoding::BINARY
|
116
|
+
raise InvalidAddressError, "invalid encoding (given #{addr.encoding}, expected BINARY)"
|
117
|
+
end
|
118
|
+
|
119
|
+
case addr.bytesize
|
115
120
|
when 4
|
116
121
|
addr.unpack('C4').join('.')
|
117
122
|
when 16
|
@@ -176,9 +181,7 @@ class IPAddr
|
|
176
181
|
def include?(other)
|
177
182
|
other = coerce_other(other)
|
178
183
|
return false unless other.family == family
|
179
|
-
|
180
|
-
other = other.to_range
|
181
|
-
range.begin <= other.begin && range.end >= other.end
|
184
|
+
begin_addr <= other.begin_addr && end_addr >= other.end_addr
|
182
185
|
end
|
183
186
|
alias === include?
|
184
187
|
|
@@ -224,6 +227,28 @@ class IPAddr
|
|
224
227
|
return str
|
225
228
|
end
|
226
229
|
|
230
|
+
# Returns a string containing the IP address representation with prefix.
|
231
|
+
def as_json(*)
|
232
|
+
if ipv4? && prefix == 32
|
233
|
+
to_s
|
234
|
+
elsif ipv6? && prefix == 128
|
235
|
+
to_s
|
236
|
+
else
|
237
|
+
cidr
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
241
|
+
# Returns a json string containing the IP address representation.
|
242
|
+
def to_json(*a)
|
243
|
+
%Q{"#{as_json(*a)}"}
|
244
|
+
end
|
245
|
+
|
246
|
+
# Returns a string containing the IP address representation in
|
247
|
+
# cidr notation
|
248
|
+
def cidr
|
249
|
+
"#{to_s}/#{prefix}"
|
250
|
+
end
|
251
|
+
|
227
252
|
# Returns a network byte ordered string form of the IP address.
|
228
253
|
def hton
|
229
254
|
case @family
|
@@ -249,12 +274,17 @@ class IPAddr
|
|
249
274
|
end
|
250
275
|
|
251
276
|
# Returns true if the ipaddr is a loopback address.
|
277
|
+
# Loopback IPv4 addresses in the IPv4-mapped IPv6
|
278
|
+
# address range are also considered as loopback addresses.
|
252
279
|
def loopback?
|
253
280
|
case @family
|
254
281
|
when Socket::AF_INET
|
255
|
-
@addr & 0xff000000 == 0x7f000000
|
282
|
+
@addr & 0xff000000 == 0x7f000000 # 127.0.0.1/8
|
256
283
|
when Socket::AF_INET6
|
257
|
-
@addr == 1
|
284
|
+
@addr == 1 || # ::1
|
285
|
+
(@addr & 0xffff_0000_0000 == 0xffff_0000_0000 && (
|
286
|
+
@addr & 0xff000000 == 0x7f000000 # ::ffff:127.0.0.1/8
|
287
|
+
))
|
258
288
|
else
|
259
289
|
raise AddressFamilyError, "unsupported address family"
|
260
290
|
end
|
@@ -263,7 +293,8 @@ class IPAddr
|
|
263
293
|
# Returns true if the ipaddr is a private address. IPv4 addresses
|
264
294
|
# in 10.0.0.0/8, 172.16.0.0/12 and 192.168.0.0/16 as defined in RFC
|
265
295
|
# 1918 and IPv6 Unique Local Addresses in fc00::/7 as defined in RFC
|
266
|
-
# 4193 are considered private.
|
296
|
+
# 4193 are considered private. Private IPv4 addresses in the
|
297
|
+
# IPv4-mapped IPv6 address range are also considered private.
|
267
298
|
def private?
|
268
299
|
case @family
|
269
300
|
when Socket::AF_INET
|
@@ -271,22 +302,31 @@ class IPAddr
|
|
271
302
|
@addr & 0xfff00000 == 0xac100000 || # 172.16.0.0/12
|
272
303
|
@addr & 0xffff0000 == 0xc0a80000 # 192.168.0.0/16
|
273
304
|
when Socket::AF_INET6
|
274
|
-
@addr & 0xfe00_0000_0000_0000_0000_0000_0000_0000 == 0xfc00_0000_0000_0000_0000_0000_0000_0000
|
305
|
+
@addr & 0xfe00_0000_0000_0000_0000_0000_0000_0000 == 0xfc00_0000_0000_0000_0000_0000_0000_0000 ||
|
306
|
+
(@addr & 0xffff_0000_0000 == 0xffff_0000_0000 && (
|
307
|
+
@addr & 0xff000000 == 0x0a000000 || # ::ffff:10.0.0.0/8
|
308
|
+
@addr & 0xfff00000 == 0xac100000 || # ::ffff::172.16.0.0/12
|
309
|
+
@addr & 0xffff0000 == 0xc0a80000 # ::ffff::192.168.0.0/16
|
310
|
+
))
|
275
311
|
else
|
276
312
|
raise AddressFamilyError, "unsupported address family"
|
277
313
|
end
|
278
314
|
end
|
279
315
|
|
280
316
|
# Returns true if the ipaddr is a link-local address. IPv4
|
281
|
-
# addresses in 169.254.0.0/16 reserved by RFC 3927 and
|
317
|
+
# addresses in 169.254.0.0/16 reserved by RFC 3927 and link-local
|
282
318
|
# IPv6 Unicast Addresses in fe80::/10 reserved by RFC 4291 are
|
283
|
-
# considered link-local.
|
319
|
+
# considered link-local. Link-local IPv4 addresses in the
|
320
|
+
# IPv4-mapped IPv6 address range are also considered link-local.
|
284
321
|
def link_local?
|
285
322
|
case @family
|
286
323
|
when Socket::AF_INET
|
287
324
|
@addr & 0xffff0000 == 0xa9fe0000 # 169.254.0.0/16
|
288
325
|
when Socket::AF_INET6
|
289
|
-
@addr & 0xffc0_0000_0000_0000_0000_0000_0000_0000 == 0xfe80_0000_0000_0000_0000_0000_0000_0000
|
326
|
+
@addr & 0xffc0_0000_0000_0000_0000_0000_0000_0000 == 0xfe80_0000_0000_0000_0000_0000_0000_0000 || # fe80::/10
|
327
|
+
(@addr & 0xffff_0000_0000 == 0xffff_0000_0000 && (
|
328
|
+
@addr & 0xffff0000 == 0xa9fe0000 # ::ffff:169.254.0.0/16
|
329
|
+
))
|
290
330
|
else
|
291
331
|
raise AddressFamilyError, "unsupported address family"
|
292
332
|
end
|
@@ -400,17 +440,6 @@ class IPAddr
|
|
400
440
|
|
401
441
|
# Creates a Range object for the network address.
|
402
442
|
def to_range
|
403
|
-
begin_addr = (@addr & @mask_addr)
|
404
|
-
|
405
|
-
case @family
|
406
|
-
when Socket::AF_INET
|
407
|
-
end_addr = (@addr | (IN4MASK ^ @mask_addr))
|
408
|
-
when Socket::AF_INET6
|
409
|
-
end_addr = (@addr | (IN6MASK ^ @mask_addr))
|
410
|
-
else
|
411
|
-
raise AddressFamilyError, "unsupported address family"
|
412
|
-
end
|
413
|
-
|
414
443
|
self.class.new(begin_addr, @family)..self.class.new(end_addr, @family)
|
415
444
|
end
|
416
445
|
|
@@ -439,7 +468,7 @@ class IPAddr
|
|
439
468
|
when Integer
|
440
469
|
mask!(prefix)
|
441
470
|
else
|
442
|
-
raise InvalidPrefixError, "prefix must be an integer
|
471
|
+
raise InvalidPrefixError, "prefix must be an integer"
|
443
472
|
end
|
444
473
|
end
|
445
474
|
|
@@ -464,6 +493,20 @@ class IPAddr
|
|
464
493
|
_to_string(@mask_addr)
|
465
494
|
end
|
466
495
|
|
496
|
+
# Returns the wildcard mask in string format e.g. 0.0.255.255
|
497
|
+
def wildcard_mask
|
498
|
+
case @family
|
499
|
+
when Socket::AF_INET
|
500
|
+
mask = IN4MASK ^ @mask_addr
|
501
|
+
when Socket::AF_INET6
|
502
|
+
mask = IN6MASK ^ @mask_addr
|
503
|
+
else
|
504
|
+
raise AddressFamilyError, "unsupported address family"
|
505
|
+
end
|
506
|
+
|
507
|
+
_to_string(mask)
|
508
|
+
end
|
509
|
+
|
467
510
|
# Returns the IPv6 zone identifier, if present.
|
468
511
|
# Raises InvalidAddressError if not an IPv6 address.
|
469
512
|
def zone_id
|
@@ -491,6 +534,21 @@ class IPAddr
|
|
491
534
|
|
492
535
|
protected
|
493
536
|
|
537
|
+
def begin_addr
|
538
|
+
@addr & @mask_addr
|
539
|
+
end
|
540
|
+
|
541
|
+
def end_addr
|
542
|
+
case @family
|
543
|
+
when Socket::AF_INET
|
544
|
+
@addr | (IN4MASK ^ @mask_addr)
|
545
|
+
when Socket::AF_INET6
|
546
|
+
@addr | (IN6MASK ^ @mask_addr)
|
547
|
+
else
|
548
|
+
raise AddressFamilyError, "unsupported address family"
|
549
|
+
end
|
550
|
+
end
|
551
|
+
|
494
552
|
# Set +@addr+, the internal stored ip address, to given +addr+. The
|
495
553
|
# parameter +addr+ is validated using the first +family+ member,
|
496
554
|
# which is +Socket::AF_INET+ or +Socket::AF_INET6+.
|
@@ -498,11 +556,11 @@ class IPAddr
|
|
498
556
|
case family[0] ? family[0] : @family
|
499
557
|
when Socket::AF_INET
|
500
558
|
if addr < 0 || addr > IN4MASK
|
501
|
-
raise InvalidAddressError, "invalid address: #{
|
559
|
+
raise InvalidAddressError, "invalid address: #{addr}"
|
502
560
|
end
|
503
561
|
when Socket::AF_INET6
|
504
562
|
if addr < 0 || addr > IN6MASK
|
505
|
-
raise InvalidAddressError, "invalid address: #{
|
563
|
+
raise InvalidAddressError, "invalid address: #{addr}"
|
506
564
|
end
|
507
565
|
else
|
508
566
|
raise AddressFamilyError, "unsupported address family"
|
@@ -529,12 +587,12 @@ class IPAddr
|
|
529
587
|
else
|
530
588
|
m = IPAddr.new(mask)
|
531
589
|
if m.family != @family
|
532
|
-
raise InvalidPrefixError, "address family is not same
|
590
|
+
raise InvalidPrefixError, "address family is not same"
|
533
591
|
end
|
534
592
|
@mask_addr = m.to_i
|
535
593
|
n = @mask_addr ^ m.instance_variable_get(:@mask_addr)
|
536
594
|
unless ((n + 1) & n).zero?
|
537
|
-
raise InvalidPrefixError, "invalid mask #{mask}
|
595
|
+
raise InvalidPrefixError, "invalid mask #{mask}"
|
538
596
|
end
|
539
597
|
@addr &= @mask_addr
|
540
598
|
return self
|
@@ -545,13 +603,13 @@ class IPAddr
|
|
545
603
|
case @family
|
546
604
|
when Socket::AF_INET
|
547
605
|
if prefixlen < 0 || prefixlen > 32
|
548
|
-
raise InvalidPrefixError, "invalid length
|
606
|
+
raise InvalidPrefixError, "invalid length"
|
549
607
|
end
|
550
608
|
masklen = 32 - prefixlen
|
551
609
|
@mask_addr = ((IN4MASK >> masklen) << masklen)
|
552
610
|
when Socket::AF_INET6
|
553
611
|
if prefixlen < 0 || prefixlen > 128
|
554
|
-
raise InvalidPrefixError, "invalid length
|
612
|
+
raise InvalidPrefixError, "invalid length"
|
555
613
|
end
|
556
614
|
masklen = 128 - prefixlen
|
557
615
|
@mask_addr = ((IN6MASK >> masklen) << masklen)
|
@@ -647,12 +705,12 @@ class IPAddr
|
|
647
705
|
when Array
|
648
706
|
octets = addr
|
649
707
|
else
|
650
|
-
|
651
|
-
octets =
|
708
|
+
RE_IPV4ADDRLIKE.match?(addr) or return nil
|
709
|
+
octets = addr.split('.')
|
652
710
|
end
|
653
711
|
octets.inject(0) { |i, s|
|
654
712
|
(n = s.to_i) < 256 or raise InvalidAddressError, "invalid address: #{@addr}"
|
655
|
-
s.
|
713
|
+
(s != '0') && s.start_with?('0') and raise InvalidAddressError, "zero-filled number in IPv4 address is ambiguous: #{@addr}"
|
656
714
|
i << 8 | n
|
657
715
|
}
|
658
716
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ipaddr
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.2.
|
4
|
+
version: 1.2.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Akinori MUSHA
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2024-10-19 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description: |
|
15
15
|
IPAddr provides a set of methods to manipulate an IP address.
|
@@ -45,7 +45,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
45
45
|
- !ruby/object:Gem::Version
|
46
46
|
version: '0'
|
47
47
|
requirements: []
|
48
|
-
rubygems_version: 3.
|
48
|
+
rubygems_version: 3.5.21
|
49
49
|
signing_key:
|
50
50
|
specification_version: 4
|
51
51
|
summary: A class to manipulate an IP address in ruby
|