Move createTunInterface to its own test file for use elsewhere.

Bug: 28362720
Test: test-only change. netd_{unit,integration}_test pass.
Change-Id: I89f7c922ae8f8a550db58938dacff92390cc1d0f
diff --git a/tests/binder_test.cpp b/tests/binder_test.cpp
index c88b02a..1481186 100644
--- a/tests/binder_test.cpp
+++ b/tests/binder_test.cpp
@@ -43,6 +43,7 @@
 
 #include "NetdConstants.h"
 #include "Stopwatch.h"
+#include "tun_interface.h"
 #include "android/net/INetd.h"
 #include "android/net/UidRange.h"
 #include "binder/IServiceManager.h"
@@ -53,6 +54,7 @@
 using namespace android::base;
 using namespace android::binder;
 using android::net::INetd;
+using android::net::TunInterface;
 using android::net::UidRange;
 
 static const char* IP_RULE_V4 = "-4";
@@ -75,33 +77,23 @@
 
     // Static because setting up the tun interface takes about 40ms.
     static void SetUpTestCase() {
-        sTunFd = createTunInterface();
-        ASSERT_LE(sTunIfName.size(), static_cast<size_t>(IFNAMSIZ));
-        ASSERT_NE(-1, sTunFd);
+        ASSERT_EQ(0, sTun.init());
+        ASSERT_LE(sTun.name().size(), static_cast<size_t>(IFNAMSIZ));
     }
 
     static void TearDownTestCase() {
         // Closing the socket removes the interface and IP addresses.
-        close(sTunFd);
+        sTun.destroy();
     }
 
     static void fakeRemoteSocketPair(int *clientSocket, int *serverSocket, int *acceptedSocket);
-    static int createTunInterface();
 
 protected:
     sp<INetd> mNetd;
-    static int sTunFd;
-    static std::string sTunIfName;
-    static in6_addr sSrcAddr, sDstAddr;
-    static char sSrcStr[], sDstStr[];
+    static TunInterface sTun;
 };
 
-int BinderTest::sTunFd;
-std::string BinderTest::sTunIfName;
-in6_addr BinderTest::sSrcAddr;
-in6_addr BinderTest::sDstAddr;
-char BinderTest::sSrcStr[INET6_ADDRSTRLEN];
-char BinderTest::sDstStr[INET6_ADDRSTRLEN];
+TunInterface BinderTest::sTun;
 
 class TimedOperation : public Stopwatch {
 public:
@@ -332,52 +324,10 @@
     EXPECT_EQ(initialRulesV6, listIpRules(IP_RULE_V6));
 }
 
-int BinderTest::createTunInterface() {
-    // Generate a random ULA address pair.
-    arc4random_buf(&sSrcAddr, sizeof(sSrcAddr));
-    sSrcAddr.s6_addr[0] = 0xfd;
-    memcpy(&sDstAddr, &sSrcAddr, sizeof(sDstAddr));
-    sDstAddr.s6_addr[15] ^= 1;
-
-    // Convert the addresses to strings because that's what ifc_add_address takes.
-    sockaddr_in6 src6 = { .sin6_family = AF_INET6, .sin6_addr = sSrcAddr, };
-    sockaddr_in6 dst6 = { .sin6_family = AF_INET6, .sin6_addr = sDstAddr, };
-    int flags = NI_NUMERICHOST;
-    if (getnameinfo((sockaddr *) &src6, sizeof(src6), sSrcStr, sizeof(sSrcStr), NULL, 0, flags) ||
-        getnameinfo((sockaddr *) &dst6, sizeof(dst6), sDstStr, sizeof(sDstStr), NULL, 0, flags)) {
-        return -1;
-    }
-
-    // Create a tun interface with a name based on our PID.
-    sTunIfName = StringPrintf("netdtest%u", getpid());
-    struct ifreq ifr = {
-        .ifr_ifru = { .ifru_flags = IFF_TUN },
-    };
-    snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s", sTunIfName.c_str());
-
-    int fd = open(TUN_DEV, O_RDWR | O_NONBLOCK | O_CLOEXEC);
-    EXPECT_NE(-1, fd) << TUN_DEV << ": " << strerror(errno);
-    if (fd == -1) return fd;
-
-    int ret = ioctl(fd, TUNSETIFF, &ifr, sizeof(ifr));
-    EXPECT_EQ(0, ret) << "TUNSETIFF: " << strerror(errno);
-    if (ret) {
-        close(fd);
-        return -1;
-    }
-
-    if (ifc_add_address(ifr.ifr_name, sSrcStr, 64) ||
-        ifc_add_address(ifr.ifr_name, sDstStr, 64)) {
-        close(fd);
-        return -1;
-    }
-    return fd;
-}
-
 // Create a socket pair that isLoopbackSocket won't think is local.
 void BinderTest::fakeRemoteSocketPair(int *clientSocket, int *serverSocket, int *acceptedSocket) {
     *serverSocket = socket(AF_INET6, SOCK_STREAM, 0);
-    struct sockaddr_in6 server6 = { .sin6_family = AF_INET6, .sin6_addr = sDstAddr };
+    struct sockaddr_in6 server6 = { .sin6_family = AF_INET6, .sin6_addr = sTun.dstAddr() };
     ASSERT_EQ(0, bind(*serverSocket, (struct sockaddr *) &server6, sizeof(server6)));
 
     socklen_t addrlen = sizeof(server6);
@@ -385,7 +335,7 @@
     ASSERT_EQ(0, listen(*serverSocket, 10));
 
     *clientSocket = socket(AF_INET6, SOCK_STREAM, 0);
-    struct sockaddr_in6 client6 = { .sin6_family = AF_INET6, .sin6_addr = sSrcAddr };
+    struct sockaddr_in6 client6 = { .sin6_family = AF_INET6, .sin6_addr = sTun.srcAddr() };
     ASSERT_EQ(0, bind(*clientSocket, (struct sockaddr *) &client6, sizeof(client6)));
     ASSERT_EQ(0, connect(*clientSocket, (struct sockaddr *) &server6, sizeof(server6)));
     ASSERT_EQ(0, getsockname(*clientSocket, (struct sockaddr *) &client6, &addrlen));
@@ -590,7 +540,7 @@
 
         // [1.a] Add the address.
         binder::Status status = mNetd->interfaceAddAddress(
-                sTunIfName, td.addrString, td.prefixLength);
+                sTun.name(), td.addrString, td.prefixLength);
         if (td.expectSuccess) {
             EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
         } else {
@@ -600,13 +550,13 @@
 
         // [1.b] Verify the addition meets the expectation.
         if (td.expectSuccess) {
-            EXPECT_TRUE(interfaceHasAddress(sTunIfName, td.addrString, td.prefixLength));
+            EXPECT_TRUE(interfaceHasAddress(sTun.name(), td.addrString, td.prefixLength));
         } else {
-            EXPECT_FALSE(interfaceHasAddress(sTunIfName, td.addrString, -1));
+            EXPECT_FALSE(interfaceHasAddress(sTun.name(), td.addrString, -1));
         }
 
         // [2.a] Try to remove the address.  If it was not previously added, removing it fails.
-        status = mNetd->interfaceDelAddress(sTunIfName, td.addrString, td.prefixLength);
+        status = mNetd->interfaceDelAddress(sTun.name(), td.addrString, td.prefixLength);
         if (td.expectSuccess) {
             EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
         } else {
@@ -615,7 +565,7 @@
         }
 
         // [2.b] No matter what, the address should not be present.
-        EXPECT_FALSE(interfaceHasAddress(sTunIfName, td.addrString, -1));
+        EXPECT_FALSE(interfaceHasAddress(sTun.name(), td.addrString, -1));
     }
 }
 
@@ -628,13 +578,13 @@
         const char *value;
         const int expectedReturnCode;
     } kTestData[] = {
-        { INetd::IPV4, INetd::CONF, sTunIfName.c_str(), "arp_ignore", "1", 0 },
-        { -1, INetd::CONF, sTunIfName.c_str(), "arp_ignore", "1", EAFNOSUPPORT },
-        { INetd::IPV4, -1, sTunIfName.c_str(), "arp_ignore", "1", EINVAL },
+        { INetd::IPV4, INetd::CONF, sTun.name().c_str(), "arp_ignore", "1", 0 },
+        { -1, INetd::CONF, sTun.name().c_str(), "arp_ignore", "1", EAFNOSUPPORT },
+        { INetd::IPV4, -1, sTun.name().c_str(), "arp_ignore", "1", EINVAL },
         { INetd::IPV4, INetd::CONF, "..", "conf/lo/arp_ignore", "1", EINVAL },
         { INetd::IPV4, INetd::CONF, ".", "lo/arp_ignore", "1", EINVAL },
-        { INetd::IPV4, INetd::CONF, sTunIfName.c_str(), "../all/arp_ignore", "1", EINVAL },
-        { INetd::IPV6, INetd::NEIGH, sTunIfName.c_str(), "ucast_solicit", "7", 0 },
+        { INetd::IPV4, INetd::CONF, sTun.name().c_str(), "../all/arp_ignore", "1", EINVAL },
+        { INetd::IPV6, INetd::NEIGH, sTun.name().c_str(), "ucast_solicit", "7", 0 },
     };
 
     for (unsigned int i = 0; i < arraysize(kTestData); i++) {