Dlaczego pingowanie 192.168.072 (tylko 2 kropki) zwraca odpowiedź z 192.168.0.58?

379

Przez pomyłkę przegapiłem kropkę adresu IP i wpisałem 192.168.072.
Ku mojemu zaskoczeniu podłączyłem się do maszyny pod adresem192.168.0.58

Jeśli pinguję 192.168.072, otrzymuję odpowiedzi od 192.168.0.58.

Dlaczego to?


Jestem na komputerze z systemem Windows w domenie Windows.


Jeśli pinguję 192.168.72, otrzymuję odpowiedź 192.168.0.72, więc wygląda na to, że znacznik 0in 072(w moim pierwotnym błędzie) jest znaczący.


To pytanie było pytaniem superużytkownika tygodnia .
Przeczytać wpis w blogu więcej szczegółów lub przyczynić się do bloga samemu

George Duckett
źródło
2
Co ciekawe, dokładnie to samo dzieje się w Linuksie: ping 192.168.072drukuje PING 192.168.072 (192.168.0.58) 56(84) bytes of data.[...].
Ślimak mechaniczny
9
jeszcze bardziej losowe jest to, że masz maszynę, 192.168.0.58aby uzyskać odpowiedź. Jakie są tego szanse?
James Mertz,
3
@KronoS nie jest tak dziwne, jeśli jesteś w sieci szkolnej lub firmowej. Niektóre serwery DHCP podają adresy w kolejności rosnącej i większość z nich będzie używana.
Taum,
5
192.168.0.58upłynął limit czasu dla mnie .. czy wszystkie żądania ping mogły w jakiś sposób powalić serwer ?!
iamserious

Odpowiedzi:

570

Wszyscy nadmiernie komplikują to za pomocą RFC, klas IP i tym podobnych. Wystarczy uruchomić kilka testów, aby zobaczyć, w jaki sposób pingpolecenie analizuje dane wejściowe IP użytkownika (usunięte zewnętrzne plewy):

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

Jak widać, pingpolecenie (w systemie Windows) pozwala używać różnych formatów adresów IP. Adres IPv4 można podzielić na cztery części („kropkowane-kwadraty”) w następujący sposób:, A.B.C.Da pingpolecenie pozwala ci je pominąć, wypełniając następujące wartości domyślne 0:

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

Jeśli podasz tylko jedną część, to jeśli jest ona mniejsza niż 255 (maksymalna dla oktetu), jest traktowana jak oktet jak powyżej, ale jeśli jest większa niż 255, to jest konwertowana i przenoszona do następnego pola (tj mod 256.).

Istnieje kilka przypadków krawędzi, takie jak dostarczanie więcej niż cztery części nie wydają się działać (np pingowanie google.com„s IP nie będzie działać albo 0.74.125.226.4albo 74.125.226.4.0).

Możesz także użyć notacji szesnastkowej zarówno w formie kropkowanej, jak i płaskiej, ale musisz ją sformatować, oczekując 0xna każdy oktet.


Istnieje wiele sposobów reprezentowania adresu IP (IPv4). Możesz użyć formatu płaskiego lub czterokrotnie z kropką (lub potrójnego z kropkami, podwójnego z kropkami lub nawet pojedynczego z kropkami), a dla każdego z nich możesz użyć (lub nawet mieszać i dopasowywać) dziesiętny, ósemkowy i szesnastkowy. Na przykład możesz pingować google.comna następujące sposoby:

  • google.com  (Nazwa domeny)
  • 74.125.226.4  (kropka dziesiętna)
  • 1249763844  (ułamek dziesiętny)
  • 0112.0175.0342.0004  (kropkowany ósemkowy)
  • 011237361004  (płaskie ósemki)
  • 0x4A.0x7D.0xE2.0x04  (kropkowany hex)
  • 0x4A7DE204  (płaski hex)
  • 74.0175.0xe2.4  (ಠ_ಠ)

(Dzięki Bogu, że obsługa notacji binarnych nie została dodana!)


Zastosowanie :

W twoim przypadku ping 192.168.072używa trzeciego formatu z powyższej tabeli ( A.B.0.C), więc faktycznie pingujesz 192.168.0.072. Ponadto, ponieważ w ostatnim fragmencie znajduje się zero wiodące, traktowane jest ono jako ósemkowe, które w systemie dziesiętnym wynosi 58.

Zagadka rozwiązana.


Zauważ, że chociaż pingpolecenie systemu Windows pozwala na tak szeroką gamę formatów wejściowych i interpretuje niestandardowe formaty w widzialny sposób, niekoniecznie oznacza to, że możesz używać takich formatów wszędzie. Niektóre programy mogą wymusić podanie wszystkich czterech części kwadratu kropkowanego, inne mogą nie zezwalać na mieszanie i dopasowywanie liczb dziesiętnych i ósemkowych itd.

Ponadto adresy IPv6 dodatkowo komplikują logikę analizy i akceptację formatu wejściowego.


Dodatek :

syss zwrócił uwagę, że jeśli użyjesz nieprawidłowego znaku w jednej z liczb (np. a 8lub 9przy użyciu ósemki, gw trybie szesnastkowym itp.), to pingjest wystarczająco inteligentny, aby rozpoznać to i zinterpretować jako ciąg (-al? -ic?) URL zamiast liczbowego adresu IP.

(Jako ktoś, kto miał wiele tętniaków i zawałów serca, próbując napisać rzekomo „prosty” kod, aby pomieścić wykładniczo eksplodującą liczbę permutacji wartości danych, doceniam, że - wydaje się - poprawnie przetwarza wszystkie wariacje wejściowe; w tym przypadek, co najmniej 3 1 +3 2 +3 3 +3 4 = 120 odmian).

Tak więc, podczas określania polecenia 010.020.030.040ping 8.16.24.32zgodnie z oczekiwaniami, przekazywanie 010.020.030.080do pingbędzie traktowane jak adres URL zamiast adresu IP - taki, foo.bar.baz.comktóry mógłby (ale niestety nie istnieje). Innymi słowy, próbuje pingować poddomenę 010w subdomenie 020w domenie 030w domenie najwyższego poziomu 080. Jednak, ponieważ 080nie jest to prawidłowy TLD (jak .com, .neti ich kumple), połączenie nie powiedzie się w prawo na pierwszym etapie.

To samo dzieje się, 090.010.010.010gdy nieprawidłowy znak znajduje się w innym oktecie. Podobnie 0xf.0xf.0xf.0xfpinguje 15.15.15.15, ale 0xh1.0x1.0xg0.0fzawodzi.

No cóż, myślę, że to właśnie dostajesz za brak biegłości w wielu bazach liczb.

Prawdopodobnie łatwiej i bezpieczniej jest po prostu zawsze używać adresów z 4 kropkami („40q”? „„ Quaddy-quad ”?„ „Cutie-q”?).

Więc idź i poznaj podstawy liczb . Będziesz mógł pochwalić się i być życiem imprez, a jak mówią, istnieje 10 rodzajów ludzi: tych, którzy znają binarny i tych, którzy nie.

Załóżmy nawet nie myśleć o adresach IPv6; Myślę, że to jedna ze 111 pieczęci !!!

Synetech
źródło
39
Zbyt skomplikowane? Eksperymenty mogą być bardzo przydatne i w tym przypadku dają dobrą odpowiedź; ale bez teorii, dokumentacji lub standardów możesz przeoczyć czynnik krytyczny i go nie znać. Albo możesz określić, jak działa jedna konkretna wersja i pomylić się z 90% wdrożeń tam. Możesz też wymyślić reguły wyjaśniające wyniki eksperymentów, ale są one bardziej skomplikowane niż zamierzone reguły. W tym przypadku uważam, że zasady (dla inet_aton()) dokumentacji są prostsze pod jednym względem - brak warunków dla „poniżej / powyżej 255”.
LarsH
71
Hej, patrz! Pojawia się „informatyczna” część informatyki! (hipoteza, eksperyment, weryfikacja)
Izkata,
13
@LarsH, o to mi chodzi, że pingpolecenie (przynajmniej w systemie Windows) jest podobne do wielu programów Microsoftu (szczególnie notorycznego) IE. Stara się być zbyt wyrozumiałym i bierze wszystko, co w niego rzucisz, i próbuje to interpretować. Tak, istnieje oficjalny dokument dotyczący formatów adresów IP, ale że nie jest to pytanie o ISO i RFC, jest praktyczne, zrobiłem coś i jest to dziwne pytanie, na które można odpowiedzieć bez uciekania się (co prawda długie, suche, nudne specyfikacje techniczne) - chociaż linkowanie do nich na wypadek, gdyby PO chciał je przeczytać, jest również dobre.
Synetech,
6
Parsowanie ósemkowe z prefiksem 0 powinno być całkowicie porzucone, z wyjątkiem chmod. Otóż ​​to. To jedyny dozwolony wyjątek dla ósemki. Kropka.
James Dunne,
6
jest przydatny do konwersji RGB HEX na DEC. lol ~C:\>ping 0xffffcc Pinging 0.255.255.204 with 32 bytes of data:
wilson
147

Są dwa powody:

Po pierwsze, przedrostek „0” oznacza liczbę ósemkową . Ponieważ oct (072) = dec (58), 192.168.072 = 192.168.58.

Po drugie, od ostatniego do ostatniego 0 można usunąć z adresów IP jako skrót . 127.0.1 jest interpretowany jako 127.0.0.1, aw twoim przypadku 192.168.58 jest interpretowany jako 192.168.0.58.

neu242
źródło
7
Nie grupuje zer. W rzeczywistości traktuje każdą kropkę jako separator odpowiadający granicy następnej bajtu. Dlatego adresy IP 2130706433 i 127.0.0.1 są tymi samymi adresami.
Serge
2
a dokładniej jest to notacja z czterema kropkami w przypadku adresu IP
Guillaume86
4
Słynne wiodące zero ponownie uderzyło!
Luc M
2
to jest prawdziwa odpowiedź!
l - '' '' ----------- '' '' '' ''
2
Ta odpowiedź jest niepoprawna i myląca. Upuszczenie 0 w wersji 1.0.2.3 (1.2.3) daje inny adres IP (1.2.0.3).
sch
101

Oprócz ważnego punktu @ neu242 dotyczącego notacji ósemkowej i obserwacji, że adresy IP można skracać, drugą ważną kwestią jest znajomość interpretacji skróconych adresów IP.

Można naiwnie zgadywać, że jeśli brakuje niektórych z czterech liczb, parser dodałby bajty wypełnione zerami na końcu (lub początku) sekwencji bajtów. Ale to nie pasuje do zachowania zgłoszonego przez OP: 192.168.072 zostało przeanalizowane jako 192.168. 0 0,58, a nie jako 192.168.58. 0 , ani 0 .192.168.58.

Najwyraźniej ping i Windows i Linux (wersja, którą wypróbowałeś i te, których próbowałem) używają czegoś równoważnego inet_aton () do analizy argumentu adresu IP. Strona podręcznika dla inet_aton () mówi:

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.

Więc masz ... 192.168.072pasuje do wzorca abc, więc 072(po analizie jako liczba ósemkowa) został zinterpretowany jako 16-bitowa wartość, która definiuje skrajnie prawe 2 bajty adresu binarnego, równoważne 0.58.

Powyższe zasady są równoważne z informacją, że jeśli brakuje jednej z czterech liczb, potrzebne bajty wypełnione zerami są dodawane bezpośrednio przed podaną ostatnią liczbą ... nie na końcu ani na początku ciągu bajtów. (Wyrażenie tego w ten sposób działa, jeśli ostatni podany numer jest mniejszy niż 256.)

Zauważ, że nowsze wersje ping mogą nie dopuszczać tego rodzaju skrótów ani interpretacji ósemkowej. Kod źródłowy iputils 2010 (w tym ping), które znalazłem wykorzystuje inet_pton () zamiast inet_aton () do analizowania argumentów adresów IP. Strona podręcznika dla inet_pton () mówi:

W przeciwieństwie do inet_aton (3) i inet_addr (3), inet_pton () obsługuje adresy IPv6. Z drugiej strony, inet_pton () akceptuje tylko adresy IPv4 w notacji dziesiętnej z kropkami, podczas gdy inet_aton (3) i inet_addr (3) pozwalają na bardziej ogólną notację liczb i kropek (formaty liczb szesnastkowych i ósemkowych oraz formaty, które nie wymagają jawnego zapisu wszystkich czterech bajtów).

LarsH
źródło
12
To zdecydowanie najlepsza odpowiedź IMHO.
Josh
W systemie Windows szukasz inet_addrw Winsock.
user7116
24

Trzeba również wziąć pod uwagę, że ip może być reprezentowany przez liczby całkowite dodane razem w zależności od ich pozycji.

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

Oto fajna rzecz:

192.168.58 będzie 192.168.0.58, ponieważ

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

192.11010106 będzie również 192.168.0.58, ponieważ

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

3232235578 będzie również 192.168.0.58, ponieważ

  192 * 256^3 
+ 168 * 256^2 
+   0 * 256^1 
+  58 * 256^0 
= 3232235578
vesquam
źródło
1
„192.168.56 będzie 192.168.0.56, ponieważ 0 * 256 ^ 1 + 58 * 256 ^ 0 = 58” Jesteś pewien? Można oczekiwać, że wartość 168 zostanie pomnożona przez 256 ^ 1 w pierwszym przypadku i przez 256 ^ 2 w drugim przypadku. Podobnie 192 pomnożymy przez 256 ^ 2 vs. 256 ^ 3. Zatem 192.168.56 może = 192.168.0.56 tylko wtedy, gdy istnieją dodatkowe reguły, takie jak pomijanie zer.
LarsH,
@LarsH, myślę, że mówi się tutaj, że opiera się od lewej do prawej, w przeciwieństwie do „normalnego” liczenia, w którym wszystko opieramy na miejscu 1. Pierwsza kropka powoduje więc pomnożenie cokolwiek po jej lewej stronie przez 256 ^ 3, druga przez 256 ^ 2, trzecia przez 256. jeśli nie ma kropki po jej lewej stronie, dodaje się bez mnożenia przez 256 ^ n. 1.2.3. (1.2.3.0) różni się od 1.2.3 (1.2.0.3), jeśli dobrze rozumiem.
iX3
@ iX3: gdyby tak było, wówczas „192.168.56 będzie 192.168.0.56” byłoby niepoprawne, ponieważ w pierwszym przypadku 56 byłoby pomnożone przez 256 ^ 1, podczas gdy w drugim przypadku 56 byłoby tylko pomnożone y 256 ^ 0. A 192.168.072 PO będzie interpretowany jako 192.168.58.0 zamiast 192.168.0.58.
LarsH,
To, co nieco wprowadza w błąd, to fakt, że adres ma 0, ma trzecią cyfrę. Rozważ ten adres 192.168.1.56. Trzycyfrowa postać to 192.168.312 Ponieważ 1 * 256 ^ 1 + 56 * 256 ^ 0 to 312
vesquam 12.10
1
Kropki służą jedynie do wyznaczenia, które liczby należy pomnożyć przez jaką potęgę 256. Parser szuka pierwszej kropki i mnoży liczbę przed nią przez 256 ^ 3. Powtórz dla 2. i 3. kropki, ale odpowiednio o 256 ^ 2 i 256 ^ 1. Następnie dodaje wszystkie wyniki razem (niektóre impl. Mogą zamiast tego zachować bieżącą sumę, chociaż wynik jest taki sam). Jeśli brakuje którejkolwiek z tych kropek, to po prostu nie robi mnożenia i po prostu dodaje ostateczną liczbę do bieżącej sumy. Dlatego też 1.2.3.powoduje błąd, ponieważ analizator składni nie może znaleźć ostatniej liczby do dodania do sumy.
Justin ᚅᚔᚈᚄᚒᚔ