ipaddr 1.2.2 → 1.2.4

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: 36032dfe23b1e485b8028f2ef7a33bf22830dfceab14f8fa87bc36b9be641257
4
+ data.tar.gz: b9287bd1261a2632fdecff1aa087883a535d6f5743344916fbe778570dcabe59
5
5
  SHA512:
6
- metadata.gz: e3089db198e90b6c0860b09483f052fa1eb24cfb034d1473db3817e46e06b00d52afec9d5f43abaf09e01bf603324473ed9ed0de770e5bdf6de308f4e57cd556
7
- data.tar.gz: ed8a0801bc5aa5df9ddcbcb7d8134e521ab1e77af14c19a38b0e625c1ac77bf0e48f271ef54b517a805585d4d3611a2bed848f997d0b8166cccf25747fcdee35
6
+ metadata.gz: f54ad4ceab5bec23c4c63369301a199dcd9558e9cc5b718bae845e9fa2d2892c76ca1207767100b0f4099c0b2a8e0bff1c7f3d52d722e40d1f6bf9ede02e757a
7
+ data.tar.gz: accdd06106c29eaa3f54ee9b230db907b8edc51c954086573f8c9fae353fc76423196e075d8b4e076499fc67e60f81d9d7a4b4471212654d93f060a4a950d984
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
@@ -3,9 +3,13 @@
3
3
  lib = File.expand_path("../lib", __FILE__)
4
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
5
 
6
+ version = File.foreach(File.expand_path("ipaddr.rb", lib)).find do |line|
7
+ /^\s*VERSION\s*=\s*["'](.*)["']/ =~ line and break $1
8
+ end
9
+
6
10
  Gem::Specification.new do |spec|
7
11
  spec.name = "ipaddr"
8
- spec.version = "1.2.2"
12
+ spec.version = version
9
13
  spec.authors = ["Akinori MUSHA", "Hajimu UMEMOTO"]
10
14
  spec.email = ["knu@idaemons.org", "ume@mahoroba.org"]
11
15
 
@@ -15,14 +19,10 @@ IPAddr provides a set of methods to manipulate an IP address.
15
19
  Both IPv4 and IPv6 are supported.
16
20
  DESCRIPTION
17
21
  spec.homepage = "https://github.com/ruby/ipaddr"
18
- spec.license = "BSD-2-Clause"
22
+ spec.licenses = ["Ruby", "BSD-2-Clause"]
19
23
 
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) }
24
+ spec.files = ["LICENSE.txt", "README.md", "ipaddr.gemspec", "lib/ipaddr.rb"]
23
25
  spec.require_paths = ["lib"]
24
26
 
25
- spec.add_development_dependency "bundler", "~> 1.15"
26
- spec.add_development_dependency "rake", "~> 10.0"
27
- spec.add_development_dependency "test-unit"
27
+ spec.required_ruby_version = ">= 2.3"
28
28
  end
data/lib/ipaddr.rb CHANGED
@@ -40,6 +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.4"
43
44
 
44
45
  # 32 bit mask for IPv4
45
46
  IN4MASK = 0xffffffff
@@ -112,13 +113,12 @@ class IPAddr
112
113
  def self.ntop(addr)
113
114
  case addr.size
114
115
  when 4
115
- s = addr.unpack('C4').join('.')
116
+ addr.unpack('C4').join('.')
116
117
  when 16
117
- s = IN6FORMAT % addr.unpack('n8')
118
+ IN6FORMAT % addr.unpack('n8')
118
119
  else
119
120
  raise AddressFamilyError, "unsupported address family"
120
121
  end
121
- return s
122
122
  end
123
123
 
124
124
  # Returns a new ipaddr built by bitwise AND.
@@ -168,34 +168,17 @@ class IPAddr
168
168
  # net1 = IPAddr.new("192.168.2.0/24")
169
169
  # net2 = IPAddr.new("192.168.2.100")
170
170
  # net3 = IPAddr.new("192.168.3.0")
171
+ # net4 = IPAddr.new("192.168.2.0/16")
171
172
  # p net1.include?(net2) #=> true
172
173
  # p net1.include?(net3) #=> false
174
+ # p net1.include?(net4) #=> false
175
+ # p net4.include?(net1) #=> true
173
176
  def include?(other)
174
177
  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))
178
+ return false unless other.family == family
179
+ range = to_range
180
+ other = other.to_range
181
+ range.begin <= other.begin && range.end >= other.end
199
182
  end
200
183
  alias === include?
201
184
 
@@ -232,7 +215,13 @@ class IPAddr
232
215
  # Returns a string containing the IP address representation in
233
216
  # canonical form.
234
217
  def to_string
235
- return _to_string(@addr)
218
+ str = _to_string(@addr)
219
+
220
+ if @family == Socket::AF_INET6
221
+ str << zone_id.to_s
222
+ end
223
+
224
+ return str
236
225
  end
237
226
 
238
227
  # Returns a network byte ordered string form of the IP address.
@@ -328,9 +317,11 @@ class IPAddr
328
317
  # into an IPv4-mapped IPv6 address.
329
318
  def ipv4_mapped
330
319
  if !ipv4?
331
- raise InvalidAddressError, "not an IPv4 address"
320
+ raise InvalidAddressError, "not an IPv4 address: #{@addr}"
332
321
  end
333
- return self.clone.set(@addr | 0xffff00000000, Socket::AF_INET6)
322
+ clone = self.clone.set(@addr | 0xffff00000000, Socket::AF_INET6)
323
+ clone.instance_variable_set(:@mask_addr, @mask_addr | 0xffffffffffffffffffffffff00000000)
324
+ clone
334
325
  end
335
326
 
336
327
  # Returns a new ipaddr built by converting the native IPv4 address
@@ -338,7 +329,7 @@ class IPAddr
338
329
  def ipv4_compat
339
330
  warn "IPAddr\##{__callee__} is obsolete", uplevel: 1 if $VERBOSE
340
331
  if !ipv4?
341
- raise InvalidAddressError, "not an IPv4 address"
332
+ raise InvalidAddressError, "not an IPv4 address: #{@addr}"
342
333
  end
343
334
  return self.clone.set(@addr, Socket::AF_INET6)
344
335
  end
@@ -369,7 +360,7 @@ class IPAddr
369
360
  # Returns a string for DNS reverse lookup compatible with RFC3172.
370
361
  def ip6_arpa
371
362
  if !ipv6?
372
- raise InvalidAddressError, "not an IPv6 address"
363
+ raise InvalidAddressError, "not an IPv6 address: #{@addr}"
373
364
  end
374
365
  return _reverse + ".ip6.arpa"
375
366
  end
@@ -377,7 +368,7 @@ class IPAddr
377
368
  # Returns a string for DNS reverse lookup compatible with RFC1886.
378
369
  def ip6_int
379
370
  if !ipv6?
380
- raise InvalidAddressError, "not an IPv6 address"
371
+ raise InvalidAddressError, "not an IPv6 address: #{@addr}"
381
372
  end
382
373
  return _reverse + ".ip6.int"
383
374
  end
@@ -404,7 +395,7 @@ class IPAddr
404
395
 
405
396
  # Returns a hash value used by Hash, Set, and Array classes
406
397
  def hash
407
- return ([@addr, @mask_addr].hash << 1) | (ipv4? ? 0 : 1)
398
+ return ([@addr, @mask_addr, @zone_id].hash << 1) | (ipv4? ? 0 : 1)
408
399
  end
409
400
 
410
401
  # Creates a Range object for the network address.
@@ -420,7 +411,7 @@ class IPAddr
420
411
  raise AddressFamilyError, "unsupported address family"
421
412
  end
422
413
 
423
- return clone.set(begin_addr, @family)..clone.set(end_addr, @family)
414
+ self.class.new(begin_addr, @family)..self.class.new(end_addr, @family)
424
415
  end
425
416
 
426
417
  # Returns the prefix length in bits for the ipaddr.
@@ -448,7 +439,7 @@ class IPAddr
448
439
  when Integer
449
440
  mask!(prefix)
450
441
  else
451
- raise InvalidPrefixError, "prefix must be an integer"
442
+ raise InvalidPrefixError, "prefix must be an integer: #{@addr}"
452
443
  end
453
444
  end
454
445
 
@@ -460,11 +451,42 @@ class IPAddr
460
451
  af = "IPv4"
461
452
  when Socket::AF_INET6
462
453
  af = "IPv6"
454
+ zone_id = @zone_id.to_s
463
455
  else
464
456
  raise AddressFamilyError, "unsupported address family"
465
457
  end
466
- return sprintf("#<%s: %s:%s/%s>", self.class.name,
467
- af, _to_string(@addr), _to_string(@mask_addr))
458
+ return sprintf("#<%s: %s:%s%s/%s>", self.class.name,
459
+ af, _to_string(@addr), zone_id, _to_string(@mask_addr))
460
+ end
461
+
462
+ # Returns the netmask in string format e.g. 255.255.0.0
463
+ def netmask
464
+ _to_string(@mask_addr)
465
+ end
466
+
467
+ # Returns the IPv6 zone identifier, if present.
468
+ # Raises InvalidAddressError if not an IPv6 address.
469
+ def zone_id
470
+ if @family == Socket::AF_INET6
471
+ @zone_id
472
+ else
473
+ raise InvalidAddressError, "not an IPv6 address"
474
+ end
475
+ end
476
+
477
+ # Returns the IPv6 zone identifier, if present.
478
+ # Raises InvalidAddressError if not an IPv6 address.
479
+ def zone_id=(zid)
480
+ if @family == Socket::AF_INET6
481
+ case zid
482
+ when nil, /\A%(\w+)\z/
483
+ @zone_id = zid
484
+ else
485
+ raise InvalidAddressError, "invalid zone identifier for address"
486
+ end
487
+ else
488
+ raise InvalidAddressError, "not an IPv6 address"
489
+ end
468
490
  end
469
491
 
470
492
  protected
@@ -476,11 +498,11 @@ class IPAddr
476
498
  case family[0] ? family[0] : @family
477
499
  when Socket::AF_INET
478
500
  if addr < 0 || addr > IN4MASK
479
- raise InvalidAddressError, "invalid address"
501
+ raise InvalidAddressError, "invalid address: #{@addr}"
480
502
  end
481
503
  when Socket::AF_INET6
482
504
  if addr < 0 || addr > IN6MASK
483
- raise InvalidAddressError, "invalid address"
505
+ raise InvalidAddressError, "invalid address: #{@addr}"
484
506
  end
485
507
  else
486
508
  raise AddressFamilyError, "unsupported address family"
@@ -488,6 +510,9 @@ class IPAddr
488
510
  @addr = addr
489
511
  if family[0]
490
512
  @family = family[0]
513
+ if @family == Socket::AF_INET
514
+ @mask_addr &= IN4MASK
515
+ end
491
516
  end
492
517
  return self
493
518
  end
@@ -496,17 +521,20 @@ class IPAddr
496
521
  def mask!(mask)
497
522
  case mask
498
523
  when String
499
- if mask =~ /\A\d+\z/
524
+ case mask
525
+ when /\A(0|[1-9]+\d*)\z/
500
526
  prefixlen = mask.to_i
527
+ when /\A\d+\z/
528
+ raise InvalidPrefixError, "leading zeros in prefix"
501
529
  else
502
530
  m = IPAddr.new(mask)
503
531
  if m.family != @family
504
- raise InvalidPrefixError, "address family is not same"
532
+ raise InvalidPrefixError, "address family is not same: #{@addr}"
505
533
  end
506
534
  @mask_addr = m.to_i
507
535
  n = @mask_addr ^ m.instance_variable_get(:@mask_addr)
508
536
  unless ((n + 1) & n).zero?
509
- raise InvalidPrefixError, "invalid mask #{mask}"
537
+ raise InvalidPrefixError, "invalid mask #{mask}: #{@addr}"
510
538
  end
511
539
  @addr &= @mask_addr
512
540
  return self
@@ -517,13 +545,13 @@ class IPAddr
517
545
  case @family
518
546
  when Socket::AF_INET
519
547
  if prefixlen < 0 || prefixlen > 32
520
- raise InvalidPrefixError, "invalid length"
548
+ raise InvalidPrefixError, "invalid length: #{@addr}"
521
549
  end
522
550
  masklen = 32 - prefixlen
523
551
  @mask_addr = ((IN4MASK >> masklen) << masklen)
524
552
  when Socket::AF_INET6
525
553
  if prefixlen < 0 || prefixlen > 128
526
- raise InvalidPrefixError, "invalid length"
554
+ raise InvalidPrefixError, "invalid length: #{@addr}"
527
555
  end
528
556
  masklen = 128 - prefixlen
529
557
  @mask_addr = ((IN6MASK >> masklen) << masklen)
@@ -555,6 +583,7 @@ class IPAddr
555
583
  # those, such as &, |, include? and ==, accept a string, or a packed
556
584
  # in_addr value instead of an IPAddr object.
557
585
  def initialize(addr = '::', family = Socket::AF_UNSPEC)
586
+ @mask_addr = nil
558
587
  if !addr.kind_of?(String)
559
588
  case family
560
589
  when Socket::AF_INET, Socket::AF_INET6
@@ -567,11 +596,16 @@ class IPAddr
567
596
  raise AddressFamilyError, "unsupported address family: #{family}"
568
597
  end
569
598
  end
570
- prefix, prefixlen = addr.split('/')
599
+ prefix, prefixlen = addr.split('/', 2)
571
600
  if prefix =~ /\A\[(.*)\]\z/i
572
601
  prefix = $1
573
602
  family = Socket::AF_INET6
574
603
  end
604
+ if prefix =~ /\A(.*)(%\w+)\z/
605
+ prefix = $1
606
+ zone_id = $2
607
+ family = Socket::AF_INET6
608
+ end
575
609
  # It seems AI_NUMERICHOST doesn't do the job.
576
610
  #Socket.getaddrinfo(left, nil, Socket::AF_INET6, Socket::SOCK_STREAM, nil,
577
611
  # Socket::AI_NUMERICHOST)
@@ -586,6 +620,7 @@ class IPAddr
586
620
  @addr = in6_addr(prefix)
587
621
  @family = Socket::AF_INET6
588
622
  end
623
+ @zone_id = zone_id
589
624
  if family != Socket::AF_UNSPEC && @family != family
590
625
  raise AddressFamilyError, "address family mismatch"
591
626
  end
@@ -594,8 +629,6 @@ class IPAddr
594
629
  else
595
630
  @mask_addr = (@family == Socket::AF_INET) ? IN4MASK : IN6MASK
596
631
  end
597
- rescue InvalidAddressError => e
598
- raise e.class, "#{e.message}: #{addr}"
599
632
  end
600
633
 
601
634
  def coerce_other(other)
@@ -618,8 +651,8 @@ class IPAddr
618
651
  octets = m.captures
619
652
  end
620
653
  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"
654
+ (n = s.to_i) < 256 or raise InvalidAddressError, "invalid address: #{@addr}"
655
+ s.match(/\A0./) and raise InvalidAddressError, "zero-filled number in IPv4 address is ambiguous: #{@addr}"
623
656
  i << 8 | n
624
657
  }
625
658
  end
@@ -636,19 +669,19 @@ class IPAddr
636
669
  right = ''
637
670
  when RE_IPV6ADDRLIKE_COMPRESSED
638
671
  if $4
639
- left.count(':') <= 6 or raise InvalidAddressError, "invalid address"
672
+ left.count(':') <= 6 or raise InvalidAddressError, "invalid address: #{@addr}"
640
673
  addr = in_addr($~[4,4])
641
674
  left = $1
642
675
  right = $3 + '0:0'
643
676
  else
644
677
  left.count(':') <= ($1.empty? || $2.empty? ? 8 : 7) or
645
- raise InvalidAddressError, "invalid address"
678
+ raise InvalidAddressError, "invalid address: #{@addr}"
646
679
  left = $1
647
680
  right = $2
648
681
  addr = 0
649
682
  end
650
683
  else
651
- raise InvalidAddressError, "invalid address"
684
+ raise InvalidAddressError, "invalid address: #{@addr}"
652
685
  end
653
686
  l = left.split(':')
654
687
  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.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Akinori MUSHA
8
8
  - Hajimu UMEMOTO
9
9
  autorequire:
10
- bindir: exe
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: 2022-02-05 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,18 +21,13 @@ 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
33
  post_install_message:
@@ -85,15 +38,14 @@ 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
48
+ rubygems_version: 3.0.3.1
97
49
  signing_key:
98
50
  specification_version: 4
99
51
  summary: A class to manipulate an IP address in ruby
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