[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:
parent
aaa8bd8b74
commit
6139d87623
2 changed files with 43 additions and 0 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in a new issue