summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoriphydf <iphydf@users.noreply.github.com>2018-08-27 16:06:40 +0000
committeriphydf <iphydf@users.noreply.github.com>2018-09-06 20:07:23 +0000
commit1cd183691735126aa3c916c3e2417e2edd104d1d (patch)
treecf690bc9bdbf5daccf2fbd2df3687a04ea64d930
parentf59e6ff0cb829dfd46e5383658a7b34bb512b5f2 (diff)
Avoid recursion in `ip_is_lan` and `ip_is_local`.
-rw-r--r--toxcore/LAN_discovery.c103
1 files changed, 54 insertions, 49 deletions
diff --git a/toxcore/LAN_discovery.c b/toxcore/LAN_discovery.c
index fd5bca34..aeeea566 100644
--- a/toxcore/LAN_discovery.c
+++ b/toxcore/LAN_discovery.c
@@ -272,71 +272,77 @@ static IP broadcast_ip(Family family_socket, Family family_broadcast)
272 return ip; 272 return ip;
273} 273}
274 274
275static bool ip4_is_local(IP4 ip4)
276{
277 /* Loopback. */
278 return ip4.uint8[0] == 127;
279}
280
275/* Is IP a local ip or not. */ 281/* Is IP a local ip or not. */
276bool ip_is_local(IP ip) 282bool ip_is_local(IP ip)
277{ 283{
278 if (net_family_is_ipv4(ip.family)) { 284 if (net_family_is_ipv4(ip.family)) {
279 IP4 ip4 = ip.ip.v4; 285 return ip4_is_local(ip.ip.v4);
286 }
280 287
281 /* Loopback. */ 288 /* embedded IPv4-in-IPv6 */
282 if (ip4.uint8[0] == 127) { 289 if (ipv6_ipv4_in_v6(ip.ip.v6)) {
283 return 1; 290 IP4 ip4;
284 } 291 ip4.uint32 = ip.ip.v6.uint32[3];
285 } else { 292 return ip4_is_local(ip4);
286 /* embedded IPv4-in-IPv6 */ 293 }
287 if (ipv6_ipv4_in_v6(ip.ip.v6)) {
288 IP ip4;
289 ip4.family = net_family_ipv4;
290 ip4.ip.v4.uint32 = ip.ip.v6.uint32[3];
291 return ip_is_local(ip4);
292 }
293 294
294 /* localhost in IPv6 (::1) */ 295 /* localhost in IPv6 (::1) */
295 if (ip.ip.v6.uint64[0] == 0 && ip.ip.v6.uint32[2] == 0 && ip.ip.v6.uint32[3] == net_htonl(1)) { 296 if (ip.ip.v6.uint64[0] == 0 && ip.ip.v6.uint32[2] == 0 && ip.ip.v6.uint32[3] == net_htonl(1)) {
296 return 1; 297 return true;
297 }
298 } 298 }
299 299
300 return 0; 300 return false;
301} 301}
302 302
303bool ip_is_lan(IP ip) 303static bool ip4_is_lan(IP4 ip4)
304{ 304{
305 if (ip_is_local(ip)) { 305 /* 10.0.0.0 to 10.255.255.255 range. */
306 if (ip4.uint8[0] == 10) {
306 return true; 307 return true;
307 } 308 }
308 309
309 if (net_family_is_ipv4(ip.family)) { 310 /* 172.16.0.0 to 172.31.255.255 range. */
310 IP4 ip4 = ip.ip.v4; 311 if (ip4.uint8[0] == 172 && ip4.uint8[1] >= 16 && ip4.uint8[1] <= 31) {
312 return true;
313 }
311 314
312 /* 10.0.0.0 to 10.255.255.255 range. */ 315 /* 192.168.0.0 to 192.168.255.255 range. */
313 if (ip4.uint8[0] == 10) { 316 if (ip4.uint8[0] == 192 && ip4.uint8[1] == 168) {
314 return true; 317 return true;
315 } 318 }
316 319
317 /* 172.16.0.0 to 172.31.255.255 range. */ 320 /* 169.254.1.0 to 169.254.254.255 range. */
318 if (ip4.uint8[0] == 172 && ip4.uint8[1] >= 16 && ip4.uint8[1] <= 31) { 321 if (ip4.uint8[0] == 169 && ip4.uint8[1] == 254 && ip4.uint8[2] != 0
319 return true; 322 && ip4.uint8[2] != 255) {
320 } 323 return true;
324 }
321 325
322 /* 192.168.0.0 to 192.168.255.255 range. */ 326 /* RFC 6598: 100.64.0.0 to 100.127.255.255 (100.64.0.0/10)
323 if (ip4.uint8[0] == 192 && ip4.uint8[1] == 168) { 327 * (shared address space to stack another layer of NAT) */
324 return true; 328 if ((ip4.uint8[0] == 100) && ((ip4.uint8[1] & 0xC0) == 0x40)) {
325 } 329 return true;
330 }
326 331
327 /* 169.254.1.0 to 169.254.254.255 range. */ 332 return false;
328 if (ip4.uint8[0] == 169 && ip4.uint8[1] == 254 && ip4.uint8[2] != 0 333}
329 && ip4.uint8[2] != 255) {
330 return true;
331 }
332 334
333 /* RFC 6598: 100.64.0.0 to 100.127.255.255 (100.64.0.0/10) 335bool ip_is_lan(IP ip)
334 * (shared address space to stack another layer of NAT) */ 336{
335 if ((ip4.uint8[0] == 100) && ((ip4.uint8[1] & 0xC0) == 0x40)) { 337 if (ip_is_local(ip)) {
336 return true; 338 return true;
337 } 339 }
338 } else if (net_family_is_ipv6(ip.family)) { 340
341 if (net_family_is_ipv4(ip.family)) {
342 return ip4_is_lan(ip.ip.v4);
343 }
339 344
345 if (net_family_is_ipv6(ip.family)) {
340 /* autogenerated for each interface: FE80::* (up to FEBF::*) 346 /* autogenerated for each interface: FE80::* (up to FEBF::*)
341 FF02::1 is - according to RFC 4291 - multicast all-nodes link-local */ 347 FF02::1 is - according to RFC 4291 - multicast all-nodes link-local */
342 if (((ip.ip.v6.uint8[0] == 0xFF) && (ip.ip.v6.uint8[1] < 3) && (ip.ip.v6.uint8[15] == 1)) || 348 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)
346 352
347 /* embedded IPv4-in-IPv6 */ 353 /* embedded IPv4-in-IPv6 */
348 if (ipv6_ipv4_in_v6(ip.ip.v6)) { 354 if (ipv6_ipv4_in_v6(ip.ip.v6)) {
349 IP ip4; 355 IP4 ip4;
350 ip4.family = net_family_ipv4; 356 ip4.uint32 = ip.ip.v6.uint32[3];
351 ip4.ip.v4.uint32 = ip.ip.v6.uint32[3]; 357 return ip4_is_lan(ip4);
352 return ip_is_lan(ip4);
353 } 358 }
354 } 359 }
355 360