Comprimento máximo da representação textual de um endereço IPv6?

430

Eu quero armazenar os dados retornados pelo $_SERVER["REMOTE_ADDR"]PHP em um campo DB, tarefa bastante simples, realmente. O problema é que não consigo encontrar nenhuma informação adequada sobre o comprimento máximo da representação textual de um endereço IPv6, que é o que um servidor da web fornece $_SERVER["REMOTE_ADDR"].

Não estou interessado em converter a representação textual em 128 bits em que o endereço normalmente é codificado. Quero apenas saber quantos caracteres são necessários no máximo para armazenar qualquer endereço IPv6 retornado por $_SERVER["REMOTE_ADDR"].

Gilles
fonte
6
E o índice da zona?
Robert Tupelo-Schneck
5
#define INET_ADDRSTRLEN (16) #define INET6_ADDRSTRLEN (48)
Fonte: lxr.free-electrons.com/source/include/linux/inet.h
1
A pergunta stackoverflow.com/questions/1076714/… tem algumas respostas semelhantes, mas úteis.
Edward

Respostas:

615

45 caracteres .

Você pode esperar que um endereço seja

0000:0000:0000:0000:0000:0000:0000:0000

8 * 4 + 7 = 39

8 grupos de 4 dígitos com 7 :entre eles.

Mas se você tiver um endereço IPv6 mapeado para IPv4 , os dois últimos grupos poderão ser escritos na base 10 separados por ., por exemplo. [::ffff:192.168.100.228]. Escrito totalmente:

0000:0000:0000:0000:0000:ffff:192.168.100.228

(6 * 4 + 5) + 1 + (4 * 3 + 3) = 29 + 1 + 15 = 45

Observe que esta é uma convenção de entrada / exibição - ainda é um endereço de 128 bits e, para armazenamento, provavelmente seria melhor padronizar no formato separado por dois pontos, [0000:0000:0000:0000:0000:ffff:c0a8:64e4]por exemplo , para o endereço acima.

Matthew Scharley
fonte
245
Os arquivos de cabeçalho definem INET6_ADDRSTRLEN como 46, que se encaixa com 45 caracteres mais um nulo à direita.
wisnij
6
Vale ressaltar que o endereço IPv6 também pode conter a zona de escopo stackoverflow.com/questions/5746082/… , por exemplo, você obtém o de RemoteEndpointMessageProperty.Address
Rory
não são endereços IPv4 escritos como :: ffff: 127.0.0.1?
GrayWolf
52
O @FelipeSchenone é esse tipo de pensamento que não é útil - descubra o tamanho e use-o. O único momento em que você deseja estender um buffer é se ele ajuda no preenchimento de 64 caracteres, mas 45 (+1) é o ideal.
precisa
1
isso leva em conta o sinal de porcentagem no endereço ipv6? Consulte - superuser.com/questions/99746/…
gaurav
85

No Linux, consulte constante INET6_ADDRSTRLEN(inclua <arpa/inet.h>, consulte man inet_ntop). No meu sistema (cabeçalho "in.h"):

#define INET6_ADDRSTRLEN 46

O último caractere é para terminar NULL, como eu acredito, então o comprimento máximo é 45, como outras respostas.

Yury
fonte
2
Então, o que é esse 48 que eu vejo? github.com/torvalds/linux/blob/master/include/linux/inet.h#L50
eis
O @eis provavelmente foi em 2013. Possivelmente incrementado para o alinhamento da estrutura.
Iiridayn 6/04
13

Respondeu minha própria pergunta:

Os endereços IPv6 são normalmente gravados como oito grupos de quatro dígitos hexadecimais, em que cada grupo é separado por dois pontos (:).

Portanto, são 39 caracteres no máximo.

Gilles
fonte
7
No entanto, aparentemente há uma advertência, consulte stackoverflow.com/a/7477384/3787376 ("Comprimento máximo do endereço IP do cliente") - Citação: "Para endereços IPv6 mapeados para IPv4, a cadeia pode ter mais de 39 caracteres.". Ele diz que um "IPv6 mapeado para IPv4" tem 45 caracteres e está no formato "NNNN: NNNN: NNNN: NNNN: NNNN: NNNN: 192.168.158.190". O máximo deve, portanto, ser 45 caracteres. A resposta em stackoverflow.com/a/166157/3787376 (esta pergunta) também parece demonstrar esse ponto.
Edward Edward
6

Acho que a resposta @Deepak neste link está mais próxima da resposta correta. Comprimento máximo para o endereço IP do cliente . Portanto, o tamanho correto é 45 e não 39. Às vezes, tentamos reduzir o tamanho dos campos, mas parece melhor se prepararmos um tamanho de armazenamento suficiente.

QMaster
fonte
4

Conforme indicado, um endereço IPv6 padrão tem no máximo 45 caracteres, mas um endereço IPv6 também pode incluir um% final seguido por uma sequência de "escopo" ou "zona", que não possui comprimento fixo, mas geralmente é um pequeno número inteiro positivo ou uma interface de rede nome, portanto, na realidade, pode ter mais de 45 caracteres. Os nomes das interfaces de rede geralmente são "eth0", "eth1", "wlan0", portanto, escolher 50 como limite provavelmente é bom o suficiente.

Sean F
fonte
3
É verdade, mas este é apenas um endereço local de link, e você não verá nenhum deles quando o site estiver em execução na Internet (e esperamos que nem mesmo durante o desenvolvimento).
Michael Hampton
1

Cuidado com determinados cabeçalhos, como os HTTP_X_FORWARDED_FORque parecem conter um único endereço IP. Eles podem realmente conter vários endereços (uma cadeia de proxies que eu assumo).

Eles parecerão delimitados por vírgula - e podem ter muito mais de 45 caracteres no total -, portanto, verifique antes de armazenar no DB.

Simon_Weaver
fonte
3
Um -1 levemente conflituoso (conflituoso porque já caí nessa armadilha antes e acho que essa resposta contém informações relevantes para algumas pessoas que chegarão a esta página) porque, no entanto, essa claramente não é uma resposta à pergunta. Provavelmente seria melhor como um comentário sobre a questão.
Mark Amery