ipaddr 1.2.8 → 1.3.0

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.
Files changed (4) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/lib/ipaddr.rb +70 -26
  4. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 27c05756ec16e7913ff99aab584bbcddab9e5ef419e5f5fb17850a846c8e562d
4
- data.tar.gz: 6845f685c7cfcee252d97e6e74f597991ba7586fc7104242e64ccad5abe9acfc
3
+ metadata.gz: d1c0830348465e01e309792b106380c16a97cfe9f5ba003ec99d3e78d2d602bd
4
+ data.tar.gz: 59a62a5f79ce024610365be4a599fa8be0afe413d184edb7e4c9517435fb4678
5
5
  SHA512:
6
- metadata.gz: 71535cdb0def5ae3bdc48c762f586c569dd3104e131da598620c43ac679b705e85dc48a45fa0142a69f98097d15dabdf3b427153cb39c283459a3d5d17471da6
7
- data.tar.gz: 74c73fbf129bfdf9526e3e76269b7c82e75dbef4b63dda82868b465c83bcd29495e470fc1743664a5a065958e455fa53ca678ac8161427a0ab10b55c92b5dd05
6
+ metadata.gz: 13aaefd68e369c3591cfe576dcf4d905cda02a7ec4b9de3b7e161817a9c676bd667e1edf4c1b4ee5816b9cac45aa80bab492095b5d46af571fca537ada32b643
7
+ data.tar.gz: 3ddb2b27e66dfa04ed44a2a2617d02501fcaa6975458fdf8378a22dc6031096e05e3034f6a6542856a069fa7cf5b183bec131a13a90be7486415da41bae85924
data/README.md CHANGED
@@ -15,7 +15,7 @@ version than comes with older versions of ruby.
15
15
  For example, you can add this line to your application's Gemfile:
16
16
 
17
17
  ```ruby
18
- gem 'ipaddr', '~> 1.2'
18
+ gem 'ipaddr'
19
19
  ```
20
20
 
21
21
  And then execute:
data/lib/ipaddr.rb CHANGED
@@ -41,7 +41,7 @@ require 'socket'
41
41
 
42
42
  class IPAddr
43
43
  # The version string
44
- VERSION = "1.2.8"
44
+ VERSION = "1.3.0"
45
45
 
46
46
  # 32 bit mask for IPv4
47
47
  IN4MASK = 0xffffffff
@@ -164,6 +164,10 @@ class IPAddr
164
164
 
165
165
  # Returns true if two ipaddrs are equal.
166
166
  def ==(other)
167
+ if other.nil?
168
+ return false
169
+ end
170
+
167
171
  other = coerce_other(other)
168
172
  rescue
169
173
  false
@@ -203,7 +207,7 @@ class IPAddr
203
207
 
204
208
  # Returns a string containing the IP address representation.
205
209
  def to_s
206
- str = to_string
210
+ str = _to_string(@addr)
207
211
  return str if ipv4?
208
212
 
209
213
  str.gsub!(/\b0{1,3}([\da-f]+)\b/i, '\1')
@@ -223,6 +227,7 @@ class IPAddr
223
227
  str = sprintf('::%s%d.%d.%d.%d', $1, $2.hex / 256, $2.hex % 256, $3.hex / 256, $3.hex % 256)
224
228
  end
225
229
 
230
+ str << @zone_id if @zone_id
226
231
  str
227
232
  end
228
233
 
@@ -290,11 +295,11 @@ class IPAddr
290
295
  def loopback?
291
296
  case @family
292
297
  when Socket::AF_INET
293
- @addr & 0xff000000 == 0x7f000000 # 127.0.0.1/8
298
+ (@addr & 0xff000000 == 0x7f000000) && prefix >= 8 # 127.0.0.1/8
294
299
  when Socket::AF_INET6
295
300
  @addr == 1 || # ::1
296
- (@addr & 0xffff_0000_0000 == 0xffff_0000_0000 && (
297
- @addr & 0xff000000 == 0x7f000000 # ::ffff:127.0.0.1/8
301
+ (@addr >> 32 == 0xffff && (
302
+ (@addr & 0xff000000 == 0x7f000000) && prefix >= 104 # ::ffff:127.0.0.0/104 (127.0.0.1/8)
298
303
  ))
299
304
  else
300
305
  raise AddressFamilyError, "unsupported address family"
@@ -309,22 +314,22 @@ class IPAddr
309
314
  def private?
310
315
  case @family
311
316
  when Socket::AF_INET
312
- @addr & 0xff000000 == 0x0a000000 || # 10.0.0.0/8
313
- @addr & 0xfff00000 == 0xac100000 || # 172.16.0.0/12
314
- @addr & 0xffff0000 == 0xc0a80000 # 192.168.0.0/16
317
+ (@addr & 0xff000000 == 0x0a000000) && prefix >= 8 || # 10.0.0.0/8
318
+ (@addr & 0xfff00000 == 0xac100000) && prefix >= 12 || # 172.16.0.0/12
319
+ (@addr & 0xffff0000 == 0xc0a80000) && prefix >= 16 # 192.168.0.0/16
315
320
  when Socket::AF_INET6
316
- @addr & 0xfe00_0000_0000_0000_0000_0000_0000_0000 == 0xfc00_0000_0000_0000_0000_0000_0000_0000 ||
317
- (@addr & 0xffff_0000_0000 == 0xffff_0000_0000 && (
318
- @addr & 0xff000000 == 0x0a000000 || # ::ffff:10.0.0.0/8
319
- @addr & 0xfff00000 == 0xac100000 || # ::ffff::172.16.0.0/12
320
- @addr & 0xffff0000 == 0xc0a80000 # ::ffff::192.168.0.0/16
321
+ (@addr & 0xfe00_0000_0000_0000_0000_0000_0000_0000 == 0xfc00_0000_0000_0000_0000_0000_0000_0000) && prefix >= 7 || # fc00::/7
322
+ (@addr >> 32 == 0xffff && (
323
+ (@addr & 0xff000000 == 0x0a000000) && prefix >= 104 || # ::ffff:10.0.0.0/104 (10.0.0.0/8)
324
+ (@addr & 0xfff00000 == 0xac100000) && prefix >= 108 || # ::ffff:172.16.0.0/108 (172.16.0.0/12)
325
+ (@addr & 0xffff0000 == 0xc0a80000) && prefix >= 112 # ::ffff:192.168.0.0/112 (192.168.0.0/16)
321
326
  ))
322
327
  else
323
328
  raise AddressFamilyError, "unsupported address family"
324
329
  end
325
330
  end
326
331
 
327
- # Returns true if the ipaddr is a link-local address. IPv4
332
+ # Returns true if the ipaddr is a link-local unicast address. IPv4
328
333
  # addresses in 169.254.0.0/16 reserved by RFC 3927 and link-local
329
334
  # IPv6 Unicast Addresses in fe80::/10 reserved by RFC 4291 are
330
335
  # considered link-local. Link-local IPv4 addresses in the
@@ -332,11 +337,49 @@ class IPAddr
332
337
  def link_local?
333
338
  case @family
334
339
  when Socket::AF_INET
335
- @addr & 0xffff0000 == 0xa9fe0000 # 169.254.0.0/16
340
+ (@addr & 0xffff0000 == 0xa9fe0000) && prefix >= 16 # 169.254.0.0/16
341
+ when Socket::AF_INET6
342
+ (@addr & 0xffc0_0000_0000_0000_0000_0000_0000_0000 == 0xfe80_0000_0000_0000_0000_0000_0000_0000) && prefix >= 10 || # fe80::/10
343
+ (@addr >> 32 == 0xffff && (
344
+ (@addr & 0xffff0000 == 0xa9fe0000) && prefix >= 112 # ::ffff:169.254.0.0/112 (169.254.0.0/16)
345
+ ))
346
+ else
347
+ raise AddressFamilyError, "unsupported address family"
348
+ end
349
+ end
350
+
351
+ alias link_local_unicast? link_local?
352
+
353
+ # Returns true if the ipaddr is a multicast address. IPv4
354
+ # addresses in 224.0.0.0/4 and IPv6 multicast addresses
355
+ # in ff00::/8 are considered multicast. Multicast IPv4 addresses in the
356
+ # IPv4-mapped IPv6 address range are also considered multicast.
357
+ def multicast?
358
+ case @family
359
+ when Socket::AF_INET
360
+ (@addr & 0xf0000000 == 0xe0000000) && prefix >= 4 # 224.0.0.0/4
361
+ when Socket::AF_INET6
362
+ (@addr & 0xff00_0000_0000_0000_0000_0000_0000_0000 == 0xff00_0000_0000_0000_0000_0000_0000_0000) && prefix >= 8 || # ff00::/8
363
+ (@addr >> 32 == 0xffff &&
364
+ (@addr & 0xf0000000 == 0xe0000000) && prefix >= 100 # ::ffff:224.0.0.0/100 (224.0.0.0/4)
365
+ )
366
+ else
367
+ raise AddressFamilyError, "unsupported address family"
368
+ end
369
+ end
370
+
371
+ # Returns true if the ipaddr is a link-local multicast address. IPv4
372
+ # addresses in 224.0.0.0/24 and link-local IPv6 Multicast Addresses in ff02::/16
373
+ # are considered link-local multicast. Link-local multicast IPv4 addresses in the
374
+ # IPv4-mapped IPv6 address range are also considered link-local multicast.
375
+ def link_local_multicast?
376
+ case @family
377
+ when Socket::AF_INET
378
+ (@addr & 0xffffff00 == 0xe0000000) && prefix >= 24 # 224.0.0.0/24 Local Network Control Block
336
379
  when Socket::AF_INET6
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
380
+ (@addr & 0xffff_0000_0000_0000_0000_0000_0000_0000 == 0xff02_0000_0000_0000_0000_0000_0000_0000) && prefix >= 16 || # ff02::/16
381
+ (@addr >> 32 == 0xffff && (
382
+ (@addr & 0xffffff00 == 0xe0000000) && prefix >= 120 # ::ffff:224.0.0.0/120 (224.0.0.0/24)
340
383
  ))
341
384
  else
342
385
  raise AddressFamilyError, "unsupported address family"
@@ -368,7 +411,7 @@ class IPAddr
368
411
  # into an IPv4-mapped IPv6 address.
369
412
  def ipv4_mapped
370
413
  if !ipv4?
371
- raise InvalidAddressError, "not an IPv4 address: #{@addr}"
414
+ raise InvalidAddressError, "not an IPv4 address: #{to_s}"
372
415
  end
373
416
  clone = self.clone.set(@addr | 0xffff00000000, Socket::AF_INET6)
374
417
  clone.instance_variable_set(:@mask_addr, @mask_addr | 0xffffffffffffffffffffffff00000000)
@@ -380,7 +423,7 @@ class IPAddr
380
423
  def ipv4_compat
381
424
  warn "IPAddr\##{__callee__} is obsolete", uplevel: 1 if $VERBOSE
382
425
  if !ipv4?
383
- raise InvalidAddressError, "not an IPv4 address: #{@addr}"
426
+ raise InvalidAddressError, "not an IPv4 address: #{to_s}"
384
427
  end
385
428
  clone = self.clone.set(@addr, Socket::AF_INET6)
386
429
  clone.instance_variable_set(:@mask_addr, @mask_addr | 0xffffffffffffffffffffffff00000000)
@@ -413,7 +456,7 @@ class IPAddr
413
456
  # Returns a string for DNS reverse lookup compatible with RFC3172.
414
457
  def ip6_arpa
415
458
  if !ipv6?
416
- raise InvalidAddressError, "not an IPv6 address: #{@addr}"
459
+ raise InvalidAddressError, "not an IPv6 address: #{to_s}"
417
460
  end
418
461
  return _reverse + ".ip6.arpa"
419
462
  end
@@ -421,7 +464,7 @@ class IPAddr
421
464
  # Returns a string for DNS reverse lookup compatible with RFC1886.
422
465
  def ip6_int
423
466
  if !ipv6?
424
- raise InvalidAddressError, "not an IPv6 address: #{@addr}"
467
+ raise InvalidAddressError, "not an IPv6 address: #{to_s}"
425
468
  end
426
469
  return _reverse + ".ip6.int"
427
470
  end
@@ -669,6 +712,7 @@ class IPAddr
669
712
  raise AddressFamilyError, "unsupported address family: #{family}"
670
713
  end
671
714
  end
715
+ requested_family = family
672
716
  prefix, prefixlen = addr.split('/', 2)
673
717
  if prefix =~ /\A\[(.*)\]\z/i
674
718
  prefix = $1
@@ -694,7 +738,7 @@ class IPAddr
694
738
  @family = Socket::AF_INET6
695
739
  end
696
740
  @zone_id = zone_id
697
- if family != Socket::AF_UNSPEC && @family != family
741
+ if requested_family != Socket::AF_UNSPEC && @family != requested_family
698
742
  raise AddressFamilyError, "address family mismatch"
699
743
  end
700
744
  if prefixlen
@@ -743,19 +787,19 @@ class IPAddr
743
787
  right = ''
744
788
  when RE_IPV6ADDRLIKE_COMPRESSED
745
789
  if $4
746
- left.count(':') <= 6 or raise InvalidAddressError, "invalid address: #{@addr}"
790
+ left.count(':') <= 6 or raise InvalidAddressError, "invalid address: #{left}"
747
791
  addr = in_addr($~[4,4])
748
792
  left = $1
749
793
  right = $3 + '0:0'
750
794
  else
751
795
  left.count(':') <= ($1.empty? || $2.empty? ? 8 : 7) or
752
- raise InvalidAddressError, "invalid address: #{@addr}"
796
+ raise InvalidAddressError, "invalid address: #{left}"
753
797
  left = $1
754
798
  right = $2
755
799
  addr = 0
756
800
  end
757
801
  else
758
- raise InvalidAddressError, "invalid address: #{@addr}"
802
+ raise InvalidAddressError, "invalid address: #{left}"
759
803
  end
760
804
  l = left.split(':')
761
805
  r = right.split(':')
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.8
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Akinori MUSHA
@@ -42,7 +42,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
42
42
  - !ruby/object:Gem::Version
43
43
  version: '0'
44
44
  requirements: []
45
- rubygems_version: 3.6.9
45
+ rubygems_version: 4.0.20
46
46
  specification_version: 4
47
47
  summary: A class to manipulate an IP address in ruby
48
48
  test_files: []