ip2net : zero less significant bits in ip4/ip6 addresses, workaround GCC bug

This commit is contained in:
bol-van 2021-09-12 13:58:13 +03:00
parent 69dab1a9d4
commit 9402cd2cf0
10 changed files with 21 additions and 3 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -94,8 +94,16 @@ static void mask_from_bitcount6(uint32_t zct, struct in6_addr *a)
// result = a & b // result = a & b
static void ip6_and(const struct in6_addr *a, const struct in6_addr *b, struct in6_addr *result) static void ip6_and(const struct in6_addr *a, const struct in6_addr *b, struct in6_addr *result)
{ {
// POSSIBLE GCC COMPILER BUG . when using uint64_t and -O2/-O3 optimizations this function gets inlined with the wrong code and produces wrong results
#if defined(__GNUC__) && !defined(__llvm__) && !defined(__NO_INLINE__)
((uint32_t*)result->s6_addr)[0] = ((uint32_t*)a->s6_addr)[0] & ((uint32_t*)b->s6_addr)[0];
((uint32_t*)result->s6_addr)[1] = ((uint32_t*)a->s6_addr)[1] & ((uint32_t*)b->s6_addr)[1];
((uint32_t*)result->s6_addr)[2] = ((uint32_t*)a->s6_addr)[2] & ((uint32_t*)b->s6_addr)[2];
((uint32_t*)result->s6_addr)[3] = ((uint32_t*)a->s6_addr)[3] & ((uint32_t*)b->s6_addr)[3];
#else
((uint64_t*)result->s6_addr)[0] = ((uint64_t*)a->s6_addr)[0] & ((uint64_t*)b->s6_addr)[0]; ((uint64_t*)result->s6_addr)[0] = ((uint64_t*)a->s6_addr)[0] & ((uint64_t*)b->s6_addr)[0];
((uint64_t*)result->s6_addr)[1] = ((uint64_t*)a->s6_addr)[1] & ((uint64_t*)b->s6_addr)[1]; ((uint64_t*)result->s6_addr)[1] = ((uint64_t*)a->s6_addr)[1] & ((uint64_t*)b->s6_addr)[1];
#endif
} }
static void rtrim(char *s) static void rtrim(char *s)
@ -259,7 +267,7 @@ int main(int argc, char **argv)
/* /*
for(uint32_t i=0;i<ipct;i++) for(uint32_t i=0;i<ipct;i++)
if (inet_ntop(AF_INET6,iplist+i,str,256)) if (inet_ntop(AF_INET6,iplist+i,str,sizeof(str)))
printf("%s\n",str); printf("%s\n",str);
printf("\n"); printf("\n");
*/ */
@ -294,7 +302,14 @@ int main(int argc, char **argv)
break; break;
} }
} }
if (!zct_best) ip_start = iplist[pos], pos_end = pos + 1; // network not found, use single ip if (zct_best)
{
// network was found
mask_from_bitcount6(zct_best, &mask);
ip6_and(iplist + pos, &mask, &ip_start);
}
else
ip_start = iplist[pos], pos_end = pos + 1; // network not found, use single ip
inet_ntop(AF_INET6, &ip_start, str, sizeof(str)); inet_ntop(AF_INET6, &ip_start, str, sizeof(str));
printf(zct_best ? "%s/%u\n" : "%s\n", str, 128 - zct_best); printf(zct_best ? "%s/%u\n" : "%s\n", str, 128 - zct_best);
@ -379,7 +394,10 @@ int main(int argc, char **argv)
break; break;
} }
} }
if (!zct_best) ip_start = iplist[pos], pos_end = pos + 1; // network not found, use single ip if (zct_best)
ip_start = iplist[pos] & mask_from_bitcount(zct_best);
else
ip_start = iplist[pos], pos_end = pos + 1; // network not found, use single ip
u1 = ip_start >> 24; u1 = ip_start >> 24;
u2 = (ip_start >> 16) & 0xFF; u2 = (ip_start >> 16) & 0xFF;