ipaddr 1.2.2 → 1.2.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 78c5854e872965800e79a6508cb7d8ff3cb3ea73
4
- data.tar.gz: 0b6b8d515a8718a852beb923e7f5c24c9f65353d
2
+ SHA256:
3
+ metadata.gz: d2856d459b11572a7c59a6ad57ec0462b5e851a5c2a012cb6d106a8be15e3739
4
+ data.tar.gz: e8bf2d309cd922ad6c10af07f359034264be462b926718b4d8524e068084fa5f
5
5
  SHA512:
6
- metadata.gz: e3089db198e90b6c0860b09483f052fa1eb24cfb034d1473db3817e46e06b00d52afec9d5f43abaf09e01bf603324473ed9ed0de770e5bdf6de308f4e57cd556
7
- data.tar.gz: ed8a0801bc5aa5df9ddcbcb7d8134e521ab1e77af14c19a38b0e625c1ac77bf0e48f271ef54b517a805585d4d3611a2bed848f997d0b8166cccf25747fcdee35
6
+ metadata.gz: 372737acde9b6852b407d6b38df6392ea2240589eda19798e14fd01184594f0a9ef7d3a30d7f3ce5d178d314ff535a92fb1400f9895863c49047229175e1e350
7
+ data.tar.gz: 46aaa06ed661f88c99b63f844855ec91e9b17639799d5d3d980a77f7db236306511671d6f38b562d08fcdd35150b5bea1adccef2b182c7c8e5563a6439b374d7
data/README.md CHANGED
@@ -3,6 +3,8 @@
3
3
  IPAddr provides a set of methods to manipulate an IP address. Both
4
4
  IPv4 and IPv6 are supported.
5
5
 
6
+ [![Build Status](https://travis-ci.org/ruby/ipaddr.svg?branch=master)](https://travis-ci.org/ruby/ipaddr)
7
+
6
8
  ## Installation
7
9
 
8
10
  This library is part of the standard ruby distribution as default gem
data/ipaddr.gemspec CHANGED
@@ -5,7 +5,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
5
 
6
6
  Gem::Specification.new do |spec|
7
7
  spec.name = "ipaddr"
8
- spec.version = "1.2.2"
8
+ spec.version = "1.2.3"
9
9
  spec.authors = ["Akinori MUSHA", "Hajimu UMEMOTO"]
10
10
  spec.email = ["knu@idaemons.org", "ume@mahoroba.org"]
11
11
 
@@ -15,14 +15,10 @@ IPAddr provides a set of methods to manipulate an IP address.
15
15
  Both IPv4 and IPv6 are supported.
16
16
  DESCRIPTION
17
17
  spec.homepage = "https://github.com/ruby/ipaddr"
18
- spec.license = "BSD-2-Clause"
18
+ spec.licenses = ["Ruby", "BSD-2-Clause"]
19
19
 
20
- spec.files = [".gitignore", ".travis.yml", "Gemfile", "LICENSE.txt", "README.md", "Rakefile", "bin/console", "bin/setup", "ipaddr.gemspec", "lib/ipaddr.rb"]
21
- spec.bindir = "exe"
22
- spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
+ spec.files = ["LICENSE.txt", "README.md", "ipaddr.gemspec", "lib/ipaddr.rb"]
23
21
  spec.require_paths = ["lib"]
24
22
 
25
- spec.add_development_dependency "bundler", "~> 1.15"
26
- spec.add_development_dependency "rake", "~> 10.0"
27
- spec.add_development_dependency "test-unit"
23
+ spec.required_ruby_version = ">= 2.3"
28
24
  end
data/lib/ipaddr.rb CHANGED
@@ -112,13 +112,12 @@ class IPAddr
112
112
  def self.ntop(addr)
113
113
  case addr.size
114
114
  when 4
115
- s = addr.unpack('C4').join('.')
115
+ addr.unpack('C4').join('.')
116
116
  when 16
117
- s = IN6FORMAT % addr.unpack('n8')
117
+ IN6FORMAT % addr.unpack('n8')
118
118
  else
119
119
  raise AddressFamilyError, "unsupported address family"
120
120
  end
121
- return s
122
121
  end
123
122
 
124
123
  # Returns a new ipaddr built by bitwise AND.
@@ -168,34 +167,17 @@ class IPAddr
168
167
  # net1 = IPAddr.new("192.168.2.0/24")
169
168
  # net2 = IPAddr.new("192.168.2.100")
170
169
  # net3 = IPAddr.new("192.168.3.0")
170
+ # net4 = IPAddr.new("192.168.2.0/16")
171
171
  # p net1.include?(net2) #=> true
172
172
  # p net1.include?(net3) #=> false
173
+ # p net1.include?(net4) #=> false
174
+ # p net4.include?(net1) #=> true
173
175
  def include?(other)
174
176
  other = coerce_other(other)
175
- if ipv4_mapped?
176
- if (@mask_addr >> 32) != 0xffffffffffffffffffffffff
177
- return false
178
- end
179
- mask_addr = (@mask_addr & IN4MASK)
180
- addr = (@addr & IN4MASK)
181
- family = Socket::AF_INET
182
- else
183
- mask_addr = @mask_addr
184
- addr = @addr
185
- family = @family
186
- end
187
- if other.ipv4_mapped?
188
- other_addr = (other.to_i & IN4MASK)
189
- other_family = Socket::AF_INET
190
- else
191
- other_addr = other.to_i
192
- other_family = other.family
193
- end
194
-
195
- if family != other_family
196
- return false
197
- end
198
- return ((addr & mask_addr) == (other_addr & mask_addr))
177
+ return false unless other.family == family
178
+ range = to_range
179
+ other = other.to_range
180
+ range.begin <= other.begin && range.end >= other.end
199
181
  end
200
182
  alias === include?
201
183
 
@@ -232,7 +214,13 @@ class IPAddr
232
214
  # Returns a string containing the IP address representation in
233
215
  # canonical form.
234
216
  def to_string
235
- return _to_string(@addr)
217
+ str = _to_string(@addr)
218
+
219
+ if @family == Socket::AF_INET6
220
+ str << zone_id.to_s
221
+ end
222
+
223
+ return str
236
224
  end
237
225
 
238
226
  # Returns a network byte ordered string form of the IP address.
@@ -328,9 +316,11 @@ class IPAddr
328
316
  # into an IPv4-mapped IPv6 address.
329
317
  def ipv4_mapped
330
318
  if !ipv4?
331
- raise InvalidAddressError, "not an IPv4 address"
319
+ raise InvalidAddressError, "not an IPv4 address: #{@addr}"
332
320
  end
333
- return self.clone.set(@addr | 0xffff00000000, Socket::AF_INET6)
321
+ clone = self.clone.set(@addr | 0xffff00000000, Socket::AF_INET6)
322
+ clone.instance_variable_set(:@mask_addr, @mask_addr | 0xffffffffffffffffffffffff00000000)
323
+ clone
334
324
  end
335
325
 
336
326
  # Returns a new ipaddr built by converting the native IPv4 address
@@ -338,7 +328,7 @@ class IPAddr
338
328
  def ipv4_compat
339
329
  warn "IPAddr\##{__callee__} is obsolete", uplevel: 1 if $VERBOSE
340
330
  if !ipv4?
341
- raise InvalidAddressError, "not an IPv4 address"
331
+ raise InvalidAddressError, "not an IPv4 address: #{@addr}"
342
332
  end
343
333
  return self.clone.set(@addr, Socket::AF_INET6)
344
334
  end
@@ -369,7 +359,7 @@ class IPAddr
369
359
  # Returns a string for DNS reverse lookup compatible with RFC3172.
370
360
  def ip6_arpa
371
361
  if !ipv6?
372
- raise InvalidAddressError, "not an IPv6 address"
362
+ raise InvalidAddressError, "not an IPv6 address: #{@addr}"
373
363
  end
374
364
  return _reverse + ".ip6.arpa"
375
365
  end
@@ -377,7 +367,7 @@ class IPAddr
377
367
  # Returns a string for DNS reverse lookup compatible with RFC1886.
378
368
  def ip6_int
379
369
  if !ipv6?
380
- raise InvalidAddressError, "not an IPv6 address"
370
+ raise InvalidAddressError, "not an IPv6 address: #{@addr}"
381
371
  end
382
372
  return _reverse + ".ip6.int"
383
373
  end
@@ -404,7 +394,7 @@ class IPAddr
404
394
 
405
395
  # Returns a hash value used by Hash, Set, and Array classes
406
396
  def hash
407
- return ([@addr, @mask_addr].hash << 1) | (ipv4? ? 0 : 1)
397
+ return ([@addr, @mask_addr, @zone_id].hash << 1) | (ipv4? ? 0 : 1)
408
398
  end
409
399
 
410
400
  # Creates a Range object for the network address.
@@ -448,7 +438,7 @@ class IPAddr
448
438
  when Integer
449
439
  mask!(prefix)
450
440
  else
451
- raise InvalidPrefixError, "prefix must be an integer"
441
+ raise InvalidPrefixError, "prefix must be an integer: #{@addr}"
452
442
  end
453
443
  end
454
444
 
@@ -460,11 +450,42 @@ class IPAddr
460
450
  af = "IPv4"
461
451
  when Socket::AF_INET6
462
452
  af = "IPv6"
453
+ zone_id = @zone_id.to_s
463
454
  else
464
455
  raise AddressFamilyError, "unsupported address family"
465
456
  end
466
- return sprintf("#<%s: %s:%s/%s>", self.class.name,
467
- af, _to_string(@addr), _to_string(@mask_addr))
457
+ return sprintf("#<%s: %s:%s%s/%s>", self.class.name,
458
+ af, _to_string(@addr), zone_id, _to_string(@mask_addr))
459
+ end
460
+
461
+ # Returns the netmask in string format e.g. 255.255.0.0
462
+ def netmask
463
+ _to_string(@mask_addr)
464
+ end
465
+
466
+ # Returns the IPv6 zone identifier, if present.
467
+ # Raises InvalidAddressError if not an IPv6 address.
468
+ def zone_id
469
+ if @family == Socket::AF_INET6
470
+ @zone_id
471
+ else
472
+ raise InvalidAddressError, "not an IPv6 address"
473
+ end
474
+ end
475
+
476
+ # Returns the IPv6 zone identifier, if present.
477
+ # Raises InvalidAddressError if not an IPv6 address.
478
+ def zone_id=(zid)
479
+ if @family == Socket::AF_INET6
480
+ case zid
481
+ when nil, /\A%(\w+)\z/
482
+ @zone_id = zid
483
+ else
484
+ raise InvalidAddressError, "invalid zone identifier for address"
485
+ end
486
+ else
487
+ raise InvalidAddressError, "not an IPv6 address"
488
+ end
468
489
  end
469
490
 
470
491
  protected
@@ -476,11 +497,11 @@ class IPAddr
476
497
  case family[0] ? family[0] : @family
477
498
  when Socket::AF_INET
478
499
  if addr < 0 || addr > IN4MASK
479
- raise InvalidAddressError, "invalid address"
500
+ raise InvalidAddressError, "invalid address: #{@addr}"
480
501
  end
481
502
  when Socket::AF_INET6
482
503
  if addr < 0 || addr > IN6MASK
483
- raise InvalidAddressError, "invalid address"
504
+ raise InvalidAddressError, "invalid address: #{@addr}"
484
505
  end
485
506
  else
486
507
  raise AddressFamilyError, "unsupported address family"
@@ -496,17 +517,20 @@ class IPAddr
496
517
  def mask!(mask)
497
518
  case mask
498
519
  when String
499
- if mask =~ /\A\d+\z/
520
+ case mask
521
+ when /\A(0|[1-9]+\d*)\z/
500
522
  prefixlen = mask.to_i
523
+ when /\A\d+\z/
524
+ raise InvalidPrefixError, "leading zeros in prefix"
501
525
  else
502
526
  m = IPAddr.new(mask)
503
527
  if m.family != @family
504
- raise InvalidPrefixError, "address family is not same"
528
+ raise InvalidPrefixError, "address family is not same: #{@addr}"
505
529
  end
506
530
  @mask_addr = m.to_i
507
531
  n = @mask_addr ^ m.instance_variable_get(:@mask_addr)
508
532
  unless ((n + 1) & n).zero?
509
- raise InvalidPrefixError, "invalid mask #{mask}"
533
+ raise InvalidPrefixError, "invalid mask #{mask}: #{@addr}"
510
534
  end
511
535
  @addr &= @mask_addr
512
536
  return self
@@ -517,13 +541,13 @@ class IPAddr
517
541
  case @family
518
542
  when Socket::AF_INET
519
543
  if prefixlen < 0 || prefixlen > 32
520
- raise InvalidPrefixError, "invalid length"
544
+ raise InvalidPrefixError, "invalid length: #{@addr}"
521
545
  end
522
546
  masklen = 32 - prefixlen
523
547
  @mask_addr = ((IN4MASK >> masklen) << masklen)
524
548
  when Socket::AF_INET6
525
549
  if prefixlen < 0 || prefixlen > 128
526
- raise InvalidPrefixError, "invalid length"
550
+ raise InvalidPrefixError, "invalid length: #{@addr}"
527
551
  end
528
552
  masklen = 128 - prefixlen
529
553
  @mask_addr = ((IN6MASK >> masklen) << masklen)
@@ -567,11 +591,16 @@ class IPAddr
567
591
  raise AddressFamilyError, "unsupported address family: #{family}"
568
592
  end
569
593
  end
570
- prefix, prefixlen = addr.split('/')
594
+ prefix, prefixlen = addr.split('/', 2)
571
595
  if prefix =~ /\A\[(.*)\]\z/i
572
596
  prefix = $1
573
597
  family = Socket::AF_INET6
574
598
  end
599
+ if prefix =~ /\A(.*)(%\w+)\z/
600
+ prefix = $1
601
+ zone_id = $2
602
+ family = Socket::AF_INET6
603
+ end
575
604
  # It seems AI_NUMERICHOST doesn't do the job.
576
605
  #Socket.getaddrinfo(left, nil, Socket::AF_INET6, Socket::SOCK_STREAM, nil,
577
606
  # Socket::AI_NUMERICHOST)
@@ -586,6 +615,7 @@ class IPAddr
586
615
  @addr = in6_addr(prefix)
587
616
  @family = Socket::AF_INET6
588
617
  end
618
+ @zone_id = zone_id
589
619
  if family != Socket::AF_UNSPEC && @family != family
590
620
  raise AddressFamilyError, "address family mismatch"
591
621
  end
@@ -594,8 +624,6 @@ class IPAddr
594
624
  else
595
625
  @mask_addr = (@family == Socket::AF_INET) ? IN4MASK : IN6MASK
596
626
  end
597
- rescue InvalidAddressError => e
598
- raise e.class, "#{e.message}: #{addr}"
599
627
  end
600
628
 
601
629
  def coerce_other(other)
@@ -618,8 +646,8 @@ class IPAddr
618
646
  octets = m.captures
619
647
  end
620
648
  octets.inject(0) { |i, s|
621
- (n = s.to_i) < 256 or raise InvalidAddressError, "invalid address"
622
- s.match(/\A0./) and raise InvalidAddressError, "zero-filled number in IPv4 address is ambiguous"
649
+ (n = s.to_i) < 256 or raise InvalidAddressError, "invalid address: #{@addr}"
650
+ s.match(/\A0./) and raise InvalidAddressError, "zero-filled number in IPv4 address is ambiguous: #{@addr}"
623
651
  i << 8 | n
624
652
  }
625
653
  end
@@ -636,19 +664,19 @@ class IPAddr
636
664
  right = ''
637
665
  when RE_IPV6ADDRLIKE_COMPRESSED
638
666
  if $4
639
- left.count(':') <= 6 or raise InvalidAddressError, "invalid address"
667
+ left.count(':') <= 6 or raise InvalidAddressError, "invalid address: #{@addr}"
640
668
  addr = in_addr($~[4,4])
641
669
  left = $1
642
670
  right = $3 + '0:0'
643
671
  else
644
672
  left.count(':') <= ($1.empty? || $2.empty? ? 8 : 7) or
645
- raise InvalidAddressError, "invalid address"
673
+ raise InvalidAddressError, "invalid address: #{@addr}"
646
674
  left = $1
647
675
  right = $2
648
676
  addr = 0
649
677
  end
650
678
  else
651
- raise InvalidAddressError, "invalid address"
679
+ raise InvalidAddressError, "invalid address: #{@addr}"
652
680
  end
653
681
  l = left.split(':')
654
682
  r = right.split(':')
metadata CHANGED
@@ -1,58 +1,16 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ipaddr
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.2
4
+ version: 1.2.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Akinori MUSHA
8
8
  - Hajimu UMEMOTO
9
- autorequire:
10
- bindir: exe
9
+ autorequire:
10
+ bindir: bin
11
11
  cert_chain: []
12
- date: 2018-12-18 00:00:00.000000000 Z
13
- dependencies:
14
- - !ruby/object:Gem::Dependency
15
- name: bundler
16
- requirement: !ruby/object:Gem::Requirement
17
- requirements:
18
- - - "~>"
19
- - !ruby/object:Gem::Version
20
- version: '1.15'
21
- type: :development
22
- prerelease: false
23
- version_requirements: !ruby/object:Gem::Requirement
24
- requirements:
25
- - - "~>"
26
- - !ruby/object:Gem::Version
27
- version: '1.15'
28
- - !ruby/object:Gem::Dependency
29
- name: rake
30
- requirement: !ruby/object:Gem::Requirement
31
- requirements:
32
- - - "~>"
33
- - !ruby/object:Gem::Version
34
- version: '10.0'
35
- type: :development
36
- prerelease: false
37
- version_requirements: !ruby/object:Gem::Requirement
38
- requirements:
39
- - - "~>"
40
- - !ruby/object:Gem::Version
41
- version: '10.0'
42
- - !ruby/object:Gem::Dependency
43
- name: test-unit
44
- requirement: !ruby/object:Gem::Requirement
45
- requirements:
46
- - - ">="
47
- - !ruby/object:Gem::Version
48
- version: '0'
49
- type: :development
50
- prerelease: false
51
- version_requirements: !ruby/object:Gem::Requirement
52
- requirements:
53
- - - ">="
54
- - !ruby/object:Gem::Version
55
- version: '0'
12
+ date: 2021-10-25 00:00:00.000000000 Z
13
+ dependencies: []
56
14
  description: |
57
15
  IPAddr provides a set of methods to manipulate an IP address.
58
16
  Both IPv4 and IPv6 are supported.
@@ -63,21 +21,16 @@ executables: []
63
21
  extensions: []
64
22
  extra_rdoc_files: []
65
23
  files:
66
- - ".gitignore"
67
- - ".travis.yml"
68
- - Gemfile
69
24
  - LICENSE.txt
70
25
  - README.md
71
- - Rakefile
72
- - bin/console
73
- - bin/setup
74
26
  - ipaddr.gemspec
75
27
  - lib/ipaddr.rb
76
28
  homepage: https://github.com/ruby/ipaddr
77
29
  licenses:
30
+ - Ruby
78
31
  - BSD-2-Clause
79
32
  metadata: {}
80
- post_install_message:
33
+ post_install_message:
81
34
  rdoc_options: []
82
35
  require_paths:
83
36
  - lib
@@ -85,16 +38,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
85
38
  requirements:
86
39
  - - ">="
87
40
  - !ruby/object:Gem::Version
88
- version: '0'
41
+ version: '2.3'
89
42
  required_rubygems_version: !ruby/object:Gem::Requirement
90
43
  requirements:
91
44
  - - ">="
92
45
  - !ruby/object:Gem::Version
93
46
  version: '0'
94
47
  requirements: []
95
- rubyforge_project:
96
- rubygems_version: 2.6.14.1
97
- signing_key:
48
+ rubygems_version: 3.2.22
49
+ signing_key:
98
50
  specification_version: 4
99
51
  summary: A class to manipulate an IP address in ruby
100
52
  test_files: []
data/.gitignore DELETED
@@ -1,9 +0,0 @@
1
- /.bundle/
2
- /.yardoc
3
- /Gemfile.lock
4
- /_yardoc/
5
- /coverage/
6
- /doc/
7
- /pkg/
8
- /spec/reports/
9
- /tmp/
data/.travis.yml DELETED
@@ -1,21 +0,0 @@
1
- sudo: false
2
- language: ruby
3
- rvm:
4
- - 2.3
5
- - 2.4
6
- - 2.5.0
7
- - ruby-head
8
- matrix:
9
- include:
10
- - rvm: jruby-9.1.13.0
11
- jdk: openjdk8
12
- - rvm: jruby-9.1.13.0
13
- jdk: oraclejdk8
14
- - rvm: jruby-head
15
- jdk: openjdk8
16
- - rvm: jruby-head
17
- jdk: oraclejdk8
18
- allow_failures:
19
- - rvm: ruby-head
20
- - rvm: jruby-head
21
- before_install: gem install bundler
data/Gemfile DELETED
@@ -1,4 +0,0 @@
1
- source "https://rubygems.org"
2
-
3
- # Specify your gem's dependencies in ipaddr.gemspec
4
- gemspec
data/Rakefile DELETED
@@ -1,10 +0,0 @@
1
- require "bundler/gem_tasks"
2
- require "rake/testtask"
3
-
4
- Rake::TestTask.new(:test) do |t|
5
- t.libs << "test"
6
- t.libs << "lib"
7
- t.test_files = FileList["test/**/test_*.rb"]
8
- end
9
-
10
- task :default => :test
data/bin/console DELETED
@@ -1,14 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require "bundler/setup"
4
- require "ipaddr"
5
-
6
- # You can add fixtures and/or initialization code here to make experimenting
7
- # with your gem easier. You can also use a different console, if you like.
8
-
9
- # (If you use this, don't forget to add pry to your Gemfile!)
10
- # require "pry"
11
- # Pry.start
12
-
13
- require "irb"
14
- IRB.start(__FILE__)
data/bin/setup DELETED
@@ -1,8 +0,0 @@
1
- #!/usr/bin/env bash
2
- set -euo pipefail
3
- IFS=$'\n\t'
4
- set -vx
5
-
6
- bundle install
7
-
8
- # Do any other automated setup that you need to do here