[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
This commit is contained in:
Hungming Chen 2021-12-17 15:47:26 +08:00
commit 6139d87623
2 changed files with 43 additions and 0 deletions

View file

@ -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 @@ void makeChecksumNeutral(in6_addr* v6, const in_addr v4, const in6_addr& nat64Pr
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

View file

@ -21,6 +21,9 @@ namespace net {
namespace clat {
void makeChecksumNeutral(in6_addr* v6, const in_addr v4, const in6_addr& nat64Prefix);
int generateIpv6Address(const char* iface, const in_addr v4, const in6_addr& nat64Prefix,
in6_addr* v6);
} // namespace clat
} // namespace net
} // namespace android