diff options
-rw-r--r-- | Android.mk | 2 | ||||
-rw-r--r-- | clatd_test.cpp | 6 | ||||
-rw-r--r-- | config.c | 15 | ||||
-rw-r--r-- | config.h | 1 |
4 files changed, 22 insertions, 2 deletions
@@ -6,7 +6,7 @@ LOCAL_SRC_FILES:=clatd.c dump.c checksum.c translate.c icmp.c ipv4.c ipv6.c conf LOCAL_CFLAGS := -Wall -Werror -Wunused-parameter LOCAL_C_INCLUDES := external/libnl/include bionic/libc/dns/include LOCAL_STATIC_LIBRARIES := libnl -LOCAL_SHARED_LIBRARIES := libcutils liblog +LOCAL_SHARED_LIBRARIES := libcutils liblog libnetutils # The clat daemon. LOCAL_MODULE := clatd diff --git a/clatd_test.cpp b/clatd_test.cpp index 085a9b7..fe52c21 100644 --- a/clatd_test.cpp +++ b/clatd_test.cpp @@ -565,6 +565,7 @@ class ClatdTest : public ::testing::Test { inet_pton(AF_INET6, kIPv6PlatSubnet, &Global_Clatd_Config.plat_subnet); inet_pton(AF_INET6, kIPv6LocalAddr, &Global_Clatd_Config.ipv6_local_subnet); Global_Clatd_Config.ipv6_host_id = in6addr_any; + Global_Clatd_Config.use_dynamic_iid = 1; } }; @@ -621,11 +622,16 @@ TEST_F(ClatdTest, TestCountOnebits) { 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) { @@ -25,6 +25,7 @@ #include <unistd.h> #include <cutils/config_utils.h> +#include <netutils/ifc.h> #include "config.h" #include "dns64.h" @@ -276,7 +277,7 @@ in_addr_t config_select_ipv4_address(const struct in_addr *ip, int16_t prefixlen void config_generate_local_ipv6_subnet(struct in6_addr *interface_ip) { int i; - if (IN6_IS_ADDR_UNSPECIFIED(&Global_Clatd_Config.ipv6_host_id)) { + if (Global_Clatd_Config.use_dynamic_iid) { /* Generate a random interface ID. */ gen_random_iid(interface_ip, &Global_Clatd_Config.ipv4_local_subnet, @@ -300,6 +301,7 @@ int read_config(const char *file, const char *uplink_interface, const char *plat unsigned net_id) { cnode *root = config_node("", ""); void *tmp_ptr = NULL; + unsigned flags; if(!root) { logmsg(ANDROID_LOG_FATAL,"out of memory"); @@ -358,6 +360,17 @@ int read_config(const char *file, const char *uplink_interface, const char *plat 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: @@ -33,6 +33,7 @@ struct clat_config { struct in6_addr plat_subnet; char *default_pdp_interface; char *plat_from_dns64_hostname; + int use_dynamic_iid; }; extern struct clat_config Global_Clatd_Config; |