Por que o ping 192.168.072 (apenas 2 pontos) retorna uma resposta de 192.168.0.58?

373

Por engano, perdi o ponto de um endereço IP e digitei 192.168.072 .
Para minha surpresa, conectei-me a uma máquina em 192.168.0.58

Se eu pingar 192.168.072 , recebo respostas de 192.168.0.58 .

Por que isso acontece?

Estou em um PC com Windows em um domínio do Windows.

Se eu pingar 192.168.72 , recebo uma resposta de 192.168.0.72 , então parece que o 0 in 072 (no meu erro original) é significativo.

This question was a Super User Question of the Week.
Read the blog entry for more details or contribute to the blog yourself

    
por George Duckett 12.10.2012 / 12:26

4 respostas

568

Todo mundo está complicando demais com RFCs, classes IP e coisas do tipo. Simplesmente execute alguns testes para ver como o comando ping analisa a entrada IP pelo usuário (chaff externo removido):

> ping 1
Pinging 0.0.0.1 with 32 bytes of data:

> ping 1.2
Pinging 1.0.0.2 with 32 bytes of data:

> ping 1.2.3
Pinging 1.2.0.3 with 32 bytes of data:

> ping 1.2.3.4
Pinging 1.2.3.4 with 32 bytes of data:

> ping 1.2.3.4.5
Ping request could not find host 1.2.3.4.5. Please check the name and try again.

> ping 255
Pinging 0.0.0.255 with 32 bytes of data:

> ping 256
Pinging 0.0.1.0 with 32 bytes of data:

Como você pode ver, o comando ping (no Windows) permite usar diferentes formatos de endereço IP. Um endereço IPv4 pode ser dividido em quatro partes ("com quatro pontos") da seguinte forma: A.B.C.D e o comando ping permite que você deixe um pouco de fora, preenchendo um padrão de 0 da seguinte forma:

1 part  (ping A)       : 0.0.0.A
2 parts (ping A.B)     : A.0.0.B
3 parts (ping A.B.C)   : A.B.0.C
4 parts (ping A.B.C.D) : A.B.C.D

Se você fornecer apenas uma única parte, se ela for menor que 255 (o máximo de um octeto), ela será tratada como um octeto como acima, mas se for maior que 255, ela será convertida e rolada para o próximo campo (ou seja, mod 256 ).

Existem alguns casos extremos, como fornecer mais de quatro partes, que parecem não funcionar (por exemplo, o ping do IP de google.com não funcionará para 0.74.125.226.4 ou 74.125.226.4.0 ).

Você também pode usar a notação hexadecimal em forma quadriculada e plana pontilhada, mas deve formatá-la com 0x pré-pendente para cada octeto.


Portanto, existem várias maneiras de representar um endereço IP (IPv4). Você pode usar o formato quádruplo plano ou pontilhado (ou pontilhado-triplo, pontilhado-duplo ou até mesmo pontilhado-único), e para cada um, você pode usar (ou mesmo misturar e combinar) decimal, octal e hexadecimal. Por exemplo, você pode efetuar ping de google.com das seguintes maneiras:

  • google.com (nome de domínio)
  • 74.125.226.4 (decimal pontuado)
  • 1249763844 (decimal fixo)
  • 0112.0175.0342.0004 (octal pontilhado)
  • 011237361004 (octal plano)
  • 0x4A.0x7D.0xE2.0x04 (hexadecimais pontilhadas)
  • 0x4A7DE204 (hexa plana)
  • 74.0175.0xe2.4 (ಠ_ಠ)

(Ainda bem que o suporte à notação binária não foi adicionado!)


Aplicativo :

No seu caso, o ping 192.168.072 usa o terceiro formato da tabela acima ( A.B.0.C ), portanto, você está pingando 192.168.0.072 . Além disso, como você tem um zero à esquerda na última parte, ele é tratado como octal, que em decimal é 58.

Mistério solucionado.


Observe que, embora o comando ping do Windows permita uma variedade tão grande de formatos para a entrada e interprete formatos não-padrão das maneiras vistas, isso não significa necessariamente que você pode usar esses formatos em todos os lugares. Alguns programas podem forçá-lo a fornecer todas as quatro partes de um quadrilátero pontilhado, outros podem não permitir misturar e combinar decimal e octal, e assim por diante.

Além disso, os endereços IPv6 complicam ainda mais a lógica de análise e a aceitabilidade do formato de entrada.


Adendo :

syss apontou que, se você usar um caractere inválido em um dos números (por exemplo, 8 ou 9 ao usar octal, g no modo hexadecimal etc.), então ping é inteligente o suficiente para reconhecer isso e interpretá-lo como uma string (-al? -ic?) URL em vez de um endereço IP numérico.

(Como alguém que teve inúmeros aneurismas e ataques cardíacos tentando escrever código supostamente “simples” para acomodar o número exponencialmente explosivo de permutações de valores de dados, eu aprecio que - parece - processar corretamente todos as variações de entrada, neste caso, pelo menos 3 1 +3 2 +3 3 +3 4 = 120 variações.)

Portanto, ao especificar 010.020.030.040 enviará ping 8.16.24.32 conforme o esperado, passar 010.020.030.080 para ping será tratado como um URL em vez de um endereço IP, como foo.bar.baz.com , o que poderia (mas infelizmente não) existir. Em outras palavras, ele tenta fazer ping no subdomínio 010 no subdomínio 020 no domínio 030 no domínio de nível superior 080 . No entanto, como 080 não é um TLD válido (como .com , .net e seus amigos), a conexão falha logo no primeiro passo.

O mesmo acontece com 090.010.010.010 , em que o caractere inválido está em um octeto diferente. Da mesma forma, 0xf.0xf.0xf.0xf pings 15.15.15.15 , mas 0xh1.0x1.0xg0.0f falha.

Ah, bem, acho que é isso que você recebe por não ser fluente em várias bases de números.

Provavelmente, é mais fácil e seguro apenas usar sempre endereços quad-com quatro pontos ("40q"? "quaddy-quad"? "cutie-q"?).

Então vá em frente e aprenda algumas bases numéricas . Você poderá se mostrar e ser a vida das festas e, como dizem, há 10 tipos de pessoas: aquelas que conhecem o binário e as que não conhecem.

Não vamos nem pensar sobre endereços IPv6; Eu acho que eles são um dos 111 selos !!!

    
por 12.10.2012 / 19:06
147

Existem duas razões para isso:

Primeiro, um prefixo "0" indica um número octal . Desde oct (072) = dec (58), 192.168.072 = 192.168.58.

Em segundo lugar, o penúltimo 0 pode ser eliminado dos endereços IP como um abreviada . 127.0.1 é interpretado como 127.0.0.1 e, no seu caso, 192.168.58 é interpretado como 192.168.0.58.

    
por 12.10.2012 / 12:39
98

Além do importante ponto de @ neu242 sobre a notação octal e a observação de que os endereços IP podem ser encurtados, a outra parte crítica é saber como os endereços IP abreviados são interpretados.

Alguém poderia ingenuamente adivinhar que, se alguns dos quatro números estiverem faltando, o analisador adicionará bytes preenchidos com zero ao final (ou ao início) da sequência de bytes. Mas isso não corresponde ao comportamento relatado pelo OP: 192.168.072 foi analisado como 192.168. 0 .58, não como 192.168.58. 0 , nem 0 .192.168.58.

Aparentemente, o ping do Windows e do Linux (a versão que você tentou e as que eu tentei) usam algo equivalente a inet_aton () para analisar o argumento do endereço IP. A página man do inet_aton () diz:

The address supplied in cp can have one of the following forms:

 a.b.c.d   Each of the four numeric parts specifies a byte of the address; the
           bytes are assigned in left-to-right order to produce the binary
           address.

 a.b.c     Parts a and b specify the first two bytes of the binary address.
           Part c is interpreted as a 16-bit value that defines the rightmost
           two bytes of the binary address.  This notation is suitable for
           specifying (outmoded) Class B network addresses.

 a.b       Part a specifies the first byte of the binary address.  Part b is
           interpreted as a 24-bit value that defines the rightmost three bytes
           of the binary address.  This notation is suitable for specifying
           (outmoded) Class C network addresses.

 a         The value a is interpreted as a 32-bit value that is stored directly
            into the binary address without any byte rearrangement.

Então, você tem isso ... 192.168.072 ajusta o padrão abc, então o 072 (após a análise como um número octal) foi interpretado como um valor de 16 bits que define os 2 bytes mais à direita do endereço binário , equivalente a 0.58 .

As regras acima são equivalentes a dizer que, se algum dos quatro números estiverem faltando, os bytes preenchidos com zero necessários serão adicionados imediatamente antes do último número dado ... não no final nem em o começo da cadeia de bytes. (Expressar desta maneira funciona se o último número dado for menor que 256).

Observe que versões mais recentes do ping podem não permitir esse tipo de atalho, nem a interpretação octal. O código-fonte 2010 para iputils (incluindo ping) que eu encontrei usa inet_pton () ao invés de inet_aton () para analisar o endereço IP argumento. A página de manual de inet_pton () diz:

Unlike inet_aton(3) and inet_addr(3), inet_pton() supports IPv6 addresses. On the other hand, inet_pton() only accepts IPv4 addresses in dotted-decimal notation, whereas inet_aton(3) and inet_addr(3) allow the more general numbers-and-dots notation (hexadecimal and octal number formats, and formats that don't require all four bytes to be explicitly written).

    
por 12.10.2012 / 17:33
25

Você tem que considerar também que um ip pode ser representado por inteiros adicionados juntos em significância à sua posição.

192.168.0.58 is :
  192 * 256^3
+ 168 * 256^2
+   0 * 256^1
+  58 * 256^0

Aqui está o legal:

192.168.58 será 192.168.0.58 porque

    0 * 256^1 
+  58 * 256^0 
=  58

192.11010106 também será 192.168.0.58 porque

  168 * 256^2 
+   0 * 256^1 
+  58 * 256^0 
= 11010106

3232235578 também será 192.168.0.58 porque

  192 * 256^3 
+ 168 * 256^2 
+   0 * 256^1 
+  58 * 256^0 
= 3232235578
    
por 12.10.2012 / 15:57