Beispiel #1
0
bool IsBehindIPv4Nat()
{

	ULONG len = 0;
	int ret = GetAdaptersAddresses(AF_INET, GAA_FLAG_SKIP_MULTICAST|GAA_FLAG_SKIP_DNS_SERVER|GAA_FLAG_SKIP_FRIENDLY_NAME, 0, 0, &len);
	if (ret != ERROR_BUFFER_OVERFLOW) {
		return false;
	}

	bool has_ipv4 = false;
	bool has_public_ipv4 = false;

	auto buf = std::unique_ptr<char[]>(new char[len]);
	IP_ADAPTER_ADDRESSES *addrs = reinterpret_cast<IP_ADAPTER_ADDRESSES*>(buf.get());
	ret = GetAdaptersAddresses(AF_INET, GAA_FLAG_SKIP_MULTICAST|GAA_FLAG_SKIP_DNS_SERVER|GAA_FLAG_SKIP_FRIENDLY_NAME, 0, addrs, &len);
	if (ret == ERROR_SUCCESS) {
		for (auto addr = addrs; addr; addr = addr->Next) {
			for (auto ip = addr->FirstUnicastAddress; ip; ip = ip->Next) {
				if (ip->Flags & IP_ADAPTER_ADDRESS_TRANSIENT) {
					continue;
				}

				if (ip->Address.lpSockaddr && ip->Address.lpSockaddr->sa_family == AF_INET) {
					has_ipv4 = true;

					CStdString ipStr = inet_ntoa(reinterpret_cast<SOCKADDR_IN*>(ip->Address.lpSockaddr)->sin_addr);
					if (!ipStr.IsEmpty()) {
						has_public_ipv4 = has_public_ipv4 || IsRoutableAddress(ipStr);
					}
				}
			}
		}
	}

	return has_ipv4 && !has_public_ipv4;
}
Beispiel #2
0
bool IsRoutableAddress(const wxString& address, CSocket::address_family family)
{
	if (family == CSocket::ipv6)
	{
		wxString long_address = GetIPV6LongForm(address);
		if (long_address.size() != 39)
			return false;
		if (long_address[0] == '0')
		{
			// ::/128
			if (long_address == _T("0000:0000:0000:0000:0000:0000:0000:0000"))
				return false;
			// ::1/128
			if (long_address == _T("0000:0000:0000:0000:0000:0000:0000:0001"))
				return false;

			if (long_address.Left(30) == _T("0000:0000:0000:0000:0000:ffff:"))
			{
				// IPv4 mapped
				wxString ipv4 = wxString::Format(_T("%d.%d.%d.%d"),
						DigitHexToDecNum(long_address[30]) * 16 + DigitHexToDecNum(long_address[31]),
						DigitHexToDecNum(long_address[32]) * 16 + DigitHexToDecNum(long_address[33]),
						DigitHexToDecNum(long_address[35]) * 16 + DigitHexToDecNum(long_address[36]),
						DigitHexToDecNum(long_address[37]) * 16 + DigitHexToDecNum(long_address[38]));
				return IsRoutableAddress(ipv4, CSocket::ipv4);
			}

			return true;
		}
		if (long_address[0] == 'f')
		{
			if (long_address[1] == 'e')
			{
				// fe80::/10 (link local)
				const wxChar& c = long_address[2];
				int v;
				if (c >= 'a')
					v = c - 'a' + 10;
				else
					v = c - '0';
				if ((v & 0xc) == 0x8)
					return false;

				return true;
			}
			else if (long_address[1] == 'c' || long_address[1] == 'd')
			{
				// fc00::/7 (site local)
				return false;
			}
		}

		return true;
	}
	else
	{
		// Assumes address is already a valid IP address
		if (address.Left(3) == _T("127") ||
			address.Left(3) == _T("10.") ||
			address.Left(7) == _T("192.168") ||
			address.Left(7) == _T("169.254"))
			return false;

		if (address.Left(3) == _T("172"))
		{
			wxString middle = address.Mid(4);
			int pos = address.Find(_T("."));
			wxASSERT(pos != -1);
			long part;
			middle.Left(pos).ToLong(&part);

			if (part >= 16 && part <= 31)
				return false;
		}

		return true;
	}
}
Beispiel #3
0
void CIPAddressTest::testIsRoutableAddress4()
{
	// 127.0.0.0/8
	CPPUNIT_ASSERT(IsRoutableAddress(_T("126.255.255.255"), CSocket::ipv4));
	CPPUNIT_ASSERT(!IsRoutableAddress(_T("127.0.0.0"), CSocket::ipv4));
	CPPUNIT_ASSERT(!IsRoutableAddress(_T("127.255.255.255"), CSocket::ipv4));
	CPPUNIT_ASSERT(IsRoutableAddress(_T("128.0.0.0"), CSocket::ipv4));

	// 10.0.0.0/8
	CPPUNIT_ASSERT(IsRoutableAddress(_T("9.255.255.255"), CSocket::ipv4));
	CPPUNIT_ASSERT(!IsRoutableAddress(_T("10.0.0.0"), CSocket::ipv4));
	CPPUNIT_ASSERT(!IsRoutableAddress(_T("10.255.255.255"), CSocket::ipv4));
	CPPUNIT_ASSERT(IsRoutableAddress(_T("11.0.0.0"), CSocket::ipv4));

	// 169.254.0.0/16
	CPPUNIT_ASSERT(IsRoutableAddress(_T("169.253.255.255"), CSocket::ipv4));
	CPPUNIT_ASSERT(!IsRoutableAddress(_T("169.254.0.0"), CSocket::ipv4));
	CPPUNIT_ASSERT(!IsRoutableAddress(_T("169.254.255.255"), CSocket::ipv4));
	CPPUNIT_ASSERT(IsRoutableAddress(_T("169.255.0.0"), CSocket::ipv4));

	// 192.168.0.0/16
	CPPUNIT_ASSERT(IsRoutableAddress(_T("192.167.255.255"), CSocket::ipv4));
	CPPUNIT_ASSERT(!IsRoutableAddress(_T("192.168.0.0"), CSocket::ipv4));
	CPPUNIT_ASSERT(!IsRoutableAddress(_T("192.168.255.255"), CSocket::ipv4));
	CPPUNIT_ASSERT(IsRoutableAddress(_T("102.169.0.0"), CSocket::ipv4));

	// 172.16.0.0/20
	CPPUNIT_ASSERT(IsRoutableAddress(_T("172.15.255.255"), CSocket::ipv4));
	CPPUNIT_ASSERT(!IsRoutableAddress(_T("172.16.0.0"), CSocket::ipv4));
	CPPUNIT_ASSERT(!IsRoutableAddress(_T("172.31.255.255"), CSocket::ipv4));
	CPPUNIT_ASSERT(IsRoutableAddress(_T("172.32.0.0"), CSocket::ipv4));
}
Beispiel #4
0
void CIPAddressTest::testIsRoutableAddress6()
{
	CPPUNIT_ASSERT(!IsRoutableAddress(_T("::1"), CSocket::ipv6));
	CPPUNIT_ASSERT(!IsRoutableAddress(_T("::0"), CSocket::ipv6));
	CPPUNIT_ASSERT(IsRoutableAddress(_T("::2"), CSocket::ipv6));
	CPPUNIT_ASSERT(IsRoutableAddress(_T("1234:ABCD::1234:ef01"), CSocket::ipv6));

	// fe80::/10 (link local)
	CPPUNIT_ASSERT(IsRoutableAddress(_T("fe7f:ffff:ffff:ffff:ffff:ffff:ffff:ffff"), CSocket::ipv6));
	CPPUNIT_ASSERT(!IsRoutableAddress(_T("fe80:0000:0000:0000:0000:0000:0000:0000"), CSocket::ipv6));
	CPPUNIT_ASSERT(!IsRoutableAddress(_T("febf:ffff:ffff:ffff:ffff:ffff:ffff:ffff"), CSocket::ipv6));
	CPPUNIT_ASSERT(IsRoutableAddress(_T("fec0:0000:0000:0000:0000:0000:0000:0000"), CSocket::ipv6));

	// fc00::/7 (site local)
	CPPUNIT_ASSERT(IsRoutableAddress(_T("fbff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"), CSocket::ipv6));
	CPPUNIT_ASSERT(!IsRoutableAddress(_T("fc00:0000:0000:0000:0000:0000:0000:0000"), CSocket::ipv6));
	CPPUNIT_ASSERT(!IsRoutableAddress(_T("fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"), CSocket::ipv6));
	CPPUNIT_ASSERT(IsRoutableAddress(_T("fe00:0000:0000:0000:0000:0000:0000:0000"), CSocket::ipv6));

	// IPv4 mapped

	// 127.0.0.0/8
	CPPUNIT_ASSERT(IsRoutableAddress(_T("::ffff:7eff:ffff"), CSocket::ipv6));
	CPPUNIT_ASSERT(!IsRoutableAddress(_T("::ffff:7f00:0000"), CSocket::ipv6));
	CPPUNIT_ASSERT(!IsRoutableAddress(_T("::ffff:7fff:ffff"), CSocket::ipv6));
	CPPUNIT_ASSERT(IsRoutableAddress(_T("::ffff:8000:0000"), CSocket::ipv6));

	// 10.0.0.0/8
	CPPUNIT_ASSERT(IsRoutableAddress(_T("::ffff:9ff:ffff"), CSocket::ipv6));
	CPPUNIT_ASSERT(!IsRoutableAddress(_T("::ffff:0a00:0000"), CSocket::ipv6));
	CPPUNIT_ASSERT(!IsRoutableAddress(_T("::ffff:0aff:ffff"), CSocket::ipv6));
	CPPUNIT_ASSERT(IsRoutableAddress(_T("::ffff:0b00:0000"), CSocket::ipv6));

	// 169.254.0.0/16
	CPPUNIT_ASSERT(IsRoutableAddress(_T("::ffff:a9fd:ffff"), CSocket::ipv6));
	CPPUNIT_ASSERT(!IsRoutableAddress(_T("::ffff:a9fe:0000"), CSocket::ipv6));
	CPPUNIT_ASSERT(!IsRoutableAddress(_T("::ffff:a9fe:ffff"), CSocket::ipv6));
	CPPUNIT_ASSERT(IsRoutableAddress(_T("::ffff:a9ff:0000"), CSocket::ipv6));

	// 192.168.0.0/16
	CPPUNIT_ASSERT(IsRoutableAddress(_T("::ffff:c0a7:ffff"), CSocket::ipv6));
	CPPUNIT_ASSERT(!IsRoutableAddress(_T("::ffff:c0a8:0000"), CSocket::ipv6));
	CPPUNIT_ASSERT(!IsRoutableAddress(_T("::ffff:c0a8:ffff"), CSocket::ipv6));
	CPPUNIT_ASSERT(IsRoutableAddress(_T("::ffff:c0a9:0000"), CSocket::ipv6));

	// 172.16.0.0/20
	CPPUNIT_ASSERT(IsRoutableAddress(_T("::ffff:ac0f:ffff"), CSocket::ipv6));
	CPPUNIT_ASSERT(!IsRoutableAddress(_T("::ffff:ac10:0000"), CSocket::ipv6));
	CPPUNIT_ASSERT(!IsRoutableAddress(_T("::ffff:ac1f:ffff"), CSocket::ipv6));
	CPPUNIT_ASSERT(IsRoutableAddress(_T("::ffff:ac20:0000"), CSocket::ipv6));
}
Beispiel #5
0
bool IsRoutableAddress(const CStdString& address)
{
	if (address.Find(_T(":")) != -1)
	{
		CStdString long_address = GetIPV6LongForm(address);
		if (long_address.IsEmpty())
			return false;
		if (long_address[0] == '0')
		{
			// ::/128
			if (long_address == _T("0000:0000:0000:0000:0000:0000:0000:0000"))
				return false;
			// ::1/128
			if (long_address == _T("0000:0000:0000:0000:0000:0000:0000:0001"))
				return false;

			if (long_address.Left(30) == _T("0000:0000:0000:0000:0000:ffff:"))
			{
				// IPv4 mapped
				CStdString ipv4;
				ipv4.Format(_T("%d.%d.%d.%d"),
						DigitHexToDecNum(long_address[30]) * 16 + DigitHexToDecNum(long_address[31]),
						DigitHexToDecNum(long_address[32]) * 16 + DigitHexToDecNum(long_address[33]),
						DigitHexToDecNum(long_address[35]) * 16 + DigitHexToDecNum(long_address[36]),
						DigitHexToDecNum(long_address[37]) * 16 + DigitHexToDecNum(long_address[38]));
				return IsRoutableAddress(ipv4);
			}

			return true;
		}
		if (long_address[0] == 'f')
		{
			if (long_address[1] == 'e')
			{
				// fe80::/10 (link local)
				const TCHAR& c = long_address[2];
				int v;
				if (c >= 'a')
					v = c - 'a' + 10;
				else
					v = c - '0';
				if ((v & 0xc) == 0x8)
					return false;

				return true;
			}
			else if (long_address[1] == 'c' || long_address[1] == 'd')
			{
				// fc00::/7 (site local)
				return false;
			}
		}

		return true;
	}
	else
	{
		// Assumes address is already a valid IP address
		if (address.Left(3) == _T("127") ||
			address.Left(3) == _T("10.") ||
			address.Left(7) == _T("192.168") ||
			address.Left(7) == _T("169.254"))
			return false;

		if (address.Left(3) == _T("172"))
		{
			CStdString middle = address.Mid(4);
			int pos = address.Find(_T("."));
			if (pos == -1)
				return false;
			int part = _ttoi(middle.Left(pos));

			if (part >= 16 && part <= 31)
				return false;
		}

		return true;
	}
}