web-dev-qa-db-ja.com

IPv6アドレスにパーセント記号 '%'があるのはなぜですか?

私は自分のマシンのIPアドレスを取得するために.NET Frameworkクラスを使っています。

Dns.GetHostAddresses(Dns.GetHostName())

私はIPv4とIPv6の両方のアドレスを持つVirtualBoxアダプタを持っています。 .NETコードを使用して、IPv6アドレスをfe80::71a3:2b00:ddd3:753f%16として取得しています

最後の%16に注意してください?

ただし、WMIを使用して同じクエリを実行すると、アドレスは「fe80 :: 71a3:2b00:ddd3:753f」と表示されます。

それで、%16は特別な意味を持ちますか?

編集:

これについてもう少し観察したところです。そして、彼らはスティーブンジェニングスが彼の答えで言ったこととかなりよく一致します。

どのIPv6アドレスが発行されたのかを確認するために、VMwareをインストールしました。アドレスは以下のとおりです。fe80 :: 3dd0:7f8e:57b7:34d5%19

fe80 :: b059:65f4:e877:c40%20

明らかに、%の後の数字は16進数表現ではありません。 Wmiを使用してネットワークアダプタに使用できるすべてのプロパティを確認したところ、番号は各ネットワークアダプタのInterfaceIndexプロパティとまったく同じであることがわかりました。 MSDN に従って、各ネットワークアダプタを一意に識別します。このプロパティはVistaで導入されました。

まだ私を混乱させていたのは、IPAddressクラスが有効でない限り、その形式でIPアドレスを作成することを許可するのはなぜなのかということです。答えはスティーブンによって提供されました。番号はスコープIDです。 IPAddressには、アドレスとスコープIDを受け取るコンストラクタがあります。

ああ、そしてこれら3つのネットワークアダプタはすべてリンクローカルでした。 ipconfigで確認しました

クール。おもしろかった!

120
Amith George

'%'の後の番号はスコープIDです。

IPv6では、アドレスに対して少なくとも3つの到達範囲を定義しています。

  1. グローバルにアドレス指定可能これはあなたのISPからあなたに与えられたIPv6アドレスです。それは公衆インターネット上で使用することが可能です。

  2. リンクローカル。これは169.254.X.Xの範囲に似ています。ローカル通信を容易にするためにコンピュータが自分自身を割り当てるアドレスです。これらのアドレスは、グローバルに一意ではないため、公衆インターネット上で回覧されることはありません。

  3. ノードローカル。これは、127.0.0.1と同様に、ローカルインタフェースを識別するアドレスです。基本的に、これはアドレス:: 1です。

マイクロソフトは、IPv6アドレス指定 について説明したこの記事を公開しました。この記事は、あなたのアドレスにスコープIDがあるということは、それが リンクローカルアドレス であることを意味していることを示しています。アドレスがfe80で始まるため、リンクローカルであると言うこともできます。

このトピックに関する明確で単純に理解される情報は稀に思われるので、私は RFC 4007 についての私の理解に基づいてこれをまとめます。そして他の情報はそこにあります。

コンピュータは、それぞれが異なるスコープを持つ複数のリンクローカルアドレスを持つことができます。スコープIDは、アドレスがどのスコープのものかを示します。たとえば、それぞれが異なるネットワーク上にリンクローカルアドレスを持つ2つのNICを持つコンピュータのシナリオを想像してください。 fe80で始まるアドレスに何かを送信しようとした場合、どのNICに送信するのか、コンピュータはどのように判断するのでしょうか。これを解決するのがスコープIDです。

130

プレフィックスfe80 ::/64の付いたIPv6アドレスは、そのプレフィックスとネットワークデバイスのハードウェアアドレス(例では71a3:2b00:ddd3:753f)を組み合わせて構成されたリンクローカルアドレスです。 (IPv4のアナログは169.254.0.0/16です。)プレフィックスはマシン上のすべてのリンクローカルアドレスで同じであるため、ルーティングではどのインタフェースを参照しているのかを知る必要がある場合があります。そしてそれが、ゾーンインデックスと呼ばれるパーセントの後の数字が指定するものです。詳細はオペレーティングシステムによって異なります。Windowsでは、%16はインターフェイス番号16です。例えばLinuxでは、%eth0のようになるでしょう。

一部のツールまたはAPIは、このゾーンインデックスをその目的上重要ではないか暗黙的と見なします。例えば、Linuxではifconfigツールはそれを表示しません。アドレスがどのインターフェースに属しているのかが明らかだからです。しかし一般的にそれは考慮に入れられるべきです。

20

%の後の文字(あなたの例では偶然の数字)はインタフェース識別子です。これらの文字は、人々がしばしば「ネットワークカード」と呼ぶ「ネットワークインターフェース」を識別するために使用されます。たとえば、パケットが有線イーサネットカードを使用するのか、ワイヤレスWi-Fiアダプタを使用するのかを判断するのに役立ちます。

Microsoft Windowsを使用していると思います。インターフェイス識別子として番号を使用します。

比較のポイントとして、Unix系システムは%記号の後に文字を使用するかもしれません。例:fe80::71a3:2b00:ddd3:753f%eth0

その場合、インタフェース識別子eth0はネットワークカードの名前と一致します。

Microsoft Windowsでは、ルーティングテーブルを確認するコマンドラインの1つを使用して、(数値の)インタフェース識別子のリストを取得できます。私は "netstat -nr"が他のオペレーティングシステムでも動作するので好むが、Microsoft Windowsも "route print"をサポートする。報告された結果の出力は、おそらく画面いっぱいになるでしょう。そのため、あなたがもっとパイプしない限り、スクロールバックする準備をしてください。

例:私のシステムでは:

=========================================================================== Interface List 14...5c f9 dd 6d 98 b8 ......Realtek PCIe GBE Family Controller 12...e0 06 e6 7e fc 4e ......Bluetooth Device (Personal Area Network) 1...........................Software Loopback Interface 1 13...00 00 00 00 00 00 00 e0 Microsoft ISATAP Adapter 15...00 00 00 00 00 00 00 e0 Microsoft ISATAP Adapter #2 ===========================================================================

この場合、fe80 :: 71a3:2b00:ddd3:753f%14のようなアドレスは、私のRealtek PCIe GBEファミリコントローラを参照します。 「GBE」はギガビットイーサネットを指します。

ここで注意が必要なのは、リモートアドレスをpingしたい場合、リモートシステムのIPv6アドレスを使用する必要があるかもしれませんが、ローカルシステムのインタフェース識別子を使用することです。したがって、たとえば、コンピュータAを使用していて、インタフェース番号14にローカルのIPv6アドレス(fe80 :: 1)が接続されていて、コンピュータBに対してpingを実行したい場合、ローカルのIPv6アドレスとしてfe80 :: 2が割り当てられます。そのインターフェース番号16、これは私が使用するものです:

ping fe80::2%14

そのため、pingコマンドは、リモートコンピュータに属するリモートIPv6アドレス(fd80 :: 2)にICMPv6パケットを送信し、それを行うには識別子付きのインタフェース14を使用します。 Interface Identifier 14は、リモートシステムではなく、使用しているシステムの番号です。

それでは、なぜこれが必要なのかを見てみましょう。

GoogleのIPv6アドレス(この回答を書いた時点では2607:f8b0:400a:802 :: 200e)にpingを送信したい場合、ルーティングテーブルは2607:f8b0:400aで始まるアドレスを処理するネットワークカードを確認します。 802。ルーティングテーブルは、私のネットワークカードが2607:f8b0:400a:802で始まるアドレスを使ってネットワークに直接接続されていないことを示しているので、私のコンピュータは "ゲートウェイ"アドレスを使うことになります。私が働いている組織の一部である別のネットワークに接続していたなら、私はトラフィックをプライベートネットワークにルーティングする特別な「ゲートウェイ」アドレスを持っているかもしれません。この場合、私はより具体的なゲートウェイを持っていないので、私はIPv6 "default gateway"を使います。それが、リンクローカルアドレスを除いて、IPv6がほとんどの場合動作する方法です。これはまたIPv4がほとんどの時間働いた方法です。 (プロセス全体を記述すると、この記述がさらに長くなる可能性があるため、IPv6サブネットサイズを/ 64と仮定して、この例を単純化しました。)

RFC 4291のセクション2.8 によると、IPv6を使用するすべてのコンピュータは、すべてのネットワークインタフェースにリンクローカルアドレスを割り当てる必要があります。 RFC 4291のセクション2.5.6 には、リンクローカルアドレスを先頭に付ける必要があるビットが示されています。これにより、リンクローカルアドレスは "fe80:0000"で始まります。 :0000:0000: "(これらのゼロの多くは二重コロンに折りたたまれますが)それらのアドレスが "fe80:"で始まるという事実は、 RFC 4291のセクション2.4 でも記述されています。

あなたがリモートシステム(例えば "2607:f8b0:400a:802")をpingしようとするなら、一般的なプロセスは通常アドレスがその一部であるネットワークまたはサブネットを見つけることです、それはビットを見ることによって行われますアドレスの先頭に次に、それらのビットを使用してトラフィックのルーティング方法を決定します。

ただし、このプロセスはIPv6リンクローカルアドレスに対しては機能しません。すべての(動作可能な、アクティブな)ネットワークインターフェイスに、サブネットプレフィックス/サイズ "/"を使用するサブネット上の "fe80:"で始まるリンクローカルアドレスがあるためです。 64 "ラップトップを使用している場合は、イーサネットカードとWi-Fiアダプタの両方にそのようなIPv6アドレスがあると予想されることがわかります。

今、あなたがあなたのpingをfe80 :: 2に送るとき、あなたはあなたのコンピュータにそのパケットを正しいネットワークカードから送り出させたいです。有線ネットワークに接続されているプリンタを使用している場合は、トラフィックがプリンタに到達しないようなネットワークパス/ルートを使用して、Wi-Fiカードからトラフィックを送信したくない場合があります。また、Wi-Fiカードを使ってワイヤレスデバイスと通信しようとしているのであれば、トラフィックがイーサネットカードから出るのを避けたいのです。

解決策は、トラフィックに使用させるネットワークデバイスを指定することです。つまり、それがネットワーク識別子の目的です。

16
TOOGAM