ElChino
2016-11-27 14:11:42 UTC
I'm having some troubles figuring out the CIDR "prefix length"
of a IPv6 addresses range.
Specifically, in some code that reads MaxMind's GeoIPv6.dat records,
the low and high IP-numbers of IPv6-blocks are given like:
IP-num low: 76:96:42:219::
IP-num high: 76:96:42:219:ffff:ffff:ffff:ffff
(belonging to 'United States')
I need to figure out how to print this using CIDR notation.
E.g. if I have the 2 above addresses in
struct in6_addr a, b;
I've cooked up this function after much head-scratching:
static int network_len128 (const struct in6_addr *a, const struct in6_addr *b)
{
int i, j, bits = 0;
BYTE v;
for (i = 15; i >= 0; i--)
{
v = (a->s6_bytes[i] ^ b->s6_bytes[i]);
for (j = 0; j < 8; j++, bits++)
if ((v & (1 << j)) == 0)
goto quit;
}
quit:
return (bits);
}
Figuring I had to go backwards from LSB to MSB and stop counting
when 2 bits are equal.
The above code (+inet_ntop(&a..)) will print "76:96:42:219::/64".
Does this make sense for you experts?
of a IPv6 addresses range.
Specifically, in some code that reads MaxMind's GeoIPv6.dat records,
the low and high IP-numbers of IPv6-blocks are given like:
IP-num low: 76:96:42:219::
IP-num high: 76:96:42:219:ffff:ffff:ffff:ffff
(belonging to 'United States')
I need to figure out how to print this using CIDR notation.
E.g. if I have the 2 above addresses in
struct in6_addr a, b;
I've cooked up this function after much head-scratching:
static int network_len128 (const struct in6_addr *a, const struct in6_addr *b)
{
int i, j, bits = 0;
BYTE v;
for (i = 15; i >= 0; i--)
{
v = (a->s6_bytes[i] ^ b->s6_bytes[i]);
for (j = 0; j < 8; j++, bits++)
if ((v & (1 << j)) == 0)
goto quit;
}
quit:
return (bits);
}
Figuring I had to go backwards from LSB to MSB and stop counting
when 2 bits are equal.
The above code (+inet_ntop(&a..)) will print "76:96:42:219::/64".
Does this make sense for you experts?