私のマシンのIPアドレスを取得するために.NET Framework
クラスを使用しています
Dns.GetHostAddresses(Dns.GetHostName())
私は、IPv4とIPv6の両方のアドレスを持つVirtualBoxアダプタを持っています。.NET コードを使用して、IPv6 アドレスを fe80::71a3:2b00:ddd3:753f%16
として取得しています
最後の%16に注目してください
しかし、WMI
で同様の問い合わせをすると、アドレスは’fe80::71a3:2b00:dd3:753f’となります
では、%16は何か特別な意味があるのでしょうか?
Edit:
これについて、もう少し観察してみました。スティーブン・ジェニングスの回答とよく一致しています
Vmwareをインストールして、どのIPv6アドレスを発行したのか確認してみました。アドレスは fe80::3dd0:7f8e:57b7:34d5%19 でした
fe80::b059:65f4:e877:c40%20
明らかに、% の後の数字は 16 進数ではありません。Wmi を使ってネットワークアダプタで利用できるすべてのプロパティをチェックしてみたところ、各ネットワークアダプタの InterfaceIndex プロパティと全く同じ数字が表示されていることがわかりました。MSDN にあるように、これは各ネットワークアダプタを一意に識別するもので、このプロパティは Vista で導入されました
それでも混乱したのは、IPAddressクラスが有効でない限り、なぜそのフォーマットでIPアドレスを作成できるのかということでした。その答えはStephen氏が提供してくれました。数字はスコープIDです。IPAddressには、アドレスとスコープIDを受け付けるコンストラクタがあります
あ、あと、この3つのネットワークアダプタはすべてリンクローカルでした。ipconfigで確認しました
かっこいい面白かった!
140 Amith George 2010-01-23
‘%’ の後の数字はスコープ ID です
IPv6では、アドレスに対して少なくとも3つの到達性スコープが定義されています
グローバルにアドレスを指定できます。これは、ISPから与えられたIPv6アドレスです。公共のインターネット上で利用することができます
リンクローカル。これは 169.254.X.X の範囲に似ています。これは、ローカル通信を容易にするためにコンピュータが自分自身に割り当てるアドレスです。これらのアドレスは、グローバルに一意ではないため、パブリックインターネット上でルーティングされることはありません
ノードローカル。127.0.0.0.1と同様に、ローカルインターフェースを識別するアドレスです。基本的には ::1 のアドレスです
MicrosoftがIPv6アドレッシングについて説明しているこの記事を公開していますが、私が見つけた記事の中では最も混乱を招くことはありませんでした。記事によると、アドレスにスコープIDがあるということは、リンクローカルアドレスであることを意味しています。また、アドレスが fe80
で始まるので、リンクローカルであることもわかります
このトピックに関する明確で分かりやすい情報は稀なので、RFC 4007やその他の情報についての私の最善の理解に基づいて、残りの部分をまとめています
コンピュータは複数のリンクローカルアドレスを持つことができ、それぞれが異なるスコープを持つことができます。スコープ ID は、そのアドレスがどのスコープに対応しているかを示します。例えば、異なるネットワーク上のリンクローカルアドレスを持つ 2 つの NIC を持つコンピュータのシナリオを想像してみましょう。もし、fe80で始まる別のアドレスに何かを送ろうとした場合、コンピュータはどのNICで送ればいいのかをどのようにして知ることができるでしょうか?スコープ ID がこれを解決してくれるようです
145 Stephen Jennings 2010-01-23
fe80::/64というプレフィックスを持つIPv6アドレスは、そのプレフィックスとネットワークデバイスのハードウェアアドレスを組み合わせて構築されたリンクローカルアドレスで、例では71a3:2b00:dd3:753fとなっています。(IPv4のアナログは169.254.0.0.0/16です。)プレフィックスはマシン上のすべてのリンクローカルアドレスで同じなので、ルーティングはどのインターフェイスを参照しているのかを知る必要がある場合があります。これは、ゾーンインデックスと呼ばれるパーセントの後の数字が指定するものです。詳細はオペレーティングシステムに依存します。Windowsでは、%16
はインターフェイス番号16で、例えばLinuxでは%eth0
のように表示されます
ツールやAPIによっては、このゾーンインデックスを重要ではないと考えたり、その目的のために暗黙のうちに表示したりするものがあります。例えば、Linux の ifconfig
ツールでは、アドレスがどのインターフェイスに属しているかは明らかなので、ゾーンインデックスは表示されません。しかし、一般的には考慮すべきです
26 Peter Eisentraut 2010-01-23
の後の文字(あなたの例ではたまたま数字になっています)は「ゾーンID」です。(「ゾーンID」は、どのネットワークカードを使用するかを識別するためのテキストです。ネットワークカードの名前のように見えるかもしれないし、単に数字であるかもしれない。)
これらの文字は「ネットワーク・インターフェース」を識別するために使用され、人々はしばしば「ネットワーク・カード」と呼んでいます。例えば、パケットが有線イーサネットカードを使用しているのか、無線Wi-Fiアダプタを使用しているのかを判断するのに役立ちます
Microsoft Windowsを使っているのではないでしょうか。それはゾーンIDとして数字を使っています。マイクロソフトのドキュメントでは、異なるタイプのゾーンIDを示していますが(この回答では後述します)、リンクローカルアドレス(fe80::/64の場合)の場合、「ゾーンID」はネットワークカードの「インターフェースインデックス」になります
比較のポイントとして、Unix 系のシステムでは % 記号の後に文字を使うことがあります。fe80::71a3:2b00:ddd3:753f%eth0
この場合、ゾーンID eth0
は、オペレーティングシステムがネットワークカードを識別するために通常使用する名前と一致する
Microsoft Windowsでは、ルーティングテーブルをチェックするコマンドラインのいずれかを使用することで、(数字の)ゾーンIDのリストを取得することができます。他のオペレーティングシステムでも動作するので、私は”netstat -nr
“を好むが、Microsoft Windowsは”route print
“もサポートしている。結果として報告される出力は、おそらく1画面以上の長さになるだろうから、それ以上にパイプする場合を除いて、スクロールバックする準備をしておく
例えば、私のシステムでは
=========================================================================== 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
のようなアドレスは、”zone ID” 14
に関連するネットワークカードを参照することになります。(「GBE」はギガビットイーサネットを指します)
(Microsoft Windows の多くのバージョンで使用されているこれらの “インターフェイスインデックス” の値は、次のようなもので見ることができます。“WMIC NICCONFIG GET Caption,InterfaceIndex,IPAddress /FORMAT:LIST
”.PowerShell でこれを試している人は、各コンマの前にバッククォートを使うことを忘れないようにしてください)
さて、ここからが厄介なところです。リモートアドレスにpingしたい場合、リモートシステムのIPv6アドレスを使用する必要がありますが、ローカルシステムの「ゾーンID」を使用する必要があります。例えば、私がコンピュータAを使用していて、インターフェイス番号14にfe80::1というローカルIPv6アドレスを持っていて、コンピュータBにpingしたい場合、コンピュータBはインターフェイス番号16にfe80::2というローカルIPv6アドレスを持っているので、私が使用するのはこのようになります
ping fe80::2%14
そこで、ping
コマンドは、ICMPv6パケットをリモートコンピュータに属するリモートIPv6アドレス(fe80::2)に送信し、その際にInterfaceゾーンID 14を使用します。ゾーンID 14は、私が使っているシステムの番号で、リモートシステムの番号ではありません。つまり、リモートシステムのアドレスと指定されたゾーンIDは、別のコンピュータから来ているということです
では、なぜこれが必要なのかを見てみましょう
Google の IPv6 アドレス(この回答を書いた時点では 2607:f8b0:400a:802::200e)を ping したい場合、ルーティングテーブルはどのネットワークカードが 2607:f8b0:400a:802 で始まるアドレスを扱うかをチェックします。 ルーティングテーブルは、2607:f8b0:400a:802 で始まるアドレスを使ってネットワークに直接接続しているネットワークカードがないことを示しているので、私のコンピュータは結局「ゲートウェイ」アドレスを使うことになります。私が働いている組織の一部である別のネットワークに接続している場合、私はプライベートネットワークにトラフィックをルーティングする特別な「ゲートウェイ」アドレスを持っているかもしれません。この場合、私はより特定のゲートウェイを持っていないので、IPv6の「デフォルトゲートウェイ」を使用します。これが、リンクローカルアドレスを除いて、ほとんどの場合、IPv6がどのように動作するかです。これはまた、IPv4がほとんどの場合にどのように動作していたかを示しています。(この例では、IPv6のサブネットサイズを/64と仮定して単純化していますが、全体のプロセスを説明するとこの説明がさらに長くなってしまうためです)
RFC 4291 セクション 2.8によると、IPv6 を使用するすべてのコンピュータは、すべてのネットワークインタフェースにリンクローカルアドレスを割り当てる必要があります。RFC 4291セクション2.5.6は、リンクローカルアドレスが “fe80:0000:0000:0000:0000:0000: “で始まる原因となる、リンクローカルアドレスが必ず “fe80:0000:0000:0000:0000: “で始まらなければならないビットを示しています(ただし、これらのゼロの多くは二重コロンに折りたたまれます)。これらのアドレスが “fe80:” で始まるという事実は、RFC 4291 セクション 2.4にも記述されています
リモートシステム(例: “2607:f8b0:400a:802”)を ping しようとした場合、一般的なプロセスは通常、アドレスの先頭のビットを見て、そのアドレスが属するネットワークやサブネットを特定することです。そして、これらのビットはトラフィックをどのようにルーティングするかを決定するために使用されます
しかし、このプロセスはIPv6リンクローカルアドレスでは機能しません。なぜなら、すべての(運用中のアクティブな)ネットワークインターフェースは、サブネットのプレフィックス/サイズが「/64」のサブネット上に「fe80:」で始まるリンクローカルアドレスを持っているからです。ラップトップを使用している場合、イーサネットカードとWi-Fiアダプタの両方がこのようなIPv6アドレスを持っていることが予想されます
さて,fe80::2 に ping を送るとき,コンピュータが正しいネットワークカードからパケットを送るようにしたいと思います.有線ネットワークに接続されているプリンタを持っている場合は、Wi-Fi カードからトラフィックを送信したくないでしょう。また、Wi-Fiカードを使用してワイヤレスデバイスと通信しようとしている場合は、イーサネットカードからトラフィックを送り出したくありません
解決策としては、どのネットワークデバイスにトラフィックを使用させたいかを指定してもらうことです。それがゾーンIDの目的なんですね
回答の更新。
- この回答の元のバージョン (たまたま私が提供した回答の中ではかなり評価の高い回答でした) では、最初は「ゾーン ID」の代わりに「インターフェイス識別子」という用語を使用していました。
- 「インターフェイス識別子」という用語は、単に私が個人的に作り上げた用語であり、Microsoft Windows が特定のネットワークカードを識別するために使用する「インターフェイスインデックス」という用語に基づいていたものだと思います。しかし、「インターフェイス ID」という用語は、IETF RFC 文書では、この用語を別の何かに使用しているため、理想的ではない選択であることが判明しました。
- RFC 1884.
- RFC 1884: “IP Version 6 Addressing Architecture”は、IPv6アドレスの末尾のいくつかのビットに対してこのフレーズを使用しています。(ビット数はいくつかの異なる例で異なるようですが、この識別子は通常、ネットワークカードの MAC-48 アドレスに基づいていました)。
- RFC 5453: Reserved IPv6 Interface Identifiers は (初期の段階で) 「IPv6 ユニキャストアドレスは、サブネットプレフィックスと、サブネットプレフィックス内の一意のインターフェイスを識別するインターフェイス識別子 (IID) の 2 つの部分から構成されています」と述べています。
- 「ゾーン ID」という用語は、RFC 4007.”IPv6 Scoped Address Architecture」の第11節「Textual Representation」 (特に第11.2節)では「zone_id」という用語が使われていました。このようなIETFのRFCが最も権威あるものと考えていますが、Microsoft Windows Server 2003 Documentationにも出くわしました。IPv6 を理解するための更新、PDF 11 ページ (印刷された 7 ページ)では、これを「ゾーン識別子 (ID)、スコープ ID としても知られている」と呼んでいます。fe80::/64 の範囲の「ゾーン ID」が「宛先アドレスを含むリンクに接続されているインターフェイスのインターフェイス インデックス」である例を示していますが、fec0::/48 の範囲の「ゾーン ID」が「宛先アドレスを含む組織サイトのサイト ID」である例とは異なります。
IETF RFC で使用されている別の用語に偶然出くわしたので、私はこの人気のある回答をすぐに更新して、このようなより公式な標準に準拠することにしました。(最初のバージョンは書かれている通りに役に立ちましたが、私は、同じフレーズがIPv6アドレスに関する公式の既存のIETF RFC標準でどのように文書化されているかとは異なる文書を作成することを好まなかったのです。そのため、これが2020年1月19日の更新の主な理由でした)。
- RFC 1884.
- 「インターフェイス識別子」を「ゾーン ID」に更新した以外にも、2020 年 1 月 19 日の更新では、他のマイナーな変更が行われました。
- インデックス識別子を取得するための WMIC コマンドを追加しました (Microsoft Windows では)
- アドレスのタイプミス (fe80 の代わりに fd80 と言っていました) が修正されました
- いくつかのテキストを少しだけ簡単に明確にすることを目的としたマイナーな調整です。(実際には、そのようなハイパーリンクは主に、この回答のさまざまな部分がどのように更新されたかを説明するこのセクションに含まれています)。
21 TOOGAM 2016-04-24
- 「インターフェイス識別子」という用語は、単に私が個人的に作り上げた用語であり、Microsoft Windows が特定のネットワークカードを識別するために使用する「インターフェイスインデックス」という用語に基づいていたものだと思います。しかし、「インターフェイス ID」という用語は、IETF RFC 文書では、この用語を別の何かに使用しているため、理想的ではない選択であることが判明しました。