mirror of
https://github.com/bol-van/zapret.git
synced 2025-05-24 22:32:58 +03:00
ip2net : precompute ipv6 masks
This commit is contained in:
@@ -79,7 +79,7 @@ static uint32_t unique6(struct in6_addr *pu, uint32_t ct)
|
||||
}
|
||||
return i;
|
||||
}
|
||||
static void mask_from_bitcount6(uint32_t zct, struct in6_addr *a)
|
||||
static void mask_from_bitcount6_make(uint32_t zct, struct in6_addr *a)
|
||||
{
|
||||
if (zct >= 128)
|
||||
memset(a->s6_addr,0x00,16);
|
||||
@@ -91,6 +91,17 @@ static void mask_from_bitcount6(uint32_t zct, struct in6_addr *a)
|
||||
a->s6_addr[n] = ~((1 << (zct & 7)) - 1);
|
||||
}
|
||||
}
|
||||
static struct in6_addr ip6_mask[129];
|
||||
static void mask_from_bitcount6_prepare()
|
||||
{
|
||||
for (int zct=0;zct<=128;zct++) mask_from_bitcount6_make(zct, ip6_mask+zct);
|
||||
}
|
||||
static inline const struct in6_addr *mask_from_bitcount6(uint32_t zct)
|
||||
{
|
||||
return ip6_mask+zct;
|
||||
}
|
||||
|
||||
|
||||
// result = a & b
|
||||
static void ip6_and(const struct in6_addr *a, const struct in6_addr *b, struct in6_addr *result)
|
||||
{
|
||||
@@ -264,6 +275,7 @@ int main(int argc, char **argv)
|
||||
}
|
||||
gnu_quicksort(iplist, ipct, sizeof(*iplist), cmp6, NULL);
|
||||
ipct = unique6(iplist, ipct);
|
||||
mask_from_bitcount6_prepare();
|
||||
|
||||
/*
|
||||
for(uint32_t i=0;i<ipct;i++)
|
||||
@@ -273,18 +285,19 @@ int main(int argc, char **argv)
|
||||
*/
|
||||
while (pos < ipct)
|
||||
{
|
||||
struct in6_addr mask, ip_start, ip;
|
||||
const struct in6_addr *mask;
|
||||
struct in6_addr ip_start, ip;
|
||||
uint32_t ip_ct_best = 0, zct_best = 0;
|
||||
|
||||
pos_end = pos + 1;
|
||||
// find smallest network with maximum ip coverage with no less than ip6_subnet_threshold addresses
|
||||
for (zct = params.zct_max; zct >= params.zct_min; zct--)
|
||||
{
|
||||
mask_from_bitcount6(zct, &mask);
|
||||
ip6_and(iplist + pos, &mask, &ip_start);
|
||||
mask = mask_from_bitcount6(zct);
|
||||
ip6_and(iplist + pos, mask, &ip_start);
|
||||
for (p = pos + 1, ip_ct = 1; p < ipct; p++, ip_ct++)
|
||||
{
|
||||
ip6_and(iplist + p, &mask, &ip);
|
||||
ip6_and(iplist + p, mask, &ip);
|
||||
if (memcmp(&ip_start, &ip, sizeof(ip)))
|
||||
break;
|
||||
}
|
||||
@@ -303,11 +316,8 @@ int main(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
if (zct_best)
|
||||
{
|
||||
// network was found
|
||||
mask_from_bitcount6(zct_best, &mask);
|
||||
ip6_and(iplist + pos, &mask, &ip_start);
|
||||
}
|
||||
ip6_and(iplist + pos, mask_from_bitcount6(zct_best), &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));
|
||||
|
Reference in New Issue
Block a user