@@ -213,7 +213,13 @@ def to_s
213
213
# Returns a string containing the IP address representation in
214
214
# canonical form.
215
215
def to_string
216
- return _to_string ( @addr )
216
+ str = _to_string ( @addr )
217
+
218
+ if @family == Socket ::AF_INET6
219
+ str << zone_id . to_s
220
+ end
221
+
222
+ return str
217
223
end
218
224
219
225
# Returns a network byte ordered string form of the IP address.
@@ -385,7 +391,7 @@ def eql?(other)
385
391
386
392
# Returns a hash value used by Hash, Set, and Array classes
387
393
def hash
388
- return ( [ @addr , @mask_addr ] . hash << 1 ) | ( ipv4? ? 0 : 1 )
394
+ return ( [ @addr , @mask_addr , @zone_id ] . hash << 1 ) | ( ipv4? ? 0 : 1 )
389
395
end
390
396
391
397
# Creates a Range object for the network address.
@@ -441,18 +447,44 @@ def inspect
441
447
af = "IPv4"
442
448
when Socket ::AF_INET6
443
449
af = "IPv6"
450
+ zone_id = @zone_id . to_s
444
451
else
445
452
raise AddressFamilyError , "unsupported address family"
446
453
end
447
- return sprintf ( "#<%s: %s:%s/%s>" , self . class . name ,
448
- af , _to_string ( @addr ) , _to_string ( @mask_addr ) )
454
+ return sprintf ( "#<%s: %s:%s%s /%s>" , self . class . name ,
455
+ af , _to_string ( @addr ) , zone_id , _to_string ( @mask_addr ) )
449
456
end
450
457
451
458
# Returns the netmask in string format e.g. 255.255.0.0
452
459
def netmask
453
460
_to_string ( @mask_addr )
454
461
end
455
462
463
+ # Returns the IPv6 zone identifier, if present.
464
+ # Raises InvalidAddressError if not an IPv6 address.
465
+ def zone_id
466
+ if @family == Socket ::AF_INET6
467
+ @zone_id
468
+ else
469
+ raise InvalidAddressError , "not an IPv6 address"
470
+ end
471
+ end
472
+
473
+ # Returns the IPv6 zone identifier, if present.
474
+ # Raises InvalidAddressError if not an IPv6 address.
475
+ def zone_id = ( zid )
476
+ if @family == Socket ::AF_INET6
477
+ case zid
478
+ when nil , /\A %(\w +)\z /
479
+ @zone_id = zid
480
+ else
481
+ raise InvalidAddressError , "invalid zone identifier for address"
482
+ end
483
+ else
484
+ raise InvalidAddressError , "not an IPv6 address"
485
+ end
486
+ end
487
+
456
488
protected
457
489
458
490
# Set +@addr+, the internal stored ip address, to given +addr+. The
@@ -561,6 +593,11 @@ def initialize(addr = '::', family = Socket::AF_UNSPEC)
561
593
prefix = $1
562
594
family = Socket ::AF_INET6
563
595
end
596
+ if prefix =~ /\A (.*)(%\w +)\z /
597
+ prefix = $1
598
+ zone_id = $2
599
+ family = Socket ::AF_INET6
600
+ end
564
601
# It seems AI_NUMERICHOST doesn't do the job.
565
602
#Socket.getaddrinfo(left, nil, Socket::AF_INET6, Socket::SOCK_STREAM, nil,
566
603
# Socket::AI_NUMERICHOST)
@@ -575,6 +612,7 @@ def initialize(addr = '::', family = Socket::AF_UNSPEC)
575
612
@addr = in6_addr ( prefix )
576
613
@family = Socket ::AF_INET6
577
614
end
615
+ @zone_id = zone_id
578
616
if family != Socket ::AF_UNSPEC && @family != family
579
617
raise AddressFamilyError , "address family mismatch"
580
618
end
0 commit comments