La struttura memorizza l'indirizzo nell'ordine dei byte di rete - o "big endian" - con il byte più significativo @s6_addr[0]
. Non puoi contare sul fatto che gli altri membri del sindacato abbiano un nome o una definizione coerenti. Anche se si accede all'unione tramite un campo (non portatile) uint32_t
, i valori devono essere convertiti con ntohl
. Quindi un metodo portatile per trovare la differenza richiede un po 'di lavoro.
È possibile convertire in6_addr
in uint64_t[2]
. Attaccando con convenzioni tipico 'bignum', usiamo [0] per le basse 64-bit e [1] per le alte 64 bit:
static inline void
in6_to_u64 (uint64_t dst[2], const struct in6_addr *src)
{
uint64_t hi = 0, lo = 0;
for (unsigned int i = 0; i < 8; i++)
{
hi = (hi << 8) | src->s6_addr[i];
lo = (lo << 8) | src->s6_addr[i + 8];
}
dst[0] = lo, dst[1] = hi;
}
e la differenza:
static inline unsigned int
u64_diff (uint64_t d[2], const uint64_t x[2], const uint64_t y[2])
{
unsigned int b = 0, bi;
for (unsigned int i = 0; i < 2; i++)
{
uint64_t di, xi, yi, tmp;
xi = x[i], yi = y[i];
tmp = xi - yi;
di = tmp - b, bi = tmp > xi;
d[i] = di, b = bi | (di > tmp);
}
return b; /* borrow flag = (x < y) */
}
fonte
2015-08-12 19:53:17
In pratica, non tutti gli intervalli saranno compresi tra/32 e/96? – MSalters
IPv6 è progettato in modo da avere sempre più indirizzi di quanti ne avrai mai bisogno, quindi spero che non avrai mai bisogno di questo codice. Pensare al numero di indirizzi con IPv6 è di solito un segno che sei ancora bloccato in una mentalità IPv4 :) –
Con alcune eccezioni, un intervallo di indirizzi IPv6 (subnet) sarà a/64, e che equivale a 18.446.744.073.709.551.616 indirizzi per sottorete . Per altre dimensioni, è sempre possibile calcolare 2^(lunghezza maschera 128). –