El sourcecode para los tipos de datos IP a mostrar este:
typedef struct
{
unsigned char family; /* PGSQL_AF_INET or PGSQL_AF_INET6 */
unsigned char bits; /* number of bits in netmask */
unsigned char ipaddr[16]; /* up to 128 bits of address */
} inet_struct;
Esto significa, que adicionalmente a los datos "en bruto" en ipaddr
(4 bytes para IP4, 16 bytes para IP6) hay un byte para la máscara de red y un byte para la familia de direcciones (básicamente un interruptor para IP4/IP6).
Además existe la varlena
gastos generales que se menciona en el mismo archivo:
/*
* Both INET and CIDR addresses are represented within Postgres as varlena
* objects, ie, there is a varlena header in front of the struct type
* depicted above. This struct depicts what we actually have in memory
* in "uncompressed" cases. Note that since the maximum data size is only
* 18 bytes, INET/CIDR will invariably be stored into tuples using the
* 1-byte-header varlena format. However, we have to be prepared to cope
* with the 4-byte-header format too, because various code may helpfully
* try to "decompress" 1-byte-header datums.
*/
typedef struct
{
char vl_len_[4]; /* Do not touch this field directly! */
inet_struct inet_data;
} inet;
Por lo tanto la ecuación para IP4 es la siguiente:
1 byte varlena
1 byte address family
1 byte netmask
4 raw bytes
===========
7 byte total
Para IP6 la misma fórmula que da 19 bytes.
EDIT Las versiones anteriores de PostgreSQL solo tenían una representación varlena de 4 bytes. Por lo tanto, puede agregar 3 bytes para cada tipo (IP4: 10, IP6: 22). Además de eso, había un relleno hasta el siguiente borde de 4 bytes. Esto le da 2 bytes para cada tipo sumando hasta 12 o 24 bytes.
This mail arroja algo de luz sobre el desarrollo de la versión más corta.
Necesita al menos +1 byte para la máscara de red, por ejemplo, "10.1.0.0/8" es válido para 10.1.0.0 máscara 255.0.0.0 –