Effective way to verify if the IPv6 bitwise netmask is contiguous

I need to save IP addresses / netmasks in in_addr / in6_addr structure. For IPv4, I use the following code to check if the netmask is continuous:

((((~netmask + 1) & (~netmask)) != 0)  && (netmask != 0))

I was wondering if there is a reasonable way to do the same for IPv6.

+4
source share
2 answers

Some compilers have 128-bit integers. I used __uint128_t in code that was compiled using gcc in the AMD64 architecture.

If you use a compiler with 128-bit integers, you can simply reuse your existing code as it makes no assumptions about the size of the word.

, , , , . , ():

for (i = 0; i < 4 && netmask[i] != 0xffffffff; ++i)

netmask[i], , , .

, , , , - :

int contiguous(uint32_t **netmask)
{
    int i;
    for (i = 0; i < 4; ++i) {
        if ((~netmask[i] + 1) & (~netmask[i])) return 0;
    }
    for (i = 0; i < 3; ++i) {
        if ((netmask[i] != 0xffffffff) && (netmask[i+1] != 0)) return 0;
    }
    return 1;
}

, , 0 128 . , .

+1

:

IPV6 32 :

uint64_t netmask1, netmask2, netmask3;
netmask1 = (netmask.s6_addr32[0] << 32) + in6_netmask.s6_addr32[1];
netmask2 = (netmask.s6_addr32[1] << 32) + in6_netmask.s6_addr32[2];
netmask3 = (netmask.s6_addr32[2] << 32) + in6_netmask.s6_addr32[3];

, .

 if ((((~address1 + 1) & (~address1)) != 0) ||
    (((~address2 + 1) & (~address2)) != 0) ||
    ((~address3 + 1) & (~address3)) != 0))) {
  // Netmask is not valid!
}
+1

Source: https://habr.com/ru/post/1569128/


All Articles