Exemple #1
0
char *get_lan_addr6_prefix(char *p_addr6s)
{
	/* force prefix len to 64 for SLAAC */
	struct in6_addr addr6;

	char *lan_addr6 = nvram_safe_get("lan_addr6");
	if (*lan_addr6) {
		if (ipv6_from_string(lan_addr6, &addr6) >= 0) {
			ipv6_to_net(&addr6, 64);
			if (inet_ntop(AF_INET6, &addr6, p_addr6s, INET6_ADDRSTRLEN) != NULL) {
				sprintf(p_addr6s, "%s/%d", p_addr6s, 64);
				return p_addr6s;
			}
		}
	}

	return NULL;
}
Exemple #2
0
void start_sit_tunnel(int ipv6_type, char *wan_addr4, char *wan_addr6)
{
	int sit_ttl, sit_mtu, size4, size6;
	char *sit_remote, *sit_relay, *wan_gate6;
	char addr6s[INET6_ADDRSTRLEN];
	struct in_addr addr4;
	struct in6_addr addr6;

	size4 = 0;
	addr4.s_addr = inet_addr_(wan_addr4);
	if (addr4.s_addr == INADDR_ANY)
		return; // cannot start SIT tunnel w/o IPv4 WAN addr

	sit_mtu = nvram_get_int("ip6_sit_mtu");
	sit_ttl = nvram_get_int("ip6_sit_ttl");
	if (sit_mtu < 1280) sit_mtu = 1280;
	if (sit_ttl < 1) sit_ttl = 1;
	if (sit_ttl > 255) sit_ttl = 255;

	memset(&addr6, 0, sizeof(addr6));
	size6 = ipv6_from_string(wan_addr6, &addr6);
	if (size6 < 0) size6 = 0;

	sit_relay = "";
	sit_remote = "any";
	if (ipv6_type == IPV6_6IN4)
		sit_remote = nvram_safe_get("ip6_6in4_remote");
	
	if (is_interface_exist(IFNAME_SIT))
		doSystem("ip tunnel del %s", IFNAME_SIT);
	
	doSystem("ip tunnel %s %s mode sit remote %s local %s ttl %d", "add", IFNAME_SIT, sit_remote, wan_addr4, sit_ttl);
	
	if (ipv6_type == IPV6_6TO4) {
		size6 = 16;
		memset(&addr6, 0, sizeof(addr6));
		addr6.s6_addr16[0] = htons(0x2002);
		ipv6_to_ipv4_map(&addr6, size6, &addr4, 0);
		addr6.s6_addr16[7] = htons(0x0001);
		sit_relay = nvram_safe_get("ip6_6to4_relay");
	}
	else if (ipv6_type == IPV6_6RD) {
		struct in_addr net4;
		struct in6_addr net6;
		char sit_6rd_prefix[INET6_ADDRSTRLEN], sit_6rd_relay_prefix[32];
		
		memcpy(&net6, &addr6, sizeof(addr6));
		ipv6_to_net(&net6, size6);
		inet_ntop(AF_INET6, &net6, sit_6rd_prefix, INET6_ADDRSTRLEN);
		sprintf(sit_6rd_prefix, "%s/%d", sit_6rd_prefix, size6);
		
		strcpy(sit_6rd_relay_prefix, "0.0.0.0/0");
		size4 = nvram_get_int("wan0_6rd_size");
		if (size4 > 0 && size4 <= 32)
		{
			net4.s_addr = addr4.s_addr & htonl(0xffffffffUL << (32 - size4));
			sprintf(sit_6rd_relay_prefix, "%s/%d", inet_ntoa(net4), size4);
		}
		
		doSystem("ip tunnel 6rd dev %s 6rd-prefix %s 6rd-relay_prefix %s", IFNAME_SIT, sit_6rd_prefix, sit_6rd_relay_prefix);
		
		ipv6_to_ipv4_map(&addr6, size6, &addr4, size4);
		addr6.s6_addr16[7] = htons(0x0001);
		sit_relay = nvram_safe_get("wan0_6rd_relay");
	}

	// WAN IPv6 address
	inet_ntop(AF_INET6, &addr6, addr6s, INET6_ADDRSTRLEN);
	if (size6 > 0)
		sprintf(addr6s, "%s/%d", addr6s, size6);

	control_if_ipv6_radv(IFNAME_SIT, 0);
	doSystem("ip link set mtu %d dev %s up", sit_mtu, IFNAME_SIT);
	control_if_ipv6(IFNAME_SIT, 1);
	clear_if_addr6(IFNAME_SIT);
	doSystem("ip -6 addr add %s dev %s", addr6s, IFNAME_SIT);

	/* WAN IPv6 gateway (auto-generate for 6to4/6rd) */
	if (ipv6_type == IPV6_6TO4 || ipv6_type == IPV6_6RD) {
		sprintf(addr6s, "::%s", sit_relay);
		wan_gate6 = addr6s;
		/* add direct default gateway for workaround "No route to host" on new kernel */
		doSystem("ip -6 route add default dev %s metric %d", IFNAME_SIT, 2048);
	}
	else {
		wan_gate6 = nvram_safe_get("wan0_gate6");
	}
	if (*wan_gate6)
		doSystem("ip -6 route add default via %s dev %s metric %d", wan_gate6, IFNAME_SIT, 1);

	/* LAN IPv6 address (auto-generate for 6to4/6rd) */
	if (ipv6_type == IPV6_6TO4 || ipv6_type == IPV6_6RD) {
		memset(&addr6, 0, sizeof(addr6));
		if (ipv6_type == IPV6_6TO4) {
			addr6.s6_addr16[0] = htons(0x2002);
			ipv6_to_ipv4_map(&addr6, 16, &addr4, 0);
			addr6.s6_addr16[3] = htons(0x0001);
			addr6.s6_addr16[7] = htons(0x0001);
		}
		else {
			ipv6_from_string(wan_addr6, &addr6);
			ipv6_to_ipv4_map(&addr6, size6, &addr4, size4);
			addr6.s6_addr16[7] = htons(0x0001);
		}
		
		inet_ntop(AF_INET6, &addr6, addr6s, INET6_ADDRSTRLEN);
		sprintf(addr6s, "%s/%d", addr6s, 64);
		
		clear_if_addr6(IFNAME_BR);
		doSystem("ip -6 addr add %s dev %s", addr6s, IFNAME_BR);
		
		store_lan_addr6(addr6s);
	}
}