Perché il ping 192.168.072 (solo 2 punti) restituisce una risposta da 192.168.0.58?


378

Ho erroneamente perso il punto di un indirizzo IP e digitato 192.168.072.
Con mia sorpresa mi sono collegato a una macchina a192.168.0.58

Se eseguo il ping 192.168.072ricevo risposte da 192.168.0.58.

Perchè è questo?


Sono su un PC Windows su un dominio Windows.


Se eseguo il ping 192.168.72ricevo una risposta da 192.168.0.72, quindi sembra che 0in 072(nel mio errore originale) sia significativo.


Questa domanda era una domanda super utente della settimana .
Leggi la voce del blog per maggiori dettagli o contribuisci tu stesso al blog



2
È interessante notare che su Linux succede esattamente la stessa cosa: ping 192.168.072stampe PING 192.168.072 (192.168.0.58) 56(84) bytes of data.[...].
Lumaca meccanica,

9
ciò che è ancora più casuale è che avevi una macchina 192.168.0.58per ottenere una risposta. Quali sono le probabilità di ciò?
James Mertz,

3
@KronoS in realtà non è così strano se sei su una rete scolastica o aziendale. Alcuni server DHCP forniranno gli indirizzi in ordine crescente e la maggior parte verrà utilizzata.
Taum,

5
192.168.0.58è il timeout per me .. tutte le richieste di ping possono in qualche modo aver eliminato il server ?!
iamserious

Risposte:


569

Tutti lo stanno complicando eccessivamente con RFC, classi IP e simili. Basta eseguire alcuni test per vedere in che modo il pingcomando analizza l'input IP da parte dell'utente (chaff estraneo rimosso):

> 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:

Come puoi vedere, il pingcomando (in Windows) ti consente di utilizzare diversi formati di indirizzi IP. Un indirizzo IPv4 può essere suddiviso in quattro parti ("punteggiato-quad") in questo modo: A.B.C.De il pingcomando consente di lasciarne un po ', compilando un valore predefinito 0come segue:

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 si fornisce solo una singola parte, quindi se è inferiore a 255 (il massimo per un ottetto), viene trattato come un ottetto come sopra, ma se è maggiore di 255, viene convertito e spostato nel campo successivo (cioè, mod 256).

Ci sono alcuni casi limite come fornire più di quattro parti che non sembrano funzionare (ad esempio, google.coml'IP del ping non funzionerà per nessuno dei due 0.74.125.226.4o 74.125.226.4.0).

È inoltre possibile utilizzare la notazione esadecimale sia in forma tratteggiata quadrata che piatta, ma è necessario formattarla pre-in attesa 0xdi ciascun ottetto.


Quindi, ci sono molti modi per rappresentare un indirizzo IP (IPv4). Puoi usare il formato flat o tratteggiato quad (o tratteggiato triplo, tratteggiato doppio o persino tratteggiato singolo) e, per ognuno, puoi usare (o anche mescolare e abbinare) decimale, ottale ed esadecimale. Ad esempio, è possibile eseguire il ping google.comnei seguenti modi:

  • google.com  (nome del dominio)
  • 74.125.226.4  (punto decimale)
  • 1249763844  (decimale piatto)
  • 0112.0175.0342.0004  (punteggiato ottale)
  • 011237361004  (ottale piatto)
  • 0x4A.0x7D.0xE2.0x04  (esagono punteggiato)
  • 0x4A7DE204  (esagono piatto)
  • 74.0175.0xe2.4  (ಠ_ಠ)

(Meno male che il supporto per la notazione binaria non è stato aggiunto!)


Applicazione :

Nel tuo caso, il ping 192.168.072utilizza il terzo formato nella tabella sopra ( A.B.0.C), quindi stai effettivamente eseguendo il ping 192.168.0.072. Inoltre, poiché hai uno zero iniziale sull'ultima parte, viene trattato come ottale, che in decimale è 58.

Mistero risolto.


Si noti che mentre il pingcomando Windows consente una così ampia varietà di formati per l'input e interpreta i formati non standard nei modi visti, ciò non significa necessariamente che è possibile utilizzare tali formati ovunque. Alcuni programmi potrebbero costringerti a fornire tutte e quattro le parti di un quadrato tratteggiato, altri potrebbero non consentire il missaggio e l'abbinamento di decimali e ottali e così via.

Inoltre, gli indirizzi IPv6 complicano ulteriormente la logica di analisi e l'accettabilità del formato di input.


Addendum :

syss ha sottolineato che se si utilizza un carattere non valido in uno dei numeri (ad esempio, 8o 9quando si utilizza ottale, a gin modalità esadecimale, ecc.), pingè abbastanza intelligente da riconoscerlo e interpretarlo come una stringa (-al? -ic?) URL anziché come indirizzo IP numerico.

(Dato che qualcuno che ha avuto numerosi aneurismi e attacchi di cuore cercando di scrivere un codice apparentemente "semplice" per soddisfare il numero esponenzialmente esponenziale di permutazioni dei valori dei dati, apprezzo che - sembra - elaborare correttamente tutte le variazioni di input; in questo caso, almeno 3 1 +3 2 +3 3 +3 4 = 120 variazioni.)

Pertanto, pur specificando il 010.020.030.040ping 8.16.24.32come previsto, il passaggio 010.020.030.080a pingverrà trattato come un URL anziché come un indirizzo IP, come se foo.bar.baz.compotesse (ma purtroppo non esistesse) esistere. In altre parole, tenta di eseguire il ping del sottodominio 010sul sottodominio 020sul dominio 030nel dominio di primo livello 080. Tuttavia, poiché 080non è un TLD valido (come .com, .nete i loro amici), la connessione non riesce proprio al primo passo.

La stessa cosa accade 090.010.010.010quando il personaggio non valido si trova in un ottetto diverso. Allo stesso modo, 0xf.0xf.0xf.0xfping 15.15.15.15, ma 0xh1.0x1.0xg0.0ffallisce.

Vabbè, immagino sia quello che ottieni per non essere fluente in più basi di numeri.

Probabilmente è più facile e sicuro assicurarsi di usare sempre gli indirizzi a 4 punte quadrate ("40q"? "Quaddy-quad"? "Cutie-q"?).

Quindi vai avanti e impara alcune basi di numeri . Sarai in grado di esibirti e di essere la vita delle feste e, come si suol dire, ci sono 10 tipi di persone: quelli che conoscono i binari e quelli che non lo fanno.

Non pensiamo nemmeno agli indirizzi IPv6; Penso che siano uno dei 111 sigilli !!!


39
Overcomplicating? La sperimentazione può essere molto utile e in questo caso ha prodotto una buona risposta; ma senza una teoria, documentazione o standard, potresti perdere un fattore critico e non saperlo. Oppure potresti determinare come funziona una versione particolare e sbagliare circa il 90% delle implementazioni là fuori. Oppure potresti trovare delle regole che spiegano i risultati dei tuoi esperimenti ma sono più complicate delle regole previste. In questo caso, penso che le regole della documentazione (per inet_aton()) siano più semplici da un punto di vista - senza condizioni per "under / over 255".
LarsH,

71
Ehi guarda! La parte "scientifica" di Informatica fa la sua comparsa! (ipotizza, sperimenta, verifica)
Izkata,

13
@LarsH, questo è il mio punto però, che il pingcomando (almeno su Windows) è come molti dei programmi di Microsoft (specialmente il famigerato) IE. Cerca di essere troppo indulgente e di prendere qualsiasi cosa gli lanci e cerca di interpretarlo. Sì, esiste un documento ufficiale sui formati degli indirizzi IP, ma che questa non è una domanda su ISO e RFC, è pratico, ho fatto qualcosa ed è una strana domanda a cui è possibile rispondere senza ricorrere a (certamente lungo, asciutto, noioso specifiche tecniche) - sebbene sia utile collegarsi ad essi nel caso in cui l'OP voglia leggerli.
Synetech,

6
L'analisi ottale con prefisso 0 deve essere completamente abbandonata, tranne per chmod. Questo è tutto. Questa è l'unica eccezione per ottale consentita. Periodo.
James Dunne,

6
è utile per la conversione da RGB HEX a DEC. lol ~C:\>ping 0xffffcc Pinging 0.255.255.204 with 32 bytes of data:
wilson,

147

Ci sono due ragioni per questo:

Innanzitutto, un prefisso '0' indica un numero ottale . Da ott (072) = dec (58), 192.168.072 = 192.168.58.

In secondo luogo, il penultimo 0 può essere eliminato dagli indirizzi IP come scorciatoia . 127.0.1 viene interpretato come 127.0.0.1 e nel tuo caso 192.168.58 viene interpretato come 192.168.0.58.


7
Non raggruppa gli zeri. In realtà tratta ogni punto come un separatore corrispondente al limite di byte successivo. Pertanto, gli indirizzi IP 2130706433 e 127.0.0.1 sono gli stessi indirizzi.
Serge,

2
più precisamente è la notazione quadrettata tratteggiata nel caso di un indirizzo IP
Guillaume86

4
Il famoso zero iniziale ha colpito ancora una volta!
Luc M,

2
ora questa è la vera risposta!
l --''''''--------- '' '' '' '' '' ''

2
Quella risposta è errata e fuorviante. Il rilascio di uno 0 in 1.0.2.3 (1.2.3) fornisce un indirizzo IP diverso (1.2.0.3).
sch

101

Oltre all'importante punto di @ neu242 sulla notazione ottale e all'osservazione che gli indirizzi IP possono essere abbreviati, l'altro pezzo critico è sapere come vengono interpretati gli indirizzi IP abbreviati.

Si potrebbe ingenuamente supporre che se mancano alcuni dei quattro numeri, il parser aggiungerebbe byte pieni di zero alla fine (o all'inizio) della sequenza di byte. Ma questo non corrisponde al comportamento riportato dall'OP: 192.168.072 è stato analizzato come 192.168. 0 .58, non come 192.168.58. 0 , né 0 .192.168.58.

Apparentemente il ping di Windows e Linux (la versione che hai provato e quelli che ho provato) usano qualcosa di equivalente a inet_aton () per analizzare l'argomento dell'indirizzo IP. La pagina man di inet_aton () dice:

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.

Quindi il gioco è fatto ... si 192.168.072adatta al modello abc, quindi il 072(dopo aver analizzato come un numero ottale) è stato interpretato come un valore a 16 bit che definisce i 2 byte più a destra dell'indirizzo binario, equivalente a 0.58.

Le regole di cui sopra equivalgono a dire che se manca uno dei quattro numeri, i byte a zero riempiti necessari vengono aggiunti immediatamente prima dell'ultimo numero indicato ... non alla fine né all'inizio della stringa di byte. (Esprimerlo in questo modo funziona se l'ultimo numero indicato è inferiore a 256.)

Si noti che le versioni più recenti di ping potrebbero non consentire questo tipo di stenografia, né l'interpretazione ottale. Il codice sorgente 2010 per iputils (incluso ping) che ho trovato utilizza inet_pton () anziché inet_aton () per analizzare l'argomento dell'indirizzo IP. La pagina man di inet_pton () dice:

A differenza di inet_aton (3) e inet_addr (3), inet_pton () supporta gli indirizzi IPv6. D'altra parte, inet_pton () accetta solo indirizzi IPv4 in notazione decimale puntata, mentre inet_aton (3) e inet_addr (3) consentono la notazione di numeri e punti più generale (formati numerici esadecimali e ottali e formati che non ' t richiede che tutti e quattro i byte siano scritti in modo esplicito).


12
Questa è di gran lunga la migliore risposta IMHO.
Josh,

Su Windows che stai cercando inet_addrin Winsock.
user7116,

24

Devi anche considerare che un IP può essere rappresentato da numeri interi sommati in significato alla loro posizione.

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

Ecco la cosa bella:

192.168.58 sarà 192.168.0.58 perché

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

192.11010106 sarà anche 192.168.0.58 perché

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

3232235578 sarà anche 192.168.0.58 perché

  192 * 256^3 
+ 168 * 256^2 
+   0 * 256^1 
+  58 * 256^0 
= 3232235578

1
"192.168.56 sarà 192.168.0.56 perché 0 * 256 ^ 1 + 58 * 256 ^ 0 = 58" Sei sicuro? Si prevede che 168 venga moltiplicato per 256 ^ 1 nel primo caso e per 256 ^ 2 nel secondo caso. Allo stesso modo 192 verrebbe moltiplicato per 256 ^ 2 contro 256 ^ 3. Quindi 192.168.56 potrebbe = 192.168.0.56 solo se ci sono regole aggiuntive in atto, come la caduta di zero.
LarsH,

@LarsH, penso che ciò che viene detto qui sia che si basa da sinistra a destra, a differenza del conteggio "normale" su cui basiamo tutto dal posto dell'1. Quindi il primo punto fa sì che tutto ciò che è alla sua sinistra sia moltiplicato per 256 ^ 3, il secondo per 256 ^ 2, il terzo per 256. Se non c'è un punto a sinistra di esso, viene aggiunto senza moltiplicare per 256 ^ n. Quindi 1.2.3. (1.2.3.0) sarebbe diverso da 1.2.3 (1.2.0.3), se ho capito bene.
iX3,

@ iX3: se così fosse, allora "192.168.56 sarà 192.168.0.56" sarebbe errato, perché nel primo caso 56 verrebbe moltiplicato per 256 ^ 1, mentre nel secondo caso 56 verrebbe moltiplicato y 256 ^ 0. E il 192.168.072 del PO sarebbe interpretato come 192.168.58.0 anziché 192.168.0.58.
LarsH,

Ciò che è un po 'fuorviante è il fatto che l'indirizzo ha 0 ha la 3a cifra. Considera questo indirizzo 192.168.1.56 La forma a 3 cifre sarebbe 192.168.312 Perché 1 * 256 ^ 1 + 56 * 256 ^ 0 è 312
vesquam

1
I punti servono solo a delineare quali numeri devono essere moltiplicati per quale potenza di 256. Il parser cerca il primo punto e moltiplica il numero prima di esso per 256 ^ 3. Ripetere l'operazione per il 2o e il 3o punto, ma rispettivamente per 256 ^ 2 e 256 ^ 1. Quindi aggiunge tutti i risultati insieme (alcuni impianti potrebbero invece mantenere un totale parziale, anche se il risultato è lo stesso). Se manca uno di quei punti, semplicemente non esegue la moltiplicazione e aggiunge semplicemente il numero finale al totale parziale. Questo è anche il motivo per cui si 1.2.3.verifica un errore, perché il parser non riesce a trovare l'ultimo numero da aggiungere al totale.
Giustino
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.