A diversão de fazer parsing de endereços IP
(blog.dave.tf)-
Um texto que organiza de forma fácil de ler o que foi aprendido ao criar um parser rápido de IPv4+v6
-
Representação canônica
→ v4 : 192.168.0.1 , Dotted Quad de bytes de 1 byte
→ v6 : 1:2:3:4:5:6:7:8 , Colon-Hex de blocos de 2 bytes
[IPv6]
- Como muitos 0 aparecem no meio, usa-se
::para remover um ou mais blocos de 0
→ 1:2::3:4 = 1:2:0:0:0:0:3:4
- Os últimos 32 bits podem usar a notação Dotted Quad do v4
→ 1:2:3:4:5:6:77.77.88.88 = 1:2:3:4:5:6:4d4d:5858
→ fe80::1.2.3.4 = fe80:0:0:0:0:0:102:304
- Fica um pouco mais complicado porque há casos em que
::aparece no começo/fim
→ ::1 = 0:0:0:0:0:0:0:1
→ 1:: = 1:0:0:0:0:0:0:0
→ :: = 0:0:0:0:0:0:0:0
- Todos os campos do IPv6 Colon-Hex são números hexadecimais de 4 dígitos, e os 0 à esquerda podem ser removidos
→ :: = 0000:0000:0000:0000:0000:0000:0000:0000
[IPv4]
- O curioso é que, antes de a notação Dotted Quad dos últimos 32 bits no IPv6 ser formalizada, ela nunca havia sido padronizada em documento algum
→ Por isso, o padrão de mercado de fato geralmente era algo como "isso pode ser interpretado no 4.2BSD?" e "o que foi mantido quando outros sistemas operacionais copiaram o 4.2BSD?"
- Mas o 4.2BSD é meio estranho (whacky)
→ 192.168.140.255 = 3232271615
→ Ou seja, se você acessar http://3232271615 no Chrome, ele vai carregar http://192.168.140.255 . Afinal, é um número de 4 bytes!
→ Também dá para usar o octal http://0300.0250.0214.0377
→ Então, claro, o hexadecimal https://0xc0.0xa8.0x8c.0xff também é o mesmo endereço
- O CIDR (Classless Inter-Domain Routing) também afeta os endereços IP
→ A representação de classe C 192.168.140.255 pode ser escrita como http://192.168.36095 na classe B, e como http://192.11046143 na classe A
→ É por isso que ping 127.1 funciona como 127.0.0.1. Não é remoção de 0 duplicado como no IPv6, e sim o primeiro host da rede classe A 127. Ou seja, o número 1 em 24 bits
- Quantos 0 podem aparecer antes do número em cada Quad?
→ 001.002.003.004 ? 0000000001.0000000002.0000000003.000000004 ?
→ ( o Chrome também aceita http://0000000001.0000000002.0000000003.000000004 )
→ Nesse caso, esse número deve ser lido em octal ou em hexadecimal? : implementações recentes abandonaram octal/hexadecimal e tratam os 0 à esquerda como decimal
- Esse problema de 0 à esquerda também afeta o IPv6
→ 000001::00001.00002.00003.00004 = 1::1.2.3.4, ou 1::102:304
→ Como os parsers mais recentes normalmente usam bibliotecas de "parse integer", eles acabam aceitando qualquer quantidade de 0 à esquerda
Ou seja, para fazer parsing de todos os endereços IP, seria preciso considerar toda essa bagunça...
O parser do autor, porém, suporta mais ou menos só o seguinte:
-
inteiros separados por ponto no estilo clássico de v4, com quantidade ilimitada de 0 à esquerda
-
não trata notação de classe A/B nem octal/hexadecimal
-
também não trata representar tudo com um único número
uint32 -
no IPv6, aceita o formato canônico colon-hex, a abreviação com
::e também anexar IPv4 nos últimos 32 bits (esse IPv4 segue as regras acima). A quantidade de 0 à esquerda em cada campo é ilimitada
- No começo foi incluída a forma de anexar um endereço IPv4 ao final para facilitar a migração de IPv4 para IPv6, mas isso quase não aparece na prática. Então há suporte, mas o autor acha que não é muito útil
2 comentários
Nossa, que interessante! Dá para ver várias técnicas boas de distorção na hora de atacar!
Não deixo de pensar que, se precisamos usar regras tão complicadas só para representar um endereço IP, isso não acaba sendo um desperdício desnecessário de recursos computacionais ^^;;