ip – なぜ192.168.072にpingすると192.168.0.58からの応答が返ってくるのですか?

ip ip-address ping

私は間違ってIPアドレスのドットを見落としてしまい、192.168.072と入力してしまいました。 驚いたことに、私は192.168.0.58のマシンに接続しました

192.168.072をpingすると、192.168.0.58からの応答が返ってきます

なぜなんでしょうか?


WindowsドメインのPCでやってます


192.168.72をpingすると192.168.0.72からの応答が返ってくるので、0720(私の元のミス)が大きいようです


この質問は、今週のスーパーユーザーの質問でした。 詳細については、ブログのエントリーを読むか、ブログに自分で投稿する

  380  George Duckett  2012-10-12


ベストアンサー

誰もがRFCやIPクラスなどで複雑にしすぎています。ping コマンドがユーザの入力した IP をどのように解析するかを見るために、いくつかのテストを実行してみてください (不要なチャフは取り除かれています)

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

ご覧のように、pingコマンド(Windowsの場合)では、異なるIPアドレス形式を使用することができます。IPv4 アドレスは、以下のように 4 つの部分 (“dotted-quad”) に分割することができます。A.B.C.D のように、ping コマンドでは一部を省略することができ、以下のように 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

単一の部分のみを供給する場合、それが255以下(オクテットの最大値)であれば、上記のようにオクテットとして扱われますが、255より大きい場合は変換されて次のフィールドにロールオーバーされます(つまり、mod 256

4つ以上の部分を提供してもうまくいかないようなエッジケースがいくつかあります(例えば、google.comのIPにpingを打つと0.74.125.226.474.125.226.4.0ではうまくいかないなど)

また、16進数表記をドットクォートとフラットの両方で使用することもできますが、各オクテットに0xを前置してフォーマットする必要があります

このように、(IPv4)IPアドレスを表現する方法はたくさんあります。フラットまたはドットクォード(またはドットトリプル、ドットダブル、またはドットシングル)形式を使用することができ、それぞれについて、10進数、8進数、16進数を使用することができます(または混ぜて使用することもできます)。例えば、google.com は以下のように ping することができます

  • google.com  (domain name)
  • 74.125.226.4  (dotted decimal)
  • 1249763844  (flat decimal)
  • 0112.0175.0342.0004  (dotted octal)
  • 011237361004  (flat octal)
  • 0x4A.0x7D.0xE2.0x04  (dotted hex)
  • 0x4A7DE204  (flat hex)
  • 74.0175.0xe2.4  (ಠ_ಠ)

(バイナリ表記のサポートが追加されていないのはありがたい!)

アプリケーションです

あなたの場合、192.168.072にpingすると、上の表の3番目のフォーマット(A.B.0.C)が使われますので、実際には192.168.0.072にpingしていることになります。さらに、最後の部分に先頭のゼロがあるので、8進数として扱われ、10進数では58となります

Mystery solved.

Windows ping コマンドは、入力のための多種多様なフォーマットを可能にし、非標準フォーマットを見てきたような方法で解釈しますが、必ずしもどこでもそのようなフォーマットを使用できるというわけではないことに注意してください。プログラムによっては、ドットクォードの4つの部分をすべて提供することを強制されるかもしれませんし、10進数と8進数の混合とマッチングを許可しないプログラムもあります

また、IPv6アドレスは、解析ロジックと入力フォーマットの許容性をさらに複雑にしています

補遺です

syssが指摘していた、数字の中に無効な文字を使った場合(例えば、八進数を使う場合は89、16進数を使う場合はgなど)、pingはそれを認識して、数字のIPアドレスではなく、文字列(-al? -ic?)のURLとして解釈することができます

(データ値の組み合わせの数が指数関数的に爆発的に増加していることに対応するために、おそらく「シンプルな」コードを書こうとして、何度も動脈瘤や心臓発作を起こしてきた者として、私はそれが入力されたすべてのバリエーションを正しく処理するように見えることを評価します

そのため、010.020.030.040を指定すると期待通りに8.16.24.32をpingしますが、010.020.030.080pingに渡すと、IPアドレスのようなfoo.bar.baz.comが存在する可能性がある(しかし悲しいことに存在しない)代わりにURLのように扱われます。つまり、トップレベルドメイン080でサブドメイン010020030030にpingしようとします。しかし、080 は有効な TLD ではないので (.com, .net, およびそれらの仲間のように)、接続は最初のステップですぐに失敗します

無効な文字が別のオクテットにある場合、090.010.010.010でも同じことが起こる。同様に、0xf.0xf.0xf.0xf15.15.15.15をpingしますが、0xh1.0x1.0xg0.0fは失敗します

まあ、複数の数字ベースに流暢に対応できないからこうなるんだろうな

常に4-dotted-quad(“40q”? “quaddy-quad”? “cutie-q”? )アドレスを使うようにした方が簡単で安全かもしれません

だから行って、learn some number basesあなたはで誇示し、パーティーの人生であることができるでしょうし、彼らが言うように、人々の10種類があります:バイナリを知っている人とそうでない人

IPv6アドレスのことも考えずに、111のシールの1つだと思います!

571  Synetech  2012-10-12


その理由は2つあります

まず、’0’という接頭辞は、オクタル数を示しています。oct(072) = dec(58)なので、192.168.072 = 192.168.58となります

第二に、その2番目から最後の0は、shorthandとしてIPアドレスから落とすことができます。127.0.0.1は127.0.0.1と解釈され、あなたの場合は192.168.58は192.168.0.58と解釈されます

148  neu242  2012-10-12


八進法についての @neu242 さんの重要な指摘や、IP アドレスは短縮できるという観測に加えて、もう一つの重要な部分は、短縮された IP アドレスがどのように解釈されるかを知っていることです

4つの数字のうちのいくつかが欠けている場合、パーサはバイト列の末尾(または先頭)にゼロフィルバイトを追加するのではないかと簡単に推測することができます。しかし、これは OP が報告した動作とは一致しません。192.168.072 は 192.168.0.58 として解析され、192.168.58.0 でも 0.192.168.58 でもありません

どうやら Windows と Linux の ping (あなたが試したバージョンと私が試したバージョン) は、IP アドレスの引数を解析するために inet_aton() と同等のものを使用しているようです。inet_aton()のmanページにはこう書かれています

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.

そこで、以下のようになります。192.168.072 は a.b.c パターンに適合するので、072 (8 進数として解析した後) は、バイナリアドレスの右端 2 バイトを定義する 16 ビットの値として解釈され、0.58 に相当します

上記のルールは、4つの数字のどれかが欠けている場合、必要なゼロフィルバイトは最後に与えられた数字の直前に追加される…ということと等価です。(このように表現すると、最後に与えられた数字が256よりも小さい場合に動作します)

ping の新しいバージョンでは、この種の速記法や八進法の解釈ができないかもしれないことに注意してください。私が見つけた 2010年版の iputils のソースコード (ping を含む) では、IP アドレスの引数を解析するのに inet_aton() ではなく inet_pton() を使用しています。inet_pton() の man ページにはこう書かれています

inet_aton(3) や inet_addr(3) とは異なり、inet_pton() は IPv6 アドレスをサポートしています。一方、inet_aton(3) と inet_addr(3) は、より一般的な数字とドットの表記 (16 進数と 8 進数の形式、および 4 バイトすべてを明示的に書き込む必要のない形式) を許可しているのに対し、inet_pton() はドット十進数表記の IPv4 アドレスのみを受け付けます

102  LarsH  2012-10-12


また、ipはその位置に意味を持たせて整数を足したもので表されることも考慮しなければなりません

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

これがかっこいいんですよ

192.168.58は192.168.0.58になるから

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

192.11010106も192.168.0.58になりますから

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

3232235578も192.168.0.58になるから

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

24  vesquam  2012-10-12


タイトルとURLをコピーしました