Add util method to generate IPv4-mapped IPv6 address from IPv4 address Cherry-pick of aosp/2795709 to backport VPN security fix to non-mainline devices. Having Merged-In to prevent automerger to udc-mainlie-prod where frameworks/libs/net does not exist. Bug: 193031925 Test: TH (cherry picked from https://googleplex-android-review.googlesource.com/q/commit:03eb6f09360de988687c06940b6f13be7e650b34) (cherry picked from https://googleplex-android-review.googlesource.com/q/commit:29e53bd862d7b4c30552f188065e1239e84c401e) Merged-In: Iaa5d5f31904f8a122cb96f2c3f0e3499a2577664 Change-Id: Iaa5d5f31904f8a122cb96f2c3f0e3499a2577664
diff --git a/common/framework/com/android/net/module/util/InetAddressUtils.java b/common/framework/com/android/net/module/util/InetAddressUtils.java index 40fc59f..4b27a97 100644 --- a/common/framework/com/android/net/module/util/InetAddressUtils.java +++ b/common/framework/com/android/net/module/util/InetAddressUtils.java
@@ -21,6 +21,7 @@ import android.util.Log; +import java.net.Inet4Address; import java.net.Inet6Address; import java.net.InetAddress; import java.net.UnknownHostException; @@ -32,6 +33,7 @@ public class InetAddressUtils { private static final String TAG = InetAddressUtils.class.getSimpleName(); + private static final int INET4_ADDR_LENGTH = 4; private static final int INET6_ADDR_LENGTH = 16; /** @@ -93,5 +95,29 @@ } } + /** + * Create a v4-mapped v6 address from v4 address + * + * @param v4Addr Inet4Address which is converted to v4-mapped v6 address + * @return v4-mapped v6 address + */ + public static Inet6Address v4MappedV6Address(@NonNull final Inet4Address v4Addr) { + final byte[] v6AddrBytes = new byte[INET6_ADDR_LENGTH]; + v6AddrBytes[10] = (byte) 0xFF; + v6AddrBytes[11] = (byte) 0xFF; + System.arraycopy(v4Addr.getAddress(), 0 /* srcPos */, v6AddrBytes, 12 /* dstPos */, + INET4_ADDR_LENGTH); + try { + // Using Inet6Address.getByAddress since InetAddress.getByAddress converts v4-mapped v6 + // address to v4 address internally and returns Inet4Address + return Inet6Address.getByAddress(null /* host */, v6AddrBytes, -1 /* scope_id */); + } catch (UnknownHostException impossible) { + // getByAddress throws UnknownHostException when the argument is the invalid length + // but INET6_ADDR_LENGTH(16) is the valid length. + Log.wtf(TAG, "Failed to generate v4-mapped v6 address from " + v4Addr, impossible); + return null; + } + } + private InetAddressUtils() {} }