/* function: interface_poll * polls the uplink network interface for address changes * tunnel - tun device data */ void interface_poll(const struct tun_data *tunnel) { union anyip *interface_ip; interface_ip = getinterface_ip(Global_Clatd_Config.default_pdp_interface, AF_INET6); if(!interface_ip) { logmsg(ANDROID_LOG_WARN,"unable to find an ipv6 ip on interface %s",Global_Clatd_Config.default_pdp_interface); return; } config_generate_local_ipv6_subnet(&interface_ip->ip6); if(!IN6_ARE_ADDR_EQUAL(&interface_ip->ip6, &Global_Clatd_Config.ipv6_local_subnet)) { char from_addr[INET6_ADDRSTRLEN], to_addr[INET6_ADDRSTRLEN]; inet_ntop(AF_INET6, &Global_Clatd_Config.ipv6_local_subnet, from_addr, sizeof(from_addr)); inet_ntop(AF_INET6, &interface_ip->ip6, to_addr, sizeof(to_addr)); logmsg(ANDROID_LOG_WARN, "clat subnet changed from %s to %s", from_addr, to_addr); // remove old route deconfigure_tun_ipv6(tunnel); // add new route, start translating packets to the new prefix memcpy(&Global_Clatd_Config.ipv6_local_subnet, &interface_ip->ip6, sizeof(struct in6_addr)); configure_tun_ipv6(tunnel); } free(interface_ip); }
/* function: subnet_from_interface * finds the ipv6 subnet configured on the specified interface * root - parsed configuration * interface - network interface name */ int subnet_from_interface(cnode *root, const char *interface) { union anyip *interface_ip; if(!config_item_ip6(root, "ipv6_host_id", "::200:5E10:0:0", &Global_Clatd_Config.ipv6_host_id)) return 0; interface_ip = getinterface_ip(interface, AF_INET6); if(!interface_ip) { logmsg(ANDROID_LOG_FATAL,"unable to find an ipv6 ip on interface %s",interface); return 0; } memcpy(&Global_Clatd_Config.ipv6_local_subnet, &interface_ip->ip6, sizeof(struct in6_addr)); free(interface_ip); config_generate_local_ipv6_subnet(&Global_Clatd_Config.ipv6_local_subnet); return 1; }
/* function: subnet_from_interface * finds the ipv6 subnet configured on the specified interface * root - parsed configuration * interface - network interface name */ int subnet_from_interface(cnode *root, const char *interface) { union anyip *interface_ip; char prop_name[PROPERTY_KEY_MAX]; char prop_value[PROPERTY_VALUE_MAX]; int cnt = 10; if(!config_item_ip6(root, "ipv6_host_id", "::200:5E10:0:0", &Global_Clatd_Config.ipv6_host_id)) return 0; logmsg(ANDROID_LOG_INFO, "before get net.ipv6.prefix"); snprintf(prop_name, sizeof(prop_name), "net.ipv6.%s.prefix", interface); while(cnt-->0) { property_get(prop_name, prop_value, NULL); if (strcmp(prop_value, "")) { break; } sleep(1); } logmsg(ANDROID_LOG_INFO, "after get net.ipv6.prefix"); interface_ip = getinterface_ip(interface, AF_INET6); if(!interface_ip) { logmsg(ANDROID_LOG_FATAL,"unable to find an ipv6 ip on interface %s",interface); return 0; } memcpy(&Global_Clatd_Config.ipv6_local_subnet, &interface_ip->ip6, sizeof(struct in6_addr)); free(interface_ip); config_generate_local_ipv6_subnet(&Global_Clatd_Config.ipv6_local_subnet); return 1; }