[CLATJ#3] libclat: move generateIpv6Address() from netd to apex

generateIpv6Address() is moved from ClatdController without behavior
change. The unique_fd for socket fd is replaced by primitive int
because libbase is not supported in mainline.

Bug: 212345928
Test: build and boot
      atest libclat_test
Change-Id: I42e152e6fe3ad577a0274e1d55e737318f61176d
diff --git a/service/native/libs/libclat/clatutils.cpp b/service/native/libs/libclat/clatutils.cpp
index 2a53ba8..69076c5 100644
--- a/service/native/libs/libclat/clatutils.cpp
+++ b/service/native/libs/libclat/clatutils.cpp
@@ -14,7 +14,10 @@
 
 #include "libclat/clatutils.h"
 
+#include <errno.h>
 #include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
 
 extern "C" {
 #include "checksum.h"
@@ -46,6 +49,43 @@
     v6->s6_addr[12] = delta & 0xff;
 }
 
+// Picks a random interface ID that is checksum neutral with the IPv4 address and the NAT64 prefix.
+int generateIpv6Address(const char* iface, const in_addr v4, const in6_addr& nat64Prefix,
+                        in6_addr* v6) {
+    int s = socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
+    if (s == -1) return -errno;
+
+    if (setsockopt(s, SOL_SOCKET, SO_BINDTODEVICE, iface, strlen(iface) + 1) == -1) {
+        close(s);
+        return -errno;
+    }
+
+    sockaddr_in6 sin6 = {.sin6_family = AF_INET6, .sin6_addr = nat64Prefix};
+    if (connect(s, reinterpret_cast<struct sockaddr*>(&sin6), sizeof(sin6)) == -1) {
+        close(s);
+        return -errno;
+    }
+
+    socklen_t len = sizeof(sin6);
+    if (getsockname(s, reinterpret_cast<struct sockaddr*>(&sin6), &len) == -1) {
+        close(s);
+        return -errno;
+    }
+
+    *v6 = sin6.sin6_addr;
+
+    if (IN6_IS_ADDR_UNSPECIFIED(v6) || IN6_IS_ADDR_LOOPBACK(v6) || IN6_IS_ADDR_LINKLOCAL(v6) ||
+        IN6_IS_ADDR_SITELOCAL(v6) || IN6_IS_ADDR_ULA(v6)) {
+        close(s);
+        return -ENETUNREACH;
+    }
+
+    makeChecksumNeutral(v6, v4, nat64Prefix);
+    close(s);
+
+    return 0;
+}
+
 }  // namespace clat
 }  // namespace net
 }  // namespace android