Avoid recursion in ip_is_lan and ip_is_local.

This commit is contained in:
iphydf 2018-08-27 16:06:40 +00:00
parent f59e6ff0cb
commit 1cd1836917
No known key found for this signature in database
GPG Key ID: 3855DBA2D74403C9

View File

@ -272,32 +272,64 @@ static IP broadcast_ip(Family family_socket, Family family_broadcast)
return ip;
}
static bool ip4_is_local(IP4 ip4)
{
/* Loopback. */
return ip4.uint8[0] == 127;
}
/* Is IP a local ip or not. */
bool ip_is_local(IP ip)
{
if (net_family_is_ipv4(ip.family)) {
IP4 ip4 = ip.ip.v4;
/* Loopback. */
if (ip4.uint8[0] == 127) {
return 1;
}
} else {
/* embedded IPv4-in-IPv6 */
if (ipv6_ipv4_in_v6(ip.ip.v6)) {
IP ip4;
ip4.family = net_family_ipv4;
ip4.ip.v4.uint32 = ip.ip.v6.uint32[3];
return ip_is_local(ip4);
}
/* localhost in IPv6 (::1) */
if (ip.ip.v6.uint64[0] == 0 && ip.ip.v6.uint32[2] == 0 && ip.ip.v6.uint32[3] == net_htonl(1)) {
return 1;
}
return ip4_is_local(ip.ip.v4);
}
return 0;
/* embedded IPv4-in-IPv6 */
if (ipv6_ipv4_in_v6(ip.ip.v6)) {
IP4 ip4;
ip4.uint32 = ip.ip.v6.uint32[3];
return ip4_is_local(ip4);
}
/* localhost in IPv6 (::1) */
if (ip.ip.v6.uint64[0] == 0 && ip.ip.v6.uint32[2] == 0 && ip.ip.v6.uint32[3] == net_htonl(1)) {
return true;
}
return false;
}
static bool ip4_is_lan(IP4 ip4)
{
/* 10.0.0.0 to 10.255.255.255 range. */
if (ip4.uint8[0] == 10) {
return true;
}
/* 172.16.0.0 to 172.31.255.255 range. */
if (ip4.uint8[0] == 172 && ip4.uint8[1] >= 16 && ip4.uint8[1] <= 31) {
return true;
}
/* 192.168.0.0 to 192.168.255.255 range. */
if (ip4.uint8[0] == 192 && ip4.uint8[1] == 168) {
return true;
}
/* 169.254.1.0 to 169.254.254.255 range. */
if (ip4.uint8[0] == 169 && ip4.uint8[1] == 254 && ip4.uint8[2] != 0
&& ip4.uint8[2] != 255) {
return true;
}
/* RFC 6598: 100.64.0.0 to 100.127.255.255 (100.64.0.0/10)
* (shared address space to stack another layer of NAT) */
if ((ip4.uint8[0] == 100) && ((ip4.uint8[1] & 0xC0) == 0x40)) {
return true;
}
return false;
}
bool ip_is_lan(IP ip)
@ -307,36 +339,10 @@ bool ip_is_lan(IP ip)
}
if (net_family_is_ipv4(ip.family)) {
IP4 ip4 = ip.ip.v4;
/* 10.0.0.0 to 10.255.255.255 range. */
if (ip4.uint8[0] == 10) {
return true;
}
/* 172.16.0.0 to 172.31.255.255 range. */
if (ip4.uint8[0] == 172 && ip4.uint8[1] >= 16 && ip4.uint8[1] <= 31) {
return true;
}
/* 192.168.0.0 to 192.168.255.255 range. */
if (ip4.uint8[0] == 192 && ip4.uint8[1] == 168) {
return true;
}
/* 169.254.1.0 to 169.254.254.255 range. */
if (ip4.uint8[0] == 169 && ip4.uint8[1] == 254 && ip4.uint8[2] != 0
&& ip4.uint8[2] != 255) {
return true;
}
/* RFC 6598: 100.64.0.0 to 100.127.255.255 (100.64.0.0/10)
* (shared address space to stack another layer of NAT) */
if ((ip4.uint8[0] == 100) && ((ip4.uint8[1] & 0xC0) == 0x40)) {
return true;
}
} else if (net_family_is_ipv6(ip.family)) {
return ip4_is_lan(ip.ip.v4);
}
if (net_family_is_ipv6(ip.family)) {
/* autogenerated for each interface: FE80::* (up to FEBF::*)
FF02::1 is - according to RFC 4291 - multicast all-nodes link-local */
if (((ip.ip.v6.uint8[0] == 0xFF) && (ip.ip.v6.uint8[1] < 3) && (ip.ip.v6.uint8[15] == 1)) ||
@ -346,10 +352,9 @@ bool ip_is_lan(IP ip)
/* embedded IPv4-in-IPv6 */
if (ipv6_ipv4_in_v6(ip.ip.v6)) {
IP ip4;
ip4.family = net_family_ipv4;
ip4.ip.v4.uint32 = ip.ip.v6.uint32[3];
return ip_is_lan(ip4);
IP4 ip4;
ip4.uint32 = ip.ip.v6.uint32[3];
return ip4_is_lan(ip4);
}
}