@@ -174,14 +174,21 @@ sealed abstract class IpAddress extends IpAddressPlatform with Host with Seriali
174
174
SourceSpecificMulticast .fromIpAddress(this )
175
175
176
176
/** Narrows this address to an Ipv4Address if that is the underlying type. */
177
- def asIpv4 : Option [Ipv4Address ] = fold(Some (_), _ => None )
177
+ def asIpv4 : Option [Ipv4Address ] = collapseMappedV4. fold(Some (_), _ => None )
178
178
179
179
/** Narrows this address to an Ipv6Address if that is the underlying type. */
180
180
def asIpv6 : Option [Ipv6Address ] = fold(_ => None , Some (_))
181
181
182
182
/** Returns the version of this address. */
183
183
def version : IpVersion = fold(_ => IpVersion .V4 , _ => IpVersion .V6 )
184
184
185
+ /** Returns true if this address is a V6 address containing a mapped V4 address. */
186
+ def isMappedV4 : Boolean = fold(_ => false , Ipv6Address .MappedV4Block .contains)
187
+
188
+ /** If this address is an IPv4 mapped IPv6 address, converts to an IPv4 address, otherwise returns this. */
189
+ def collapseMappedV4 : IpAddress =
190
+ fold(identity, v6 => if (v6.isMappedV4) IpAddress .fromBytes(v6.toBytes.takeRight(4 )).get else v6)
191
+
185
192
/** Constructs a [[Cidr ]] address from this address. */
186
193
def / (prefixBits : Int ): Cidr [this .type ] = Cidr (this , prefixBits)
187
194
@@ -559,6 +566,10 @@ object Ipv6Address extends Ipv6AddressCompanionPlatform {
559
566
val SourceSpecificMulticastRangeEnd : Ipv6Address =
560
567
fromBytes(255 , 63 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 )
561
568
569
+ /** CIDR which defines the mapped IPv4 address block (https://datatracker.ietf.org/doc/html/rfc4291#section-2.5.5.2). */
570
+ val MappedV4Block : Cidr [Ipv6Address ] =
571
+ Cidr (Ipv6Address .fromBytes(0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 255 , 255 , 0 , 0 , 0 , 0 ), 96 )
572
+
562
573
/** Parses an IPv6 address from a string in RFC4291 notation, returning `None` if the string is not a valid IPv6 address. */
563
574
def fromString (value : String ): Option [Ipv6Address ] =
564
575
fromNonMixedString(value) orElse fromMixedString(value)
0 commit comments