ipaddr 1.3.0 → 1.3.1

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 (3) hide show
  1. checksums.yaml +4 -4
  2. data/lib/ipaddr.rb +73 -14
  3. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d1c0830348465e01e309792b106380c16a97cfe9f5ba003ec99d3e78d2d602bd
4
- data.tar.gz: 59a62a5f79ce024610365be4a599fa8be0afe413d184edb7e4c9517435fb4678
3
+ metadata.gz: b3a45f67694de980f29fe97b4b20675bf93b95d8250b26dfcc0549816129394a
4
+ data.tar.gz: 37d8f96d02031b7847bd8c32b22776cdf0e9596a416defc64769899d5e89c6d3
5
5
  SHA512:
6
- metadata.gz: 13aaefd68e369c3591cfe576dcf4d905cda02a7ec4b9de3b7e161817a9c676bd667e1edf4c1b4ee5816b9cac45aa80bab492095b5d46af571fca537ada32b643
7
- data.tar.gz: 3ddb2b27e66dfa04ed44a2a2617d02501fcaa6975458fdf8378a22dc6031096e05e3034f6a6542856a069fa7cf5b183bec131a13a90be7486415da41bae85924
6
+ metadata.gz: 3da16382856d2668a53ca3f270b708e0ec8d3d109e6c103aa9be482aac4b84697d12a9b928b13516a522ae355ab8c47e79299d4c18e356c6944add55a6033613
7
+ data.tar.gz: 60ec70c14d1715254f564070d8f3b7bbac87a7a07af194f99604fbf222d7cea15f08fc858497b8f9a342ea94dbccd1706f1d14b5b686792a800fce2c9cec9206
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.3.0"
44
+ VERSION = "1.3.1"
45
45
 
46
46
  # 32 bit mask for IPv4
47
47
  IN4MASK = 0xffffffff
@@ -205,6 +205,48 @@ class IPAddr
205
205
  return @addr
206
206
  end
207
207
 
208
+ # Returns a string containing the binary representation of the
209
+ # IP address value, right adjusted to the address size (32 bits
210
+ # for IPv4, 128 bits for IPv6), regardless of the prefix length.
211
+ #
212
+ # e.g.:
213
+ # require 'ipaddr'
214
+ # p IPAddr.new("192.168.1.1").to_bits
215
+ # #=> "11000000101010000000000100000001"
216
+ # p IPAddr.new("3ffe:505:2::1").to_bits
217
+ # #=> "00111111111111100000010100000101" \
218
+ # # "00000000000000100000000000000000" \
219
+ # # "00000000000000000000000000000000" \
220
+ # # "00000000000000000000000000000001"
221
+ def to_bits
222
+ case @family
223
+ when Socket::AF_INET
224
+ @addr.to_s(2).rjust(32, '0')
225
+ when Socket::AF_INET6
226
+ @addr.to_s(2).rjust(128, '0')
227
+ else
228
+ raise AddressFamilyError, "unsupported address family"
229
+ end
230
+ end
231
+
232
+ # Returns a string containing the hexadecimal representation of the
233
+ # IP address value, right adjusted to the address size.
234
+ #
235
+ # e.g.:
236
+ # require 'ipaddr'
237
+ # p IPAddr.new("192.168.1.1").to_hex #=> "c0a80101"
238
+ # p IPAddr.new("3ffe:505:2::1").to_hex #=> "3ffe0505000200000000000000000001"
239
+ def to_hex
240
+ case @family
241
+ when Socket::AF_INET
242
+ @addr.to_s(16).rjust(8, '0')
243
+ when Socket::AF_INET6
244
+ @addr.to_s(16).rjust(32, '0')
245
+ else
246
+ raise AddressFamilyError, "unsupported address family"
247
+ end
248
+ end
249
+
208
250
  # Returns a string containing the IP address representation.
209
251
  def to_s
210
252
  str = _to_string(@addr)
@@ -268,12 +310,9 @@ class IPAddr
268
310
  # Returns a network byte ordered string form of the IP address.
269
311
  def hton
270
312
  case @family
271
- when Socket::AF_INET
272
- return [@addr].pack('N')
273
- when Socket::AF_INET6
274
- return (0..7).map { |i|
275
- (@addr >> (112 - 16 * i)) & 0xffff
276
- }.pack('n8')
313
+ when Socket::AF_INET, Socket::AF_INET6
314
+ value = to_hex
315
+ return [value].pack("H#{value.length}")
277
316
  else
278
317
  raise AddressFamilyError, "unsupported address family"
279
318
  end
@@ -350,6 +389,22 @@ class IPAddr
350
389
 
351
390
  alias link_local_unicast? link_local?
352
391
 
392
+ # Returns true if the ipaddr is an unspecified address. The IPv4
393
+ # address 0.0.0.0 and the IPv6 address :: are unspecified. Unspecified
394
+ # IPv4 addresses in the IPv4-mapped IPv6 address range are also
395
+ # considered unspecified.
396
+ def unspecified?
397
+ case @family
398
+ when Socket::AF_INET
399
+ @addr == 0 && prefix == 32 # 0.0.0.0
400
+ when Socket::AF_INET6
401
+ @addr == 0 && prefix == 128 || # ::
402
+ (@addr >> 32 == 0xffff && (@addr & IN4MASK) == 0) && prefix == 128 # ::ffff:0.0.0.0
403
+ else
404
+ raise AddressFamilyError, "unsupported address family"
405
+ end
406
+ end
407
+
353
408
  # Returns true if the ipaddr is a multicast address. IPv4
354
409
  # addresses in 224.0.0.0/4 and IPv6 multicast addresses
355
410
  # in ff00::/8 are considered multicast. Multicast IPv4 addresses in the
@@ -578,7 +633,7 @@ class IPAddr
578
633
  def zone_id=(zid)
579
634
  if @family == Socket::AF_INET6
580
635
  case zid
581
- when nil, /\A%(\w+)\z/
636
+ when nil, /\A%[-0-9A-Za-z._~]+\z/
582
637
  @zone_id = zid
583
638
  else
584
639
  raise InvalidAddressError, "invalid zone identifier for address"
@@ -717,8 +772,9 @@ class IPAddr
717
772
  if prefix =~ /\A\[(.*)\]\z/i
718
773
  prefix = $1
719
774
  family = Socket::AF_INET6
775
+ bracketed = true
720
776
  end
721
- if prefix =~ /\A(.*)(%\w+)\z/
777
+ if prefix =~ /\A(.*)(%[-0-9A-Za-z._~]+)\z/
722
778
  prefix = $1
723
779
  zone_id = $2
724
780
  family = Socket::AF_INET6
@@ -743,6 +799,12 @@ class IPAddr
743
799
  end
744
800
  if prefixlen
745
801
  mask!(prefixlen)
802
+
803
+ if bracketed
804
+ warn "bracketed IPv6 address with a prefix length is an invalid address " \
805
+ "and will raise IPAddr::InvalidAddressError in a future version: #{addr}",
806
+ uplevel: 1
807
+ end
746
808
  else
747
809
  @mask_addr = (@family == Socket::AF_INET) ? IN4MASK : IN6MASK
748
810
  end
@@ -787,7 +849,7 @@ class IPAddr
787
849
  right = ''
788
850
  when RE_IPV6ADDRLIKE_COMPRESSED
789
851
  if $4
790
- left.count(':') <= 6 or raise InvalidAddressError, "invalid address: #{left}"
852
+ left.count(':') <= ($1.empty? ? 7 : 6) or raise InvalidAddressError, "invalid address: #{left}"
791
853
  addr = in_addr($~[4,4])
792
854
  left = $1
793
855
  right = $3 + '0:0'
@@ -804,9 +866,6 @@ class IPAddr
804
866
  l = left.split(':')
805
867
  r = right.split(':')
806
868
  rest = 8 - l.size - r.size
807
- if rest < 0
808
- return nil
809
- end
810
869
  (l + Array.new(rest, '0') + r).inject(0) { |i, s|
811
870
  i << 16 | s.hex
812
871
  } | addr
@@ -830,7 +889,7 @@ class IPAddr
830
889
  (@addr >> (8 * i)) & 0xff
831
890
  }.join('.')
832
891
  when Socket::AF_INET6
833
- return ("%.32x" % @addr).reverse!.gsub!(/.(?!$)/, '\&.')
892
+ return to_hex.reverse.chars.join('.')
834
893
  else
835
894
  raise AddressFamilyError, "unsupported address family"
836
895
  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.3.0
4
+ version: 1.3.1
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: 4.0.20
45
+ rubygems_version: 3.6.9
46
46
  specification_version: 4
47
47
  summary: A class to manipulate an IP address in ruby
48
48
  test_files: []