ipaddr 1.2.6 → 1.2.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/lib/ipaddr.rb +68 -18
- 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
|
-
[![
|
6
|
+
[![build](https://github.com/ruby/ipaddr/actions/workflows/test.yml/badge.svg)](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
|
@@ -222,6 +227,28 @@ class IPAddr
|
|
222
227
|
return str
|
223
228
|
end
|
224
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
|
+
|
225
252
|
# Returns a network byte ordered string form of the IP address.
|
226
253
|
def hton
|
227
254
|
case @family
|
@@ -247,12 +274,17 @@ class IPAddr
|
|
247
274
|
end
|
248
275
|
|
249
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.
|
250
279
|
def loopback?
|
251
280
|
case @family
|
252
281
|
when Socket::AF_INET
|
253
|
-
@addr & 0xff000000 == 0x7f000000
|
282
|
+
@addr & 0xff000000 == 0x7f000000 # 127.0.0.1/8
|
254
283
|
when Socket::AF_INET6
|
255
|
-
@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
|
+
))
|
256
288
|
else
|
257
289
|
raise AddressFamilyError, "unsupported address family"
|
258
290
|
end
|
@@ -282,15 +314,19 @@ class IPAddr
|
|
282
314
|
end
|
283
315
|
|
284
316
|
# Returns true if the ipaddr is a link-local address. IPv4
|
285
|
-
# 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
|
286
318
|
# IPv6 Unicast Addresses in fe80::/10 reserved by RFC 4291 are
|
287
|
-
# considered link-local.
|
319
|
+
# considered link-local. Link-local IPv4 addresses in the
|
320
|
+
# IPv4-mapped IPv6 address range are also considered link-local.
|
288
321
|
def link_local?
|
289
322
|
case @family
|
290
323
|
when Socket::AF_INET
|
291
324
|
@addr & 0xffff0000 == 0xa9fe0000 # 169.254.0.0/16
|
292
325
|
when Socket::AF_INET6
|
293
|
-
@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
|
+
))
|
294
330
|
else
|
295
331
|
raise AddressFamilyError, "unsupported address family"
|
296
332
|
end
|
@@ -432,7 +468,7 @@ class IPAddr
|
|
432
468
|
when Integer
|
433
469
|
mask!(prefix)
|
434
470
|
else
|
435
|
-
raise InvalidPrefixError, "prefix must be an integer
|
471
|
+
raise InvalidPrefixError, "prefix must be an integer"
|
436
472
|
end
|
437
473
|
end
|
438
474
|
|
@@ -457,6 +493,20 @@ class IPAddr
|
|
457
493
|
_to_string(@mask_addr)
|
458
494
|
end
|
459
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
|
+
|
460
510
|
# Returns the IPv6 zone identifier, if present.
|
461
511
|
# Raises InvalidAddressError if not an IPv6 address.
|
462
512
|
def zone_id
|
@@ -506,11 +556,11 @@ class IPAddr
|
|
506
556
|
case family[0] ? family[0] : @family
|
507
557
|
when Socket::AF_INET
|
508
558
|
if addr < 0 || addr > IN4MASK
|
509
|
-
raise InvalidAddressError, "invalid address: #{
|
559
|
+
raise InvalidAddressError, "invalid address: #{addr}"
|
510
560
|
end
|
511
561
|
when Socket::AF_INET6
|
512
562
|
if addr < 0 || addr > IN6MASK
|
513
|
-
raise InvalidAddressError, "invalid address: #{
|
563
|
+
raise InvalidAddressError, "invalid address: #{addr}"
|
514
564
|
end
|
515
565
|
else
|
516
566
|
raise AddressFamilyError, "unsupported address family"
|
@@ -537,12 +587,12 @@ class IPAddr
|
|
537
587
|
else
|
538
588
|
m = IPAddr.new(mask)
|
539
589
|
if m.family != @family
|
540
|
-
raise InvalidPrefixError, "address family is not same
|
590
|
+
raise InvalidPrefixError, "address family is not same"
|
541
591
|
end
|
542
592
|
@mask_addr = m.to_i
|
543
593
|
n = @mask_addr ^ m.instance_variable_get(:@mask_addr)
|
544
594
|
unless ((n + 1) & n).zero?
|
545
|
-
raise InvalidPrefixError, "invalid mask #{mask}
|
595
|
+
raise InvalidPrefixError, "invalid mask #{mask}"
|
546
596
|
end
|
547
597
|
@addr &= @mask_addr
|
548
598
|
return self
|
@@ -553,13 +603,13 @@ class IPAddr
|
|
553
603
|
case @family
|
554
604
|
when Socket::AF_INET
|
555
605
|
if prefixlen < 0 || prefixlen > 32
|
556
|
-
raise InvalidPrefixError, "invalid length
|
606
|
+
raise InvalidPrefixError, "invalid length"
|
557
607
|
end
|
558
608
|
masklen = 32 - prefixlen
|
559
609
|
@mask_addr = ((IN4MASK >> masklen) << masklen)
|
560
610
|
when Socket::AF_INET6
|
561
611
|
if prefixlen < 0 || prefixlen > 128
|
562
|
-
raise InvalidPrefixError, "invalid length
|
612
|
+
raise InvalidPrefixError, "invalid length"
|
563
613
|
end
|
564
614
|
masklen = 128 - prefixlen
|
565
615
|
@mask_addr = ((IN6MASK >> masklen) << masklen)
|
@@ -655,12 +705,12 @@ class IPAddr
|
|
655
705
|
when Array
|
656
706
|
octets = addr
|
657
707
|
else
|
658
|
-
|
659
|
-
octets =
|
708
|
+
RE_IPV4ADDRLIKE.match?(addr) or return nil
|
709
|
+
octets = addr.split('.')
|
660
710
|
end
|
661
711
|
octets.inject(0) { |i, s|
|
662
712
|
(n = s.to_i) < 256 or raise InvalidAddressError, "invalid address: #{@addr}"
|
663
|
-
s.
|
713
|
+
(s != '0') && s.start_with?('0') and raise InvalidAddressError, "zero-filled number in IPv4 address is ambiguous: #{@addr}"
|
664
714
|
i << 8 | n
|
665
715
|
}
|
666
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.5.
|
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
|