ipaddr 1.2.6 → 1.2.8
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 +88 -22
- metadata +4 -8
- data/ipaddr.gemspec +0 -36
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 27c05756ec16e7913ff99aab584bbcddab9e5ef419e5f5fb17850a846c8e562d
|
|
4
|
+
data.tar.gz: 6845f685c7cfcee252d97e6e74f597991ba7586fc7104242e64ccad5abe9acfc
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 71535cdb0def5ae3bdc48c762f586c569dd3104e131da598620c43ac679b705e85dc48a45fa0142a69f98097d15dabdf3b427153cb39c283459a3d5d17471da6
|
|
7
|
+
data.tar.gz: 74c73fbf129bfdf9526e3e76269b7c82e75dbef4b63dda82868b465c83bcd29495e470fc1743664a5a065958e455fa53ca678ac8161427a0ab10b55c92b5dd05
|
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,8 @@ require 'socket'
|
|
|
40
40
|
# p ipaddr3 #=> #<IPAddr: IPv4:192.168.2.0/255.255.255.0>
|
|
41
41
|
|
|
42
42
|
class IPAddr
|
|
43
|
-
|
|
43
|
+
# The version string
|
|
44
|
+
VERSION = "1.2.8"
|
|
44
45
|
|
|
45
46
|
# 32 bit mask for IPv4
|
|
46
47
|
IN4MASK = 0xffffffff
|
|
@@ -52,7 +53,7 @@ class IPAddr
|
|
|
52
53
|
# Regexp _internally_ used for parsing IPv4 address.
|
|
53
54
|
RE_IPV4ADDRLIKE = %r{
|
|
54
55
|
\A
|
|
55
|
-
|
|
56
|
+
\d+ \. \d+ \. \d+ \. \d+
|
|
56
57
|
\z
|
|
57
58
|
}x
|
|
58
59
|
|
|
@@ -110,8 +111,13 @@ class IPAddr
|
|
|
110
111
|
|
|
111
112
|
# Convert a network byte ordered string form of an IP address into
|
|
112
113
|
# human readable form.
|
|
114
|
+
# It expects the string to be encoded in Encoding::ASCII_8BIT (BINARY).
|
|
113
115
|
def self.ntop(addr)
|
|
114
|
-
|
|
116
|
+
if addr.is_a?(String) && addr.encoding != Encoding::BINARY
|
|
117
|
+
raise InvalidAddressError, "invalid encoding (given #{addr.encoding}, expected BINARY)"
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
case addr.bytesize
|
|
115
121
|
when 4
|
|
116
122
|
addr.unpack('C4').join('.')
|
|
117
123
|
when 16
|
|
@@ -146,6 +152,16 @@ class IPAddr
|
|
|
146
152
|
return self.clone.set(addr_mask(~@addr))
|
|
147
153
|
end
|
|
148
154
|
|
|
155
|
+
# Returns a new ipaddr greater than the original address by offset
|
|
156
|
+
def +(offset)
|
|
157
|
+
self.clone.set(@addr + offset, @family)
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
# Returns a new ipaddr less than the original address by offset
|
|
161
|
+
def -(offset)
|
|
162
|
+
self.clone.set(@addr - offset, @family)
|
|
163
|
+
end
|
|
164
|
+
|
|
149
165
|
# Returns true if two ipaddrs are equal.
|
|
150
166
|
def ==(other)
|
|
151
167
|
other = coerce_other(other)
|
|
@@ -222,6 +238,28 @@ class IPAddr
|
|
|
222
238
|
return str
|
|
223
239
|
end
|
|
224
240
|
|
|
241
|
+
# Returns a string containing the IP address representation with prefix.
|
|
242
|
+
def as_json(*)
|
|
243
|
+
if ipv4? && prefix == 32
|
|
244
|
+
to_s
|
|
245
|
+
elsif ipv6? && prefix == 128
|
|
246
|
+
to_s
|
|
247
|
+
else
|
|
248
|
+
cidr
|
|
249
|
+
end
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
# Returns a json string containing the IP address representation.
|
|
253
|
+
def to_json(*a)
|
|
254
|
+
%Q{"#{as_json(*a)}"}
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
# Returns a string containing the IP address representation in
|
|
258
|
+
# cidr notation
|
|
259
|
+
def cidr
|
|
260
|
+
"#{to_s}/#{prefix}"
|
|
261
|
+
end
|
|
262
|
+
|
|
225
263
|
# Returns a network byte ordered string form of the IP address.
|
|
226
264
|
def hton
|
|
227
265
|
case @family
|
|
@@ -247,12 +285,17 @@ class IPAddr
|
|
|
247
285
|
end
|
|
248
286
|
|
|
249
287
|
# Returns true if the ipaddr is a loopback address.
|
|
288
|
+
# Loopback IPv4 addresses in the IPv4-mapped IPv6
|
|
289
|
+
# address range are also considered as loopback addresses.
|
|
250
290
|
def loopback?
|
|
251
291
|
case @family
|
|
252
292
|
when Socket::AF_INET
|
|
253
|
-
@addr & 0xff000000 == 0x7f000000
|
|
293
|
+
@addr & 0xff000000 == 0x7f000000 # 127.0.0.1/8
|
|
254
294
|
when Socket::AF_INET6
|
|
255
|
-
@addr == 1
|
|
295
|
+
@addr == 1 || # ::1
|
|
296
|
+
(@addr & 0xffff_0000_0000 == 0xffff_0000_0000 && (
|
|
297
|
+
@addr & 0xff000000 == 0x7f000000 # ::ffff:127.0.0.1/8
|
|
298
|
+
))
|
|
256
299
|
else
|
|
257
300
|
raise AddressFamilyError, "unsupported address family"
|
|
258
301
|
end
|
|
@@ -282,15 +325,19 @@ class IPAddr
|
|
|
282
325
|
end
|
|
283
326
|
|
|
284
327
|
# Returns true if the ipaddr is a link-local address. IPv4
|
|
285
|
-
# addresses in 169.254.0.0/16 reserved by RFC 3927 and
|
|
328
|
+
# addresses in 169.254.0.0/16 reserved by RFC 3927 and link-local
|
|
286
329
|
# IPv6 Unicast Addresses in fe80::/10 reserved by RFC 4291 are
|
|
287
|
-
# considered link-local.
|
|
330
|
+
# considered link-local. Link-local IPv4 addresses in the
|
|
331
|
+
# IPv4-mapped IPv6 address range are also considered link-local.
|
|
288
332
|
def link_local?
|
|
289
333
|
case @family
|
|
290
334
|
when Socket::AF_INET
|
|
291
335
|
@addr & 0xffff0000 == 0xa9fe0000 # 169.254.0.0/16
|
|
292
336
|
when Socket::AF_INET6
|
|
293
|
-
@addr & 0xffc0_0000_0000_0000_0000_0000_0000_0000 == 0xfe80_0000_0000_0000_0000_0000_0000_0000
|
|
337
|
+
@addr & 0xffc0_0000_0000_0000_0000_0000_0000_0000 == 0xfe80_0000_0000_0000_0000_0000_0000_0000 || # fe80::/10
|
|
338
|
+
(@addr & 0xffff_0000_0000 == 0xffff_0000_0000 && (
|
|
339
|
+
@addr & 0xffff0000 == 0xa9fe0000 # ::ffff:169.254.0.0/16
|
|
340
|
+
))
|
|
294
341
|
else
|
|
295
342
|
raise AddressFamilyError, "unsupported address family"
|
|
296
343
|
end
|
|
@@ -307,7 +354,7 @@ class IPAddr
|
|
|
307
354
|
_ipv4_compat?
|
|
308
355
|
end
|
|
309
356
|
|
|
310
|
-
def _ipv4_compat?
|
|
357
|
+
def _ipv4_compat? # :nodoc:
|
|
311
358
|
if !ipv6? || (@addr >> 32) != 0
|
|
312
359
|
return false
|
|
313
360
|
end
|
|
@@ -335,7 +382,9 @@ class IPAddr
|
|
|
335
382
|
if !ipv4?
|
|
336
383
|
raise InvalidAddressError, "not an IPv4 address: #{@addr}"
|
|
337
384
|
end
|
|
338
|
-
|
|
385
|
+
clone = self.clone.set(@addr, Socket::AF_INET6)
|
|
386
|
+
clone.instance_variable_set(:@mask_addr, @mask_addr | 0xffffffffffffffffffffffff00000000)
|
|
387
|
+
clone
|
|
339
388
|
end
|
|
340
389
|
|
|
341
390
|
# Returns a new ipaddr built by converting the IPv6 address into a
|
|
@@ -432,7 +481,7 @@ class IPAddr
|
|
|
432
481
|
when Integer
|
|
433
482
|
mask!(prefix)
|
|
434
483
|
else
|
|
435
|
-
raise InvalidPrefixError, "prefix must be an integer
|
|
484
|
+
raise InvalidPrefixError, "prefix must be an integer"
|
|
436
485
|
end
|
|
437
486
|
end
|
|
438
487
|
|
|
@@ -457,6 +506,20 @@ class IPAddr
|
|
|
457
506
|
_to_string(@mask_addr)
|
|
458
507
|
end
|
|
459
508
|
|
|
509
|
+
# Returns the wildcard mask in string format e.g. 0.0.255.255
|
|
510
|
+
def wildcard_mask
|
|
511
|
+
case @family
|
|
512
|
+
when Socket::AF_INET
|
|
513
|
+
mask = IN4MASK ^ @mask_addr
|
|
514
|
+
when Socket::AF_INET6
|
|
515
|
+
mask = IN6MASK ^ @mask_addr
|
|
516
|
+
else
|
|
517
|
+
raise AddressFamilyError, "unsupported address family"
|
|
518
|
+
end
|
|
519
|
+
|
|
520
|
+
_to_string(mask)
|
|
521
|
+
end
|
|
522
|
+
|
|
460
523
|
# Returns the IPv6 zone identifier, if present.
|
|
461
524
|
# Raises InvalidAddressError if not an IPv6 address.
|
|
462
525
|
def zone_id
|
|
@@ -483,6 +546,7 @@ class IPAddr
|
|
|
483
546
|
end
|
|
484
547
|
|
|
485
548
|
protected
|
|
549
|
+
# :stopdoc:
|
|
486
550
|
|
|
487
551
|
def begin_addr
|
|
488
552
|
@addr & @mask_addr
|
|
@@ -498,6 +562,7 @@ class IPAddr
|
|
|
498
562
|
raise AddressFamilyError, "unsupported address family"
|
|
499
563
|
end
|
|
500
564
|
end
|
|
565
|
+
#:startdoc:
|
|
501
566
|
|
|
502
567
|
# Set +@addr+, the internal stored ip address, to given +addr+. The
|
|
503
568
|
# parameter +addr+ is validated using the first +family+ member,
|
|
@@ -506,11 +571,11 @@ class IPAddr
|
|
|
506
571
|
case family[0] ? family[0] : @family
|
|
507
572
|
when Socket::AF_INET
|
|
508
573
|
if addr < 0 || addr > IN4MASK
|
|
509
|
-
raise InvalidAddressError, "invalid address: #{
|
|
574
|
+
raise InvalidAddressError, "invalid address: #{addr}"
|
|
510
575
|
end
|
|
511
576
|
when Socket::AF_INET6
|
|
512
577
|
if addr < 0 || addr > IN6MASK
|
|
513
|
-
raise InvalidAddressError, "invalid address: #{
|
|
578
|
+
raise InvalidAddressError, "invalid address: #{addr}"
|
|
514
579
|
end
|
|
515
580
|
else
|
|
516
581
|
raise AddressFamilyError, "unsupported address family"
|
|
@@ -537,12 +602,12 @@ class IPAddr
|
|
|
537
602
|
else
|
|
538
603
|
m = IPAddr.new(mask)
|
|
539
604
|
if m.family != @family
|
|
540
|
-
raise InvalidPrefixError, "address family is not same
|
|
605
|
+
raise InvalidPrefixError, "address family is not same"
|
|
541
606
|
end
|
|
542
607
|
@mask_addr = m.to_i
|
|
543
608
|
n = @mask_addr ^ m.instance_variable_get(:@mask_addr)
|
|
544
609
|
unless ((n + 1) & n).zero?
|
|
545
|
-
raise InvalidPrefixError, "invalid mask #{mask}
|
|
610
|
+
raise InvalidPrefixError, "invalid mask #{mask}"
|
|
546
611
|
end
|
|
547
612
|
@addr &= @mask_addr
|
|
548
613
|
return self
|
|
@@ -553,13 +618,13 @@ class IPAddr
|
|
|
553
618
|
case @family
|
|
554
619
|
when Socket::AF_INET
|
|
555
620
|
if prefixlen < 0 || prefixlen > 32
|
|
556
|
-
raise InvalidPrefixError, "invalid length
|
|
621
|
+
raise InvalidPrefixError, "invalid length"
|
|
557
622
|
end
|
|
558
623
|
masklen = 32 - prefixlen
|
|
559
624
|
@mask_addr = ((IN4MASK >> masklen) << masklen)
|
|
560
625
|
when Socket::AF_INET6
|
|
561
626
|
if prefixlen < 0 || prefixlen > 128
|
|
562
|
-
raise InvalidPrefixError, "invalid length
|
|
627
|
+
raise InvalidPrefixError, "invalid length"
|
|
563
628
|
end
|
|
564
629
|
masklen = 128 - prefixlen
|
|
565
630
|
@mask_addr = ((IN6MASK >> masklen) << masklen)
|
|
@@ -639,6 +704,7 @@ class IPAddr
|
|
|
639
704
|
end
|
|
640
705
|
end
|
|
641
706
|
|
|
707
|
+
# :stopdoc:
|
|
642
708
|
def coerce_other(other)
|
|
643
709
|
case other
|
|
644
710
|
when IPAddr
|
|
@@ -655,12 +721,12 @@ class IPAddr
|
|
|
655
721
|
when Array
|
|
656
722
|
octets = addr
|
|
657
723
|
else
|
|
658
|
-
|
|
659
|
-
octets =
|
|
724
|
+
RE_IPV4ADDRLIKE.match?(addr) or return nil
|
|
725
|
+
octets = addr.split('.')
|
|
660
726
|
end
|
|
661
727
|
octets.inject(0) { |i, s|
|
|
662
|
-
(n = s.to_i) < 256 or raise InvalidAddressError, "invalid address: #{
|
|
663
|
-
s.
|
|
728
|
+
(n = s.to_i) < 256 or raise InvalidAddressError, "invalid address: #{addr}"
|
|
729
|
+
(s != '0') && s.start_with?('0') and raise InvalidAddressError, "zero-filled number in IPv4 address is ambiguous: #{addr}"
|
|
664
730
|
i << 8 | n
|
|
665
731
|
}
|
|
666
732
|
end
|
|
@@ -750,7 +816,7 @@ unless Socket.const_defined? :AF_INET6
|
|
|
750
816
|
class << IPSocket
|
|
751
817
|
private
|
|
752
818
|
|
|
753
|
-
def valid_v6?(addr)
|
|
819
|
+
def valid_v6?(addr) # :nodoc:
|
|
754
820
|
case addr
|
|
755
821
|
when IPAddr::RE_IPV6ADDRLIKE_FULL
|
|
756
822
|
if $2
|
metadata
CHANGED
|
@@ -1,15 +1,14 @@
|
|
|
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.8
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Akinori MUSHA
|
|
8
8
|
- Hajimu UMEMOTO
|
|
9
|
-
autorequire:
|
|
10
9
|
bindir: bin
|
|
11
10
|
cert_chain: []
|
|
12
|
-
date:
|
|
11
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
13
12
|
dependencies: []
|
|
14
13
|
description: |
|
|
15
14
|
IPAddr provides a set of methods to manipulate an IP address.
|
|
@@ -23,14 +22,12 @@ extra_rdoc_files: []
|
|
|
23
22
|
files:
|
|
24
23
|
- LICENSE.txt
|
|
25
24
|
- README.md
|
|
26
|
-
- ipaddr.gemspec
|
|
27
25
|
- lib/ipaddr.rb
|
|
28
26
|
homepage: https://github.com/ruby/ipaddr
|
|
29
27
|
licenses:
|
|
30
28
|
- Ruby
|
|
31
29
|
- BSD-2-Clause
|
|
32
30
|
metadata: {}
|
|
33
|
-
post_install_message:
|
|
34
31
|
rdoc_options: []
|
|
35
32
|
require_paths:
|
|
36
33
|
- lib
|
|
@@ -38,15 +35,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
38
35
|
requirements:
|
|
39
36
|
- - ">="
|
|
40
37
|
- !ruby/object:Gem::Version
|
|
41
|
-
version: '2.
|
|
38
|
+
version: '2.4'
|
|
42
39
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
43
40
|
requirements:
|
|
44
41
|
- - ">="
|
|
45
42
|
- !ruby/object:Gem::Version
|
|
46
43
|
version: '0'
|
|
47
44
|
requirements: []
|
|
48
|
-
rubygems_version: 3.
|
|
49
|
-
signing_key:
|
|
45
|
+
rubygems_version: 3.6.9
|
|
50
46
|
specification_version: 4
|
|
51
47
|
summary: A class to manipulate an IP address in ruby
|
|
52
48
|
test_files: []
|
data/ipaddr.gemspec
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
# coding: utf-8
|
|
3
|
-
|
|
4
|
-
if File.exist?(File.expand_path("ipaddr.gemspec"))
|
|
5
|
-
lib = File.expand_path("../lib", __FILE__)
|
|
6
|
-
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
7
|
-
|
|
8
|
-
file = File.expand_path("ipaddr.rb", lib)
|
|
9
|
-
else
|
|
10
|
-
# for ruby-core
|
|
11
|
-
file = File.expand_path("../ipaddr.rb", __FILE__)
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
version = File.foreach(file).find do |line|
|
|
15
|
-
/^\s*VERSION\s*=\s*["'](.*)["']/ =~ line and break $1
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
Gem::Specification.new do |spec|
|
|
19
|
-
spec.name = "ipaddr"
|
|
20
|
-
spec.version = version
|
|
21
|
-
spec.authors = ["Akinori MUSHA", "Hajimu UMEMOTO"]
|
|
22
|
-
spec.email = ["knu@idaemons.org", "ume@mahoroba.org"]
|
|
23
|
-
|
|
24
|
-
spec.summary = %q{A class to manipulate an IP address in ruby}
|
|
25
|
-
spec.description = <<-'DESCRIPTION'
|
|
26
|
-
IPAddr provides a set of methods to manipulate an IP address.
|
|
27
|
-
Both IPv4 and IPv6 are supported.
|
|
28
|
-
DESCRIPTION
|
|
29
|
-
spec.homepage = "https://github.com/ruby/ipaddr"
|
|
30
|
-
spec.licenses = ["Ruby", "BSD-2-Clause"]
|
|
31
|
-
|
|
32
|
-
spec.files = ["LICENSE.txt", "README.md", "ipaddr.gemspec", "lib/ipaddr.rb"]
|
|
33
|
-
spec.require_paths = ["lib"]
|
|
34
|
-
|
|
35
|
-
spec.required_ruby_version = ">= 2.3"
|
|
36
|
-
end
|