Use dnsproxyd_protocol_headers instead of libnetd_client_headers for NETID_USE_LOCAL_NAMESERVERS am: 12a1f2d8b5 am: 3b332209b5
Original change: https://googleplex-android-review.googlesource.com/c/platform/external/android-clat/+/11626547
Change-Id: Ia07699fd37b2a5ff34d6e6ff19d161ec4e23114b
diff --git a/Android.bp b/Android.bp
index 8585780..ac24a00 100644
--- a/Android.bp
+++ b/Android.bp
@@ -10,20 +10,17 @@
"-Wno-address-of-packed-member",
],
- // For NETID_UNSET and MARK_UNSET.
- include_dirs: ["bionic/libc/dns/include"],
-
- // For NETID_USE_LOCAL_NAMESERVERS.
- header_libs: ["dnsproxyd_protocol_headers"],
+ // For MARK_UNSET.
+ header_libs: [
+ "libnetd_client_headers"
+ ],
}
// Code used both by the daemon and by unit tests.
filegroup {
name: "clatd_common",
srcs: [
- "config.c",
"clatd.c",
- "dns64.c",
"dump.c",
"getaddr.c",
"icmp.c",
@@ -68,12 +65,6 @@
],
}
-// The configuration file.
-prebuilt_etc {
- name: "clatd.conf",
- src: "clatd.conf",
-}
-
// Unit tests.
cc_test {
name: "clatd_test",
diff --git a/METADATA b/METADATA
new file mode 100644
index 0000000..d97975c
--- /dev/null
+++ b/METADATA
@@ -0,0 +1,3 @@
+third_party {
+ license_type: NOTICE
+}
diff --git a/clatd.c b/clatd.c
index 54fc2f7..422cded 100644
--- a/clatd.c
+++ b/clatd.c
@@ -39,18 +39,19 @@
#include <sys/capability.h>
#include <sys/uio.h>
-#include <private/android_filesystem_config.h>
+#include <netid_client.h> // For MARK_UNSET.
+#include <private/android_filesystem_config.h> // For AID_CLAT.
#include "clatd.h"
#include "config.h"
#include "dump.h"
#include "getaddr.h"
#include "logging.h"
-#include "resolv_netid.h"
#include "ring.h"
#include "setif.h"
#include "translate.h"
-#include "tun.h"
+
+struct clat_config Global_Clatd_Config;
/* 40 bytes IPv6 header - 20 bytes IPv4 header + 8 bytes fragment header */
#define MTU_DELTA 28
@@ -98,7 +99,7 @@
struct sockaddr_ll sll = {
.sll_family = AF_PACKET,
.sll_protocol = htons(ETH_P_IPV6),
- .sll_ifindex = if_nametoindex(Global_Clatd_Config.default_pdp_interface),
+ .sll_ifindex = if_nametoindex(Global_Clatd_Config.native_ipv6_interface),
.sll_pkttype = PACKET_OTHERHOST, // The 464xlat IPv6 address is not assigned to the kernel.
};
if (bind(sock, (struct sockaddr *)&sll, sizeof(sll))) {
@@ -109,52 +110,15 @@
return 1;
}
-/* function: ipv4_address_generate
- * picks a free IPv4 address from the local subnet or exits if there are no free addresses
- * returns: the IPv4 address as an in_addr_t
- */
-static in_addr_t ipv4_address_generate() {
- // Pick an IPv4 address to use by finding a free address in the configured prefix. Technically,
- // there is a race here - if another clatd calls config_select_ipv4_address after we do, but
- // before we call add_address, it can end up having the same IP address as we do. But the time
- // window in which this can happen is extremely small, and even if we end up with a duplicate
- // address, the only damage is that IPv4 TCP connections won't be reset until both interfaces go
- // down.
- in_addr_t localaddr = config_select_ipv4_address(&Global_Clatd_Config.ipv4_local_subnet,
- Global_Clatd_Config.ipv4_local_prefixlen);
- if (localaddr == INADDR_NONE) {
- logmsg(ANDROID_LOG_FATAL, "No free IPv4 address in %s/%d",
- inet_ntoa(Global_Clatd_Config.ipv4_local_subnet),
- Global_Clatd_Config.ipv4_local_prefixlen);
- exit(1);
- }
- return localaddr;
-}
-
-/* function: ipv4_address_from_cmdline
- * configures the IPv4 address specified on the command line, or exits if the address is not valid
- * v4_addr - a string, the IPv4 address
- * returns: the IPv4 address as an in_addr_t
- */
-static in_addr_t ipv4_address_from_cmdline(const char *v4_addr) {
- in_addr_t localaddr;
- if (!inet_pton(AF_INET, v4_addr, &localaddr)) {
- logmsg(ANDROID_LOG_FATAL, "Invalid IPv4 address %s", v4_addr);
- exit(1);
- }
- return localaddr;
-}
-
/* function: configure_tun_ip
* configures the ipv4 and ipv6 addresses on the tunnel interface
* tunnel - tun device data
* mtu - mtu of tun device
*/
void configure_tun_ip(const struct tun_data *tunnel, const char *v4_addr, int mtu) {
- if (v4_addr) {
- Global_Clatd_Config.ipv4_local_subnet.s_addr = ipv4_address_from_cmdline(v4_addr);
- } else {
- Global_Clatd_Config.ipv4_local_subnet.s_addr = ipv4_address_generate();
+ if (!v4_addr || !inet_pton(AF_INET, v4_addr, &Global_Clatd_Config.ipv4_local_subnet.s_addr)) {
+ logmsg(ANDROID_LOG_FATAL, "Invalid IPv4 address %s", v4_addr);
+ exit(1);
}
char addrstr[INET_ADDRSTRLEN];
@@ -272,43 +236,6 @@
}
}
-/* function: clat_ipv6_address_from_interface
- * picks the clat IPv6 address based on the interface address
- * interface - uplink interface name
- * returns: 1 on success, 0 on failure
- */
-static int clat_ipv6_address_from_interface(const char *interface) {
- union anyip *interface_ip;
-
- // TODO: check that the prefix length is /64.
- interface_ip = getinterface_ip(interface, AF_INET6);
- if (!interface_ip) {
- logmsg(ANDROID_LOG_ERROR, "Unable to find an IPv6 address on interface %s", interface);
- return 0;
- }
-
- // Generate an interface ID.
- config_generate_local_ipv6_subnet(&interface_ip->ip6);
-
- Global_Clatd_Config.ipv6_local_subnet = interface_ip->ip6;
- free(interface_ip);
- return 1;
-}
-
-/* function: clat_ipv6_address_from_cmdline
- * parses the clat IPv6 address from the command line
- * v4_addr - a string, the IPv6 address
- * returns: 1 on success, 0 on failure
- */
-static int clat_ipv6_address_from_cmdline(const char *v6_addr) {
- if (!inet_pton(AF_INET6, v6_addr, &Global_Clatd_Config.ipv6_local_subnet)) {
- logmsg(ANDROID_LOG_FATAL, "Invalid source address %s", v6_addr);
- return 0;
- }
-
- return 1;
-}
-
/* function: configure_clat_ipv6_address
* picks the clat IPv6 address and configures packet translation to use it.
* tunnel - tun device data
@@ -317,13 +244,10 @@
*/
int configure_clat_ipv6_address(const struct tun_data *tunnel, const char *interface,
const char *v6_addr) {
- int ret;
- if (v6_addr) {
- ret = clat_ipv6_address_from_cmdline(v6_addr);
- } else {
- ret = clat_ipv6_address_from_interface(interface);
+ if (!v6_addr || !inet_pton(AF_INET6, v6_addr, &Global_Clatd_Config.ipv6_local_subnet)) {
+ logmsg(ANDROID_LOG_FATAL, "Invalid source address %s", v6_addr);
+ return 0;
}
- if (!ret) return 0;
char addrstr[INET6_ADDRSTRLEN];
inet_ntop(AF_INET6, &Global_Clatd_Config.ipv6_local_subnet, addrstr, sizeof(addrstr));
@@ -388,15 +312,16 @@
* reads the configuration and applies it to the interface
* uplink_interface - network interface to use to reach the ipv6 internet
* plat_prefix - PLAT prefix to use
+ * v4_addr - the v4 address to use on the tunnel interface
+ * v6_addr - the v6 address to use on the native interface
* tunnel - tun device data
- * net_id - NetID to use, NETID_UNSET indicates use of default network
* mark - the socket mark to use for the sending raw socket
*/
void configure_interface(const char *uplink_interface, const char *plat_prefix, const char *v4_addr,
- const char *v6_addr, struct tun_data *tunnel, unsigned net_id,
- uint32_t mark) {
- if (!read_config("/system/etc/clatd.conf", uplink_interface, plat_prefix, net_id)) {
- logmsg(ANDROID_LOG_FATAL, "read_config failed");
+ const char *v6_addr, struct tun_data *tunnel, uint32_t mark) {
+ Global_Clatd_Config.native_ipv6_interface = uplink_interface;
+ if (!plat_prefix || inet_pton(AF_INET6, plat_prefix, &Global_Clatd_Config.plat_subnet) <= 0) {
+ logmsg(ANDROID_LOG_FATAL, "invalid IPv6 address specified for plat prefix: %s", plat_prefix);
exit(1);
}
@@ -501,8 +426,9 @@
}
time_t now = time(NULL);
- if (last_interface_poll < (now - INTERFACE_POLL_FREQUENCY)) {
- if (ipv6_address_changed(Global_Clatd_Config.default_pdp_interface)) {
+ if (now >= (last_interface_poll + INTERFACE_POLL_FREQUENCY)) {
+ last_interface_poll = now;
+ if (ipv6_address_changed(Global_Clatd_Config.native_ipv6_interface)) {
break;
}
}
diff --git a/clatd.conf b/clatd.conf
deleted file mode 100644
index aef9c75..0000000
--- a/clatd.conf
+++ /dev/null
@@ -1,20 +0,0 @@
-# Host IID to use as the source of CLAT traffic.
-# This is a /128 taken out of the /64 on the parent interface.
-# A host IID of :: means to generate a checksum-neutral, random IID.
-ipv6_host_id ::
-
-# IPv4 address configuration to use when selecting a host address. The first
-# clat daemon started will use the address specified by ipv4_local_subnet. If
-# more than one daemon is run at the same time, subsequent daemons will use
-# other addresses in the prefix of length ipv4_local prefixlen that contains
-# ipv4_local_subnet. The default is to use the IANA-assigned range 192.0.0.0/29,
-# which allows up to 8 clat daemons (.4, .5, .6, .7, .0, .1, .2, .3).
-ipv4_local_subnet 192.0.0.4
-ipv4_local_prefixlen 29
-
-# get the plat_subnet from dns lookups (requires DNS64)
-plat_from_dns64 yes
-
-# plat subnet to send ipv4 traffic to. This is a /96 subnet.
-# This setting only makes sense with: plat_from_dns64 no
-#plat_subnet 2001:db8:1:2:3:4::
diff --git a/clatd.h b/clatd.h
index e1d28a7..a3f9326 100644
--- a/clatd.h
+++ b/clatd.h
@@ -45,7 +45,7 @@
const char *src_addr);
int detect_mtu(const struct in6_addr *plat_subnet, uint32_t plat_suffix, uint32_t mark);
void configure_interface(const char *uplink_interface, const char *plat_prefix, const char *v4_addr,
- const char *v6, struct tun_data *tunnel, unsigned net_id, uint32_t mark);
+ const char *v6, struct tun_data *tunnel, uint32_t mark);
void event_loop(struct tun_data *tunnel);
/* function: parse_int
diff --git a/clatd_test.cpp b/clatd_test.cpp
index 5de7b63..c16a4dd 100644
--- a/clatd_test.cpp
+++ b/clatd_test.cpp
@@ -34,7 +34,6 @@
#include "getaddr.h"
#include "netutils/checksum.h"
#include "translate.h"
-#include "tun.h"
}
// For convenience.
@@ -585,9 +584,7 @@
inet_pton(AF_INET, kIPv4LocalAddr, &Global_Clatd_Config.ipv4_local_subnet);
inet_pton(AF_INET6, kIPv6PlatSubnet, &Global_Clatd_Config.plat_subnet);
memset(&Global_Clatd_Config.ipv6_local_subnet, 0, sizeof(in6_addr));
- Global_Clatd_Config.ipv6_host_id = in6addr_any;
- Global_Clatd_Config.use_dynamic_iid = 1;
- Global_Clatd_Config.default_pdp_interface = const_cast<char *>(sTun.name().c_str());
+ Global_Clatd_Config.native_ipv6_interface = const_cast<char *>(sTun.name().c_str());
}
// Static because setting up the tun interface takes about 40ms.
@@ -627,185 +624,12 @@
EXPECT_FALSE(ipv6_prefix_equal(&subnet2, &Global_Clatd_Config.ipv6_local_subnet));
}
-int count_onebits(const void *data, size_t size) {
- int onebits = 0;
- for (size_t pos = 0; pos < size; pos++) {
- uint8_t *byte = ((uint8_t *)data) + pos;
- for (int shift = 0; shift < 8; shift++) {
- onebits += (*byte >> shift) & 1;
- }
- }
- return onebits;
-}
-
-TEST_F(ClatdTest, TestCountOnebits) {
- uint64_t i;
- i = 1;
- ASSERT_EQ(1, count_onebits(&i, sizeof(i)));
- i <<= 61;
- ASSERT_EQ(1, count_onebits(&i, sizeof(i)));
- i |= ((uint64_t)1 << 33);
- ASSERT_EQ(2, count_onebits(&i, sizeof(i)));
- i = 0xf1000202020000f0;
- ASSERT_EQ(5 + 1 + 1 + 1 + 4, count_onebits(&i, sizeof(i)));
-}
-
-TEST_F(ClatdTest, TestGenIIDConfigured) {
- struct in6_addr myaddr, expected;
- Global_Clatd_Config.use_dynamic_iid = 0;
- ASSERT_TRUE(inet_pton(AF_INET6, "::bad:ace:d00d", &Global_Clatd_Config.ipv6_host_id));
- ASSERT_TRUE(inet_pton(AF_INET6, "2001:db8:1:2:0:bad:ace:d00d", &expected));
- ASSERT_TRUE(inet_pton(AF_INET6, "2001:db8:1:2:f076:ae99:124e:aa54", &myaddr));
- config_generate_local_ipv6_subnet(&myaddr);
- expect_ipv6_addr_equal(&expected, &myaddr);
-
- Global_Clatd_Config.use_dynamic_iid = 1;
- config_generate_local_ipv6_subnet(&myaddr);
- EXPECT_FALSE(IN6_ARE_ADDR_EQUAL(&expected, &myaddr));
-}
-
-TEST_F(ClatdTest, TestGenIIDRandom) {
- struct in6_addr interface_ipv6;
- ASSERT_TRUE(inet_pton(AF_INET6, "2001:db8:1:2:f076:ae99:124e:aa54", &interface_ipv6));
- Global_Clatd_Config.ipv6_host_id = in6addr_any;
-
- // Generate a boatload of random IIDs.
- int onebits = 0;
- uint64_t prev_iid = 0;
- for (int i = 0; i < 100000; i++) {
- struct in6_addr myaddr = interface_ipv6;
-
- config_generate_local_ipv6_subnet(&myaddr);
-
- // Check the generated IP address is in the same prefix as the interface IPv6 address.
- EXPECT_TRUE(ipv6_prefix_equal(&interface_ipv6, &myaddr));
-
- // Check that consecutive IIDs are not the same.
- uint64_t iid = *(uint64_t *)(&myaddr.s6_addr[8]);
- ASSERT_TRUE(iid != prev_iid)
- << "Two consecutive random IIDs are the same: "
- << std::showbase << std::hex
- << iid << "\n";
- prev_iid = iid;
-
- // Check that the IID is checksum-neutral with the NAT64 prefix and the
- // local prefix.
- struct in_addr *ipv4addr = &Global_Clatd_Config.ipv4_local_subnet;
- struct in6_addr *plat_subnet = &Global_Clatd_Config.plat_subnet;
-
- uint16_t c1 = ip_checksum_finish(ip_checksum_add(0, ipv4addr, sizeof(*ipv4addr)));
- uint16_t c2 = ip_checksum_finish(ip_checksum_add(0, plat_subnet, sizeof(*plat_subnet)) +
- ip_checksum_add(0, &myaddr, sizeof(myaddr)));
-
- if (c1 != c2) {
- char myaddr_str[INET6_ADDRSTRLEN], plat_str[INET6_ADDRSTRLEN], ipv4_str[INET6_ADDRSTRLEN];
- inet_ntop(AF_INET6, &myaddr, myaddr_str, sizeof(myaddr_str));
- inet_ntop(AF_INET6, plat_subnet, plat_str, sizeof(plat_str));
- inet_ntop(AF_INET, ipv4addr, ipv4_str, sizeof(ipv4_str));
- FAIL()
- << "Bad IID: " << myaddr_str
- << " not checksum-neutral with " << ipv4_str << " and " << plat_str
- << std::showbase << std::hex
- << "\n IPv4 checksum: " << c1
- << "\n IPv6 checksum: " << c2
- << "\n";
- }
-
- // Check that IIDs are roughly random and use all the bits by counting the
- // total number of bits set to 1 in a random sample of 100000 generated IIDs.
- onebits += count_onebits(&iid, sizeof(iid));
- }
- EXPECT_LE(3190000, onebits);
- EXPECT_GE(3210000, onebits);
-}
-
-extern "C" addr_free_func config_is_ipv4_address_free;
-int never_free(in_addr_t /* addr */) { return 0; }
-int always_free(in_addr_t /* addr */) { return 1; }
-int only2_free(in_addr_t addr) { return (ntohl(addr) & 0xff) == 2; }
-int over6_free(in_addr_t addr) { return (ntohl(addr) & 0xff) >= 6; }
-int only10_free(in_addr_t addr) { return (ntohl(addr) & 0xff) == 10; }
-
-TEST_F(ClatdTest, SelectIPv4Address) {
- struct in_addr addr;
-
- inet_pton(AF_INET, kIPv4LocalAddr, &addr);
-
- addr_free_func orig_config_is_ipv4_address_free = config_is_ipv4_address_free;
-
- // If no addresses are free, return INADDR_NONE.
- config_is_ipv4_address_free = never_free;
- EXPECT_EQ(INADDR_NONE, config_select_ipv4_address(&addr, 29));
- EXPECT_EQ(INADDR_NONE, config_select_ipv4_address(&addr, 16));
-
- // If the configured address is free, pick that. But a prefix that's too big is invalid.
- config_is_ipv4_address_free = always_free;
- EXPECT_EQ(inet_addr(kIPv4LocalAddr), config_select_ipv4_address(&addr, 29));
- EXPECT_EQ(inet_addr(kIPv4LocalAddr), config_select_ipv4_address(&addr, 20));
- EXPECT_EQ(INADDR_NONE, config_select_ipv4_address(&addr, 15));
-
- // A prefix length of 32 works, but anything above it is invalid.
- EXPECT_EQ(inet_addr(kIPv4LocalAddr), config_select_ipv4_address(&addr, 32));
- EXPECT_EQ(INADDR_NONE, config_select_ipv4_address(&addr, 33));
-
- // If another address is free, pick it.
- config_is_ipv4_address_free = over6_free;
- EXPECT_EQ(inet_addr("192.0.0.6"), config_select_ipv4_address(&addr, 29));
-
- // Check that we wrap around to addresses that are lower than the first address.
- config_is_ipv4_address_free = only2_free;
- EXPECT_EQ(inet_addr("192.0.0.2"), config_select_ipv4_address(&addr, 29));
- EXPECT_EQ(INADDR_NONE, config_select_ipv4_address(&addr, 30));
-
- // If a free address exists outside the prefix, we don't pick it.
- config_is_ipv4_address_free = only10_free;
- EXPECT_EQ(INADDR_NONE, config_select_ipv4_address(&addr, 29));
- EXPECT_EQ(inet_addr("192.0.0.10"), config_select_ipv4_address(&addr, 24));
-
- // Now try using the real function which sees if IP addresses are free using bind().
- // Assume that the machine running the test has the address 127.0.0.1, but not 8.8.8.8.
- config_is_ipv4_address_free = orig_config_is_ipv4_address_free;
- addr.s_addr = inet_addr("8.8.8.8");
- EXPECT_EQ(inet_addr("8.8.8.8"), config_select_ipv4_address(&addr, 29));
-
- addr.s_addr = inet_addr("127.0.0.1");
- EXPECT_EQ(inet_addr("127.0.0.2"), config_select_ipv4_address(&addr, 29));
-}
-
TEST_F(ClatdTest, DetectMtu) {
// ::1 with bottom 32 bits set to 1 is still ::1 which routes via lo with mtu of 64KiB
ASSERT_EQ(detect_mtu(&in6addr_loopback, htonl(1), 0 /*MARK_UNSET*/), 65536);
}
-TEST_F(ClatdTest, ConfigureTunIp) {
- addr_free_func orig_config_is_ipv4_address_free = config_is_ipv4_address_free;
- config_is_ipv4_address_free = over6_free;
-
- Global_Clatd_Config.ipv4_local_prefixlen = 29;
-
- // Create an interface for configure_tun_ip to configure and bring up.
- TunInterface v4Iface;
- ASSERT_EQ(0, v4Iface.init());
- struct tun_data tunnel = makeTunData();
- strlcpy(tunnel.device4, v4Iface.name().c_str(), sizeof(tunnel.device4));
-
- configure_tun_ip(&tunnel, nullptr /* v4_addr */, 1472);
- EXPECT_EQ(inet_addr("192.0.0.6"), Global_Clatd_Config.ipv4_local_subnet.s_addr);
-
- union anyip *ip = getinterface_ip(v4Iface.name().c_str(), AF_INET);
- EXPECT_EQ(inet_addr("192.0.0.6"), ip->ip4.s_addr);
- free(ip);
-
- config_is_ipv4_address_free = orig_config_is_ipv4_address_free;
- v4Iface.destroy();
-}
-
TEST_F(ClatdTest, ConfigureTunIpManual) {
- addr_free_func orig_config_is_ipv4_address_free = config_is_ipv4_address_free;
- config_is_ipv4_address_free = over6_free;
-
- Global_Clatd_Config.ipv4_local_prefixlen = 29;
-
// Create an interface for configure_tun_ip to configure and bring up.
TunInterface v4Iface;
ASSERT_EQ(0, v4Iface.init());
@@ -820,7 +644,6 @@
EXPECT_EQ(inet_addr("192.0.2.1"), ip->ip4.s_addr);
free(ip);
- config_is_ipv4_address_free = orig_config_is_ipv4_address_free;
v4Iface.destroy();
}
@@ -986,6 +809,29 @@
ARRAYSIZE(kIPv6Fragments), "IPv6->IPv4 fragment translation");
}
+// picks a random interface ID that is checksum neutral with the IPv4 address and the NAT64 prefix
+void gen_random_iid(struct in6_addr *myaddr, struct in_addr *ipv4_local_subnet,
+ struct in6_addr *plat_subnet) {
+ // Fill last 8 bytes of IPv6 address with random bits.
+ arc4random_buf(&myaddr->s6_addr[8], 8);
+
+ // Make the IID checksum-neutral. That is, make it so that:
+ // checksum(Local IPv4 | Remote IPv4) = checksum(Local IPv6 | Remote IPv6)
+ // in other words (because remote IPv6 = NAT64 prefix | Remote IPv4):
+ // checksum(Local IPv4) = checksum(Local IPv6 | NAT64 prefix)
+ // Do this by adjusting the two bytes in the middle of the IID.
+
+ uint16_t middlebytes = (myaddr->s6_addr[11] << 8) + myaddr->s6_addr[12];
+
+ uint32_t c1 = ip_checksum_add(0, ipv4_local_subnet, sizeof(*ipv4_local_subnet));
+ uint32_t c2 = ip_checksum_add(0, plat_subnet, sizeof(*plat_subnet)) +
+ ip_checksum_add(0, myaddr, sizeof(*myaddr));
+
+ uint16_t delta = ip_checksum_adjust(middlebytes, c1, c2);
+ myaddr->s6_addr[11] = delta >> 8;
+ myaddr->s6_addr[12] = delta & 0xff;
+}
+
void check_translate_checksum_neutral(const uint8_t *original, size_t original_len,
size_t expected_len, const char *msg) {
uint8_t translated[MAXMTU];
@@ -1003,10 +849,12 @@
TEST_F(ClatdTest, TranslateChecksumNeutral) {
// Generate a random clat IPv6 address and check that translation is checksum-neutral.
- Global_Clatd_Config.ipv6_host_id = in6addr_any;
ASSERT_TRUE(inet_pton(AF_INET6, "2001:db8:1:2:f076:ae99:124e:aa54",
&Global_Clatd_Config.ipv6_local_subnet));
- config_generate_local_ipv6_subnet(&Global_Clatd_Config.ipv6_local_subnet);
+
+ gen_random_iid(&Global_Clatd_Config.ipv6_local_subnet, &Global_Clatd_Config.ipv4_local_subnet,
+ &Global_Clatd_Config.plat_subnet);
+
ASSERT_NE(htonl((uint32_t)0x00000464), Global_Clatd_Config.ipv6_local_subnet.s6_addr32[3]);
ASSERT_NE((uint32_t)0, Global_Clatd_Config.ipv6_local_subnet.s6_addr32[3]);
@@ -1079,7 +927,13 @@
.write_fd6 = socket(AF_INET6, SOCK_RAW | SOCK_NONBLOCK, IPPROTO_RAW),
};
const char *ifname = sTun.name().c_str();
- ASSERT_EQ(1, configure_clat_ipv6_address(&tunnel, ifname, nullptr));
+
+ in6_addr myaddr = sTun.srcAddr();
+ gen_random_iid(&myaddr, &Global_Clatd_Config.ipv4_local_subnet, &Global_Clatd_Config.plat_subnet);
+ char addrstr[INET6_ADDRSTRLEN];
+ ASSERT_NE(nullptr, inet_ntop(AF_INET6, &myaddr, addrstr, sizeof(addrstr)));
+
+ ASSERT_EQ(1, configure_clat_ipv6_address(&tunnel, ifname, addrstr));
EXPECT_EQ(0, ipv6_address_changed(ifname));
EXPECT_EQ(0, ipv6_address_changed(ifname));
diff --git a/config.c b/config.c
deleted file mode 100644
index 1c1a1f7..0000000
--- a/config.c
+++ /dev/null
@@ -1,387 +0,0 @@
-/*
- * Copyright 2011 Daniel Drown
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * config.c - configuration settings
- */
-
-#include <arpa/inet.h>
-#include <errno.h>
-#include <limits.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include <cutils/config_utils.h>
-#include <netutils/checksum.h>
-#include <netutils/ifc.h>
-
-#include "clatd.h"
-#include "config.h"
-#include "dns64.h"
-#include "getaddr.h"
-#include "logging.h"
-
-struct clat_config Global_Clatd_Config;
-
-/* function: config_item_str
- * locates the config item and returns the pointer to a string, or NULL on failure. Caller frees
- * pointer
- * root - parsed configuration
- * item_name - name of config item to locate
- * defaultvar - value to use if config item isn't present
- */
-char *config_item_str(cnode *root, const char *item_name, const char *defaultvar) {
- const char *tmp;
-
- if (!(tmp = config_str(root, item_name, defaultvar))) {
- logmsg(ANDROID_LOG_FATAL, "%s config item needed", item_name);
- return NULL;
- }
- return strdup(tmp);
-}
-
-/* function: config_item_int16_t
- * locates the config item, parses the integer, and returns the pointer ret_val_ptr, or NULL on
- * failure
- * root - parsed configuration
- * item_name - name of config item to locate
- * defaultvar - value to use if config item isn't present
- * ret_val_ptr - pointer for return value storage
- */
-int16_t *config_item_int16_t(cnode *root, const char *item_name, const char *defaultvar,
- int16_t *ret_val_ptr) {
- const char *tmp;
- char *endptr;
- long int conf_int;
-
- if (!(tmp = config_str(root, item_name, defaultvar))) {
- logmsg(ANDROID_LOG_FATAL, "%s config item needed", item_name);
- return NULL;
- }
-
- errno = 0;
- conf_int = strtol(tmp, &endptr, 10);
- if (errno > 0) {
- logmsg(ANDROID_LOG_FATAL, "%s config item is not numeric: %s (error=%s)", item_name, tmp,
- strerror(errno));
- return NULL;
- }
- if (endptr == tmp || *tmp == '\0') {
- logmsg(ANDROID_LOG_FATAL, "%s config item is not numeric: %s", item_name, tmp);
- return NULL;
- }
- if (*endptr != '\0') {
- logmsg(ANDROID_LOG_FATAL, "%s config item contains non-numeric characters: %s", item_name,
- endptr);
- return NULL;
- }
- if (conf_int > INT16_MAX || conf_int < INT16_MIN) {
- logmsg(ANDROID_LOG_FATAL, "%s config item is too big/small: %d", item_name, conf_int);
- return NULL;
- }
- *ret_val_ptr = conf_int;
- return ret_val_ptr;
-}
-
-/* function: config_item_ip
- * locates the config item, parses the ipv4 address, and returns the pointer ret_val_ptr, or NULL on
- * failure
- * root - parsed configuration
- * item_name - name of config item to locate
- * defaultvar - value to use if config item isn't present
- * ret_val_ptr - pointer for return value storage
- */
-struct in_addr *config_item_ip(cnode *root, const char *item_name, const char *defaultvar,
- struct in_addr *ret_val_ptr) {
- const char *tmp;
- int status;
-
- if (!(tmp = config_str(root, item_name, defaultvar))) {
- logmsg(ANDROID_LOG_FATAL, "%s config item needed", item_name);
- return NULL;
- }
-
- status = inet_pton(AF_INET, tmp, ret_val_ptr);
- if (status <= 0) {
- logmsg(ANDROID_LOG_FATAL, "invalid IPv4 address specified for %s: %s", item_name, tmp);
- return NULL;
- }
-
- return ret_val_ptr;
-}
-
-/* function: config_item_ip6
- * locates the config item, parses the ipv6 address, and returns the pointer ret_val_ptr, or NULL on
- * failure
- * root - parsed configuration
- * item_name - name of config item to locate
- * defaultvar - value to use if config item isn't present
- * ret_val_ptr - pointer for return value storage
- */
-struct in6_addr *config_item_ip6(cnode *root, const char *item_name, const char *defaultvar,
- struct in6_addr *ret_val_ptr) {
- const char *tmp;
- int status;
-
- if (!(tmp = config_str(root, item_name, defaultvar))) {
- logmsg(ANDROID_LOG_FATAL, "%s config item needed", item_name);
- return NULL;
- }
-
- status = inet_pton(AF_INET6, tmp, ret_val_ptr);
- if (status <= 0) {
- logmsg(ANDROID_LOG_FATAL, "invalid IPv6 address specified for %s: %s", item_name, tmp);
- return NULL;
- }
-
- return ret_val_ptr;
-}
-
-/* function: ipv6_prefix_equal
- * compares the prefixes two ipv6 addresses. assumes the prefix lengths are both /64.
- * a1 - first address
- * a2 - second address
- * returns: 0 if the subnets are different, 1 if they are the same.
- */
-int ipv6_prefix_equal(struct in6_addr *a1, struct in6_addr *a2) { return !memcmp(a1, a2, 8); }
-
-/* function: dns64_detection
- * does dns lookups to set the plat subnet or exits on failure, waits forever for a dns response
- * with a query backoff timer
- * net_id - (optional) netId to use, NETID_UNSET indicates use of default network
- */
-void dns64_detection(unsigned net_id) {
- int backoff_sleep, status;
- struct in6_addr tmp_ptr;
-
- backoff_sleep = 1;
-
- while (1) {
- status = plat_prefix(DNS64_DETECTION_HOSTNAME, net_id, &tmp_ptr);
- if (status > 0) {
- memcpy(&Global_Clatd_Config.plat_subnet, &tmp_ptr, sizeof(struct in6_addr));
- return;
- }
- logmsg(ANDROID_LOG_WARN, "dns64_detection -- error, sleeping for %d seconds", backoff_sleep);
- sleep(backoff_sleep);
- backoff_sleep *= 2;
- if (backoff_sleep >= 1800) {
- // Scale down to one DNS query per half hour. Unnecessary DNS queries waste power, and the
- // benefit is minimal (basically, only limited to the case where a network goes from IPv6-only
- // to IPv6 with NAT64).
- backoff_sleep = 1800;
- }
- }
-}
-
-/* function: gen_random_iid
- * picks a random interface ID that is checksum neutral with the IPv4 address and the NAT64 prefix
- * myaddr - IPv6 address to write to
- * ipv4_local_subnet - clat IPv4 address
- * plat_subnet - NAT64 prefix
- */
-void gen_random_iid(struct in6_addr *myaddr, struct in_addr *ipv4_local_subnet,
- struct in6_addr *plat_subnet) {
- // Fill last 8 bytes of IPv6 address with random bits.
- arc4random_buf(&myaddr->s6_addr[8], 8);
-
- // Make the IID checksum-neutral. That is, make it so that:
- // checksum(Local IPv4 | Remote IPv4) = checksum(Local IPv6 | Remote IPv6)
- // in other words (because remote IPv6 = NAT64 prefix | Remote IPv4):
- // checksum(Local IPv4) = checksum(Local IPv6 | NAT64 prefix)
- // Do this by adjusting the two bytes in the middle of the IID.
-
- uint16_t middlebytes = (myaddr->s6_addr[11] << 8) + myaddr->s6_addr[12];
-
- uint32_t c1 = ip_checksum_add(0, ipv4_local_subnet, sizeof(*ipv4_local_subnet));
- uint32_t c2 = ip_checksum_add(0, plat_subnet, sizeof(*plat_subnet)) +
- ip_checksum_add(0, myaddr, sizeof(*myaddr));
-
- uint16_t delta = ip_checksum_adjust(middlebytes, c1, c2);
- myaddr->s6_addr[11] = delta >> 8;
- myaddr->s6_addr[12] = delta & 0xff;
-}
-
-// Factored out to a separate function for testability.
-int connect_is_ipv4_address_free(in_addr_t addr) {
- int s = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
- if (s == -1) {
- return 0;
- }
-
- // Attempt to connect to the address. If the connection succeeds and getsockname returns the same
- // the address then the address is already assigned to the system and we can't use it.
- struct sockaddr_in sin = { .sin_family = AF_INET, .sin_addr = { addr }, .sin_port = htons(53) };
- socklen_t len = sizeof(sin);
- int inuse = connect(s, (struct sockaddr *)&sin, sizeof(sin)) == 0 &&
- getsockname(s, (struct sockaddr *)&sin, &len) == 0 && (size_t)len >= sizeof(sin) &&
- sin.sin_addr.s_addr == addr;
-
- close(s);
- return !inuse;
-}
-
-addr_free_func config_is_ipv4_address_free = connect_is_ipv4_address_free;
-
-/* function: config_select_ipv4_address
- * picks a free IPv4 address, starting from ip and trying all addresses in the prefix in order
- * ip - the IP address from the configuration file
- * prefixlen - the length of the prefix from which addresses may be selected.
- * returns: the IPv4 address, or INADDR_NONE if no addresses were available
- */
-in_addr_t config_select_ipv4_address(const struct in_addr *ip, int16_t prefixlen) {
- in_addr_t chosen = INADDR_NONE;
-
- // Don't accept prefixes that are too large because we scan addresses one by one.
- if (prefixlen < 16 || prefixlen > 32) {
- return chosen;
- }
-
- // All these are in host byte order.
- in_addr_t mask = 0xffffffff >> (32 - prefixlen) << (32 - prefixlen);
- in_addr_t ipv4 = ntohl(ip->s_addr);
- in_addr_t first_ipv4 = ipv4;
- in_addr_t prefix = ipv4 & mask;
-
- // Pick the first IPv4 address in the pool, wrapping around if necessary.
- // So, for example, 192.0.0.4 -> 192.0.0.5 -> 192.0.0.6 -> 192.0.0.7 -> 192.0.0.0.
- do {
- if (config_is_ipv4_address_free(htonl(ipv4))) {
- chosen = htonl(ipv4);
- break;
- }
- ipv4 = prefix | ((ipv4 + 1) & ~mask);
- } while (ipv4 != first_ipv4);
-
- return chosen;
-}
-
-/* function: config_generate_local_ipv6_subnet
- * generates the local ipv6 subnet when given the interface ip requires config.ipv6_host_id
- * interface_ip - in: interface ip, out: local ipv6 host address
- */
-void config_generate_local_ipv6_subnet(struct in6_addr *interface_ip) {
- int i;
-
- if (Global_Clatd_Config.use_dynamic_iid) {
- /* Generate a random interface ID. */
- gen_random_iid(interface_ip, &Global_Clatd_Config.ipv4_local_subnet,
- &Global_Clatd_Config.plat_subnet);
- } else {
- /* Use the specified interface ID. */
- for (i = 2; i < 4; i++) {
- interface_ip->s6_addr32[i] = Global_Clatd_Config.ipv6_host_id.s6_addr32[i];
- }
- }
-}
-
-/* function: read_config
- * reads the config file and parses it into the global variable Global_Clatd_Config. returns 0 on
- * failure, 1 on success
- * file - filename to parse
- * uplink_interface - interface to use to reach the internet and supplier of address space
- * plat_prefix - (optional) plat prefix to use, otherwise follow config file
- * net_id - (optional) netId to use, NETID_UNSET indicates use of default network
- */
-int read_config(const char *file, const char *uplink_interface, const char *plat_prefix,
- unsigned net_id) {
- cnode *root = config_node("", "");
- void *tmp_ptr = NULL;
- unsigned flags;
-
- if (!root) {
- logmsg(ANDROID_LOG_FATAL, "out of memory");
- return 0;
- }
-
- memset(&Global_Clatd_Config, '\0', sizeof(Global_Clatd_Config));
-
- config_load_file(root, file);
- if (root->first_child == NULL) {
- logmsg(ANDROID_LOG_FATAL, "Could not read config file %s", file);
- goto failed;
- }
-
- Global_Clatd_Config.default_pdp_interface = strdup(uplink_interface);
- if (!Global_Clatd_Config.default_pdp_interface) goto failed;
-
- if (!config_item_ip(root, "ipv4_local_subnet", DEFAULT_IPV4_LOCAL_SUBNET,
- &Global_Clatd_Config.ipv4_local_subnet))
- goto failed;
-
- if (!config_item_int16_t(root, "ipv4_local_prefixlen", DEFAULT_IPV4_LOCAL_PREFIXLEN,
- &Global_Clatd_Config.ipv4_local_prefixlen))
- goto failed;
-
- if (plat_prefix) { // plat subnet is coming from the command line
- if (inet_pton(AF_INET6, plat_prefix, &Global_Clatd_Config.plat_subnet) <= 0) {
- logmsg(ANDROID_LOG_FATAL, "invalid IPv6 address specified for plat prefix: %s", plat_prefix);
- goto failed;
- }
- } else {
- tmp_ptr = (void *)config_item_str(root, "plat_from_dns64", "yes");
- if (!tmp_ptr || strcmp(tmp_ptr, "no") == 0) {
- free(tmp_ptr);
-
- if (!config_item_ip6(root, "plat_subnet", NULL, &Global_Clatd_Config.plat_subnet)) {
- logmsg(ANDROID_LOG_FATAL, "plat_from_dns64 disabled, but no plat_subnet specified");
- goto failed;
- }
- } else {
- free(tmp_ptr);
-
- dns64_detection(net_id);
- }
- }
-
- if (!config_item_ip6(root, "ipv6_host_id", "::", &Global_Clatd_Config.ipv6_host_id)) goto failed;
-
- /* In order to prevent multiple devices attempting to use the same clat address, never use a
- statically-configured interface ID on a broadcast interface such as wifi. */
- if (!IN6_IS_ADDR_UNSPECIFIED(&Global_Clatd_Config.ipv6_host_id)) {
- ifc_init();
- ifc_get_info(Global_Clatd_Config.default_pdp_interface, NULL, NULL, &flags);
- ifc_close();
- Global_Clatd_Config.use_dynamic_iid = (flags & IFF_BROADCAST) != 0;
- } else {
- Global_Clatd_Config.use_dynamic_iid = 1;
- }
-
- return 1;
-
-failed:
- free(root);
- return 0;
-}
-
-/* function; dump_config
- * prints the current config
- */
-void dump_config() {
- char charbuffer[INET6_ADDRSTRLEN];
-
- logmsg(
- ANDROID_LOG_DEBUG, "ipv6_local_subnet = %s",
- inet_ntop(AF_INET6, &Global_Clatd_Config.ipv6_local_subnet, charbuffer, sizeof(charbuffer)));
- logmsg(
- ANDROID_LOG_DEBUG, "ipv4_local_subnet = %s",
- inet_ntop(AF_INET, &Global_Clatd_Config.ipv4_local_subnet, charbuffer, sizeof(charbuffer)));
- logmsg(ANDROID_LOG_DEBUG, "ipv4_local_prefixlen = %d", Global_Clatd_Config.ipv4_local_prefixlen);
- logmsg(ANDROID_LOG_DEBUG, "plat_subnet = %s",
- inet_ntop(AF_INET6, &Global_Clatd_Config.plat_subnet, charbuffer, sizeof(charbuffer)));
- logmsg(ANDROID_LOG_DEBUG, "default_pdp_interface = %s",
- Global_Clatd_Config.default_pdp_interface);
-}
diff --git a/config.h b/config.h
index d5c4399..1ba6850 100644
--- a/config.h
+++ b/config.h
@@ -21,28 +21,31 @@
#include <linux/if.h>
#include <netinet/in.h>
-#define DEFAULT_IPV4_LOCAL_SUBNET "192.0.0.4"
-#define DEFAULT_IPV4_LOCAL_PREFIXLEN "29"
-#define DNS64_DETECTION_HOSTNAME "ipv4only.arpa"
+#include "ring.h"
+
+struct tun_data {
+ char device4[IFNAMSIZ];
+ int read_fd6, write_fd6, fd4;
+ struct packet_ring ring;
+};
struct clat_config {
struct in6_addr ipv6_local_subnet;
- struct in6_addr ipv6_host_id;
struct in_addr ipv4_local_subnet;
- int16_t ipv4_local_prefixlen;
struct in6_addr plat_subnet;
- char *default_pdp_interface;
- int use_dynamic_iid;
+ const char *native_ipv6_interface;
};
extern struct clat_config Global_Clatd_Config;
-int read_config(const char *file, const char *uplink_interface, const char *plat_prefix,
- unsigned net_id);
-void config_generate_local_ipv6_subnet(struct in6_addr *interface_ip);
-in_addr_t config_select_ipv4_address(const struct in_addr *ip, int16_t prefixlen);
-int ipv6_prefix_equal(struct in6_addr *a1, struct in6_addr *a2);
-
-typedef int (*addr_free_func)(in_addr_t addr);
+/* function: ipv6_prefix_equal
+ * compares the /64 prefixes of two ipv6 addresses.
+ * a1 - first address
+ * a2 - second address
+ * returns: 0 if the subnets are different, 1 if they are the same.
+ */
+static inline int ipv6_prefix_equal(struct in6_addr *a1, struct in6_addr *a2) {
+ return !memcmp(a1, a2, 8);
+}
#endif /* __CONFIG_H__ */
diff --git a/dns64.c b/dns64.c
deleted file mode 100644
index 66cb7dc..0000000
--- a/dns64.c
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright 2011 Daniel Drown
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * dns64.c - find the nat64 prefix with a dns64 lookup
- */
-
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <netinet/in.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <strings.h>
-#include <sys/socket.h>
-#include <unistd.h>
-
-#include <DnsProxydProtocol.h> // NETID_USE_LOCAL_NAMESERVERS
-#include "dns64.h"
-#include "logging.h"
-#include "resolv_netid.h"
-
-/* function: plat_prefix
- * looks up an ipv4-only hostname and looks for a nat64 /96 prefix, returns 1 on success, 0 on
- * failure
- * ipv4_name - name to lookup
- * net_id - (optional) netId to use, NETID_UNSET indicates use of default network
- * prefix - the plat /96 prefix
- */
-int plat_prefix(const char *ipv4_name, unsigned net_id, struct in6_addr *prefix) {
- const struct addrinfo hints = {
- .ai_family = AF_INET6,
- };
- int status;
- struct addrinfo *result = NULL;
- struct in6_addr plat_addr;
- char plat_addr_str[INET6_ADDRSTRLEN];
-
- logmsg(ANDROID_LOG_INFO, "Detecting NAT64 prefix from DNS...");
-
- // Be sure to query local DNS64 servers, bypassing Private DNS (if enabled).
- if (net_id != NETID_UNSET) {
- net_id |= NETID_USE_LOCAL_NAMESERVERS;
- }
-
- status = android_getaddrinfofornet(ipv4_name, NULL, &hints, net_id, MARK_UNSET, &result);
- if (status != 0 || result == NULL) {
- logmsg(ANDROID_LOG_ERROR, "plat_prefix/dns(%s) status = %d/%s", ipv4_name, status,
- gai_strerror(status));
- return 0;
- }
-
- // Use only the first result. If other records are present, possibly with
- // differing DNS64 prefixes they are ignored (there is very little sensible
- // that could be done with them at this time anyway).
-
- if (result->ai_family != AF_INET6) {
- logmsg(ANDROID_LOG_WARN, "plat_prefix/unexpected address family: %d", result->ai_family);
- return 0;
- }
- plat_addr = ((struct sockaddr_in6 *)result->ai_addr)->sin6_addr;
- // Only /96 DNS64 prefixes are supported at this time.
- plat_addr.s6_addr32[3] = 0;
- freeaddrinfo(result);
-
- logmsg(ANDROID_LOG_INFO, "Detected NAT64 prefix %s/96",
- inet_ntop(AF_INET6, &plat_addr, plat_addr_str, sizeof(plat_addr_str)));
- *prefix = plat_addr;
- return 1;
-}
diff --git a/dns64.h b/dns64.h
deleted file mode 100644
index f5eaea8..0000000
--- a/dns64.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright 2011 Daniel Drown
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * dns64.h - find the nat64 prefix with a dns64 lookup
- */
-#ifndef __DNS64_H__
-#define __DNS64_H__
-
-int plat_prefix(const char *ipv4_name, unsigned net_id, struct in6_addr *prefix);
-
-#endif
diff --git a/main.c b/main.c
index e973bf3..683b507 100644
--- a/main.c
+++ b/main.c
@@ -16,6 +16,7 @@
* main.c - main function
*/
+#include <arpa/inet.h>
#include <errno.h>
#include <netinet/in.h>
#include <stdint.h>
@@ -24,14 +25,13 @@
#include <sys/capability.h>
#include <unistd.h>
-#include "resolv_netid.h"
+#include <netid_client.h> // For MARK_UNSET.
#include "clatd.h"
#include "common.h"
#include "config.h"
#include "logging.h"
#include "setif.h"
-#include "tun.h"
#define DEVICEPREFIX "v4-"
@@ -44,7 +44,6 @@
printf("-p [plat prefix]\n");
printf("-4 [IPv4 address]\n");
printf("-6 [IPv6 address]\n");
- printf("-n [NetId]\n");
printf("-m [socket mark]\n");
printf("-t [tun file descriptor number]\n");
}
@@ -55,13 +54,12 @@
int main(int argc, char **argv) {
struct tun_data tunnel;
int opt;
- char *uplink_interface = NULL, *plat_prefix = NULL, *net_id_str = NULL, *mark_str = NULL;
+ char *uplink_interface = NULL, *plat_prefix = NULL, *mark_str = NULL;
char *v4_addr = NULL, *v6_addr = NULL, *tunfd_str = NULL;
- unsigned net_id = NETID_UNSET;
uint32_t mark = MARK_UNSET;
unsigned len;
- while ((opt = getopt(argc, argv, "i:p:4:6:n:m:t:h")) != -1) {
+ while ((opt = getopt(argc, argv, "i:p:4:6:m:t:h")) != -1) {
switch (opt) {
case 'i':
uplink_interface = optarg;
@@ -75,9 +73,6 @@
case '6':
v6_addr = optarg;
break;
- case 'n':
- net_id_str = optarg;
- break;
case 'm':
mark_str = optarg;
break;
@@ -98,11 +93,6 @@
exit(1);
}
- if (net_id_str != NULL && !parse_unsigned(net_id_str, &net_id)) {
- logmsg(ANDROID_LOG_FATAL, "invalid NetID %s", net_id_str);
- exit(1);
- }
-
if (mark_str != NULL && !parse_unsigned(mark_str, &mark)) {
logmsg(ANDROID_LOG_FATAL, "invalid mark %s", mark_str);
exit(1);
@@ -123,10 +113,10 @@
exit(1);
}
- logmsg(ANDROID_LOG_INFO, "Starting clat version %s on %s netid=%s mark=%s plat=%s v4=%s v6=%s",
- CLATD_VERSION, uplink_interface, net_id_str ? net_id_str : "(none)",
- mark_str ? mark_str : "(none)", plat_prefix ? plat_prefix : "(none)",
- v4_addr ? v4_addr : "(none)", v6_addr ? v6_addr : "(none)");
+ logmsg(ANDROID_LOG_INFO, "Starting clat version %s on %s mark=%s plat=%s v4=%s v6=%s",
+ CLATD_VERSION, uplink_interface, mark_str ? mark_str : "(none)",
+ plat_prefix ? plat_prefix : "(none)", v4_addr ? v4_addr : "(none)",
+ v6_addr ? v6_addr : "(none)");
// run under a regular user but keep needed capabilities
drop_root_but_keep_caps();
@@ -137,12 +127,7 @@
// keeps only admin capability
set_capability(1 << CAP_NET_ADMIN);
- // When run from netd, the environment variable ANDROID_DNS_MODE is set to
- // "local", but that only works for the netd process itself. Removing the
- // following line causes XLAT failure in permissive mode.
- unsetenv("ANDROID_DNS_MODE");
-
- configure_interface(uplink_interface, plat_prefix, v4_addr, v6_addr, &tunnel, net_id, mark);
+ configure_interface(uplink_interface, plat_prefix, v4_addr, v6_addr, &tunnel, mark);
// Drop all remaining capabilities.
set_capability(0);
diff --git a/ring.c b/ring.c
index 96a50ca..7626c6d 100644
--- a/ring.c
+++ b/ring.c
@@ -24,10 +24,10 @@
#include <sys/mman.h>
#include <sys/socket.h>
+#include "config.h"
#include "logging.h"
#include "ring.h"
#include "translate.h"
-#include "tun.h"
int ring_create(struct tun_data *tunnel) {
// Will eventually be bound to htons(ETH_P_IPV6) protocol,
diff --git a/translate.c b/translate.c
index 1632753..728acc3 100644
--- a/translate.c
+++ b/translate.c
@@ -26,7 +26,6 @@
#include "icmp.h"
#include "logging.h"
#include "translate.h"
-#include "tun.h"
/* function: packet_checksum
* calculates the checksum over all the packet components starting from pos
@@ -524,7 +523,7 @@
if (iov_len > 0) {
fill_tun_header(&tun_targ, ETH_P_IP);
out[CLAT_POS_TUNHDR].iov_len = sizeof(tun_targ);
- send_tun(fd, out, iov_len);
+ writev(fd, out, iov_len);
}
}
}
diff --git a/tun.h b/tun.h
deleted file mode 100644
index eaeebc6..0000000
--- a/tun.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * tun.h - tun device functions
- */
-#ifndef __TUN_H__
-#define __TUN_H__
-
-#include <fcntl.h>
-#include <linux/if.h>
-#include <sys/uio.h>
-#include <unistd.h>
-
-#include "common.h"
-#include "ring.h"
-
-struct tun_data {
- char device4[IFNAMSIZ];
- int read_fd6, write_fd6, fd4;
- struct packet_ring ring;
-};
-
-/* function: send_tun
- * sends a clat_packet to a tun interface
- * fd - the tun filedescriptor
- * out - the packet to send
- * iov_len - the number of entries in the clat_packet
- * returns: number of bytes read on success, -1 on failure
- */
-static inline int send_tun(int fd, clat_packet out, int iov_len) {
- return writev(fd, out, iov_len);
-}
-
-#endif