My approach is related to Zan's, but copes with the fact that a struct in6_addr
, which is contained in a struct sockaddr_in6
, is essentially an array of 16 chars.
So you should iterate over the bytes until you find a value != 0xFF
.
int bits = 0;
struct in6_addr * addr = &((struct sockaddr_in6 *)ai_addr)->sin6_addr;
for (i=0; i<16; i++) {
if (addr->s6_addr[i] == '\xFF') {
bits += 8;
} else {
case (addr->s6_addr[i]) {
'\xFE': bits += 7; break;
'\xFC': bits += 6; break;
'\xF8': bits += 5; break;
'\xF0': bits += 4; break;
'\xE0': bits += 3; break;
'\xC0': bits += 2; break;
'\x80': bits += 1; break;
'\x00': bits += 0; break;
default: complain();
}
break;
}
}
But, as Zan writes, better keep the number you already have an generate the mask if you need it, not the other way.
But, @SamuelChampagne, really: you should really accept working answers! One day, people will refuse to help you at all.