我正在使用.NET Framework类来获取我的计算机的IP地址。

Dns.GetHostAddresses(Dns.GetHostName())


我有一个VirtualBox适配器,它同时具有IPv4和IPv6地址。使用.NET代码,我将IPv6地址作为fe80::71a3:2b00:ddd3:753f%16

注意%16结尾吗?

但是,如果我使用WMI进行查询,则得到的地址为'fe80 :: 71a3:2b00:ddd3:753f'

所以,%16有什么特殊的意义?

编辑:

我对此有更多观察。他们与斯蒂芬·詹宁斯在回答中所说的非常吻合。

我安装了Vmware来查看它发出的IPv6地址。地址为:
fe80 :: 3dd0:7f8e:57b7:34d5%19

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

很显然, %之后的数字不是十六进制表示形式。我使用Wmi检查了网络适配器的所有可用属性,发现数字与每个网络适配器的InterfaceIndex属性完全相同。根据MSDN,它唯一地标识每个网络适配器,并且此属性是在Vista中引入的。

令我困惑的是,为什么IPAddress类允许您以这种格式创建一个ip地址,除非它是有效的。答案由斯蒂芬提供。该数字是作用域ID。 IPAddress具有接受地址和作用域ID的构造函数。

哦,所有这三个网络适配器都是本地链接。通过ipconfig

酷确认。真有趣!

评论

在你问之前我也不知道那是什么。我今天也学到了一些有关IPv6的东西(我们是个书呆子)。

@Stephen,所以您以前使用过ipv6吗?我为您很快将它钉住而感到惊讶。在这里发布问题之前,我已经搜索了很长时间。干得好!

搜索“ ipv6地址百分比”为我找到了所需的名称,然后从那里进行搜索并尝试弄清混乱的技术文档,这花费了最多的时间。我了解了IPv6想要完成的工作,但是它有很多新概念,我还没有深入研究和理解。这是一个,没有什么比尝试向其他人更好的理解了。

另一种表示法可能是fe80:10(0x0010为16)。在使用本地链接的IPv6地址时,我在浏览器中使用了该地址,但是我不确定100%是否符合标准。 (在浏览器中使用URL中的百分比是混乱的;实际上,我根本无法使用它。)

#1 楼

“%”后面的数字是作用域ID。

IPv6至少定义了三个地址可访问性范围:


全局可寻址。这是您的ISP提供给您的IPv6地址。可以在公共Internet上使用。
本地链接。这类似于169.254.X.X范围。这是计算机分配给自己的地址,以便于进行本地通信。这些地址不会在全球范围内唯一地路由,因为它们不是全局唯一的。
本地节点。这是标识本地接口的地址,类似于127.0.0.1。基本上,这是地址:: 1。

Microsoft已发布了这篇文章,描述了IPv6寻址,这是我发现的最混乱的文章。该文章表明您的地址中存在作用域ID,这意味着它是本地链接地址。您也可以说它是链接本地的,因为地址以fe80开头。

关于此主题的清晰,简单易懂的信息似乎很少见,因此我根据以下内容将其放在一起我对RFC 4007和其他信息的最佳理解。

一台计算机可以有多个链接本地地址,每个地址都有不同的范围。范围ID指示该地址用于哪个范围。例如,假设一台计算机有两个NIC的情况,每个NIC在不同的网络上都有一个本地链接地址。如果您尝试将内容发送到以fe80开头的另一个地址,计算机将如何知道要发送哪个NIC?范围ID似乎是解决此问题的方法。

评论


谢谢!编辑了我的问题,以添加我在等待答案时偶然观察到的其他内容。当我来发布它们时,我很惊讶地看到您的回答证实了观​​察结果:)

–阿米特·乔治(Amith George)
2010-1-23在23:10

好答案。让我看看我是否完全理解这一点。因此,具有两个NIC的设备可以连接到两个不同的路由器,并被分配相同的DHCP地址fe80 :: 42。此外,路由器具有相同的地址fe80 :: 1。现在,可以使用fe80 :: 1%X来区分路由器,但是fe80 :: 42%X对客户端没有什么用,对吗?

–user123444555621
2012年11月27日在8:27

@ Pumbaa80客户端将向fe80 :: 1%1发送消息以到达连接到NIC#1的路由器,并且将向fe80 :: 1%2发送消息到达连接到NIC#2的路由器。顺便说一句,本地链接地址是由主机自动配置的,而不是通过DHCP配置的,因此它可能不会为其两个NIC分配相同的IP。还请记住,本地链接地址不可路由,因此通常您不会将消息发送到路由器,而是会在两个主机之间发送消息。

–斯蒂芬·詹宁斯(Stephen Jennings)
2012年11月28日在6:33

通过实验,似乎至少对于某些命令(例如ping,tracert。

–马特·威尔基
2012年12月30日5:23在

很好的答案。仅提及范围ID为零是很特殊的,并且似乎表明一种特定于实现的算法,该算法从具有该IP范围的接口列表中选择一个范围ID。

– Arran Cudbard-Bell
15年11月7日在20:22

#2 楼

前缀为fe80 :: / 64的IPv6地址是链接本地地址,该地址是通过将该前缀与网络设备的硬件地址(在您的示例中为71a3:2b00:ddd3:753f)组合而构造的。 (IPv4中的模拟为169.254.0.0/16。)由于前缀对于计算机上的所有本地链接地址都是相同的,所以路由有时可能需要知道您所指的是哪个接口。这就是百分比之后的数字,即区域索引。具体情况取决于操作系统:在Windows上,%16是接口号16;在Windows上,接口号是16。例如,在Linux上,您可能会看到类似%eth0的内容。

某些工具或API会认为此区域索引对于它们的用途而言并不重要或隐含。例如,在Linux上,ifconfig工具没有显示它,因为很明显地址属于哪个接口。但通常应考虑到它。

#3 楼

%后的字符(在您的示例中为数字)是“区域ID”。 (“区域ID”是用于识别的信息,有助于识别要使用的网卡。
它看起来像网卡的名称,或者只是一个数字。)

那些字符用于标识“网络接口”,人们通常将其称为“网卡”。例如,它可以帮助确定数据包是使用有线以太网卡还是无线Wi-Fi适配器。

我猜您正在使用Microsoft Windows。它使用数字作为区域ID。尽管Microsoft的文档指出了不同类型的区域ID(我将在此答案后面讨论),但对于本地链接的地址(在fe80 :: / 64中),“区域ID”是网卡的“接口索引”。

作为比较,类似Unix的系统可以在%符号后使用字母。例如:fe80::71a3:2b00:ddd3:753f%eth0

在这种情况下,区域ID eth0与操作系统通常用来标识网卡的名称匹配。

在Microsoft Windows中,您可以通过使用检查路由表的命令行之一来获取(数字)区域ID的列表。我更喜欢“ 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的地址将指向与“区域ID” 14相关的网卡,该地址恰好是我的Realtek PCIe GBE系列控制器。 (“ GBE”是指千兆以太网。)

(您还可以看到许多Microsoft Windows版本使用的这些“接口索引”值,例如:“ WMIC NICCONFIG GET Caption,InterfaceIndex,IPAddress /FORMAT:LIST”。 PowerShell应该记住在每个逗号之前使用反引号。)

现在,这是棘手的部分:如果要ping远程地址,可能需要使用远程系统的IPv6地址,但要使用本地系统的“区域ID”。因此,例如,如果我使用的是计算机A,并且我将本地IP6地址fe80 :: 1附加到接口号14,并且我想ping计算机B,并且它将本地IPv6地址附加到fe80 :: 2。它的接口号16,那么这就是我要使用的接口:

ping fe80::2%14

所以ping命令会将ICMPv6数据包发送到远程IPv6地址(fe80 :: 2) ,它属于远程计算机,并且将使用接口区域ID 14来执行此操作。区域ID 14是我正在使用的系统中的数字,而不是远程系统中的数字。因此,远程系统的地址和指定的区域ID来自不同的计算机。

现在,让我们看一下为什么这可能是必要的。

如果我要ping Google的IPv6地址(在我撰写此答案时为2607:f8b0:400a:802 :: 200e),然后路由表将检查哪个网卡处理以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:”开头(尽管其中许多零都被折叠成双冒号) )。 RFC 4291第2.4节还描述了这些地址以“ fe80:”开头的事实。

如果您尝试ping远程系统(例如,“ 2607:f8b0:400a:802”),通常的过程通常是找出地址所属的网络或子网,方法是查看地址开头的位。然后,这些位用于确定如何路由流量。

但是,该过程不适用于IPv6链路本地地址,因为每个(运行,活动)网络接口都有一个子网中以“ / 64”作为子网前缀/大小的,以“ fe80:”开头的链接本地地址。如果您使用的是笔记本电脑,则可能会发现以太网卡和Wi-Fi适配器都应该具有这样的IPv6地址。

现在,将ping发送到fe80时: :2,您希望您的计算机将该数据包发送出正确的网卡。如果您有一台连接到有线网络的打印机,则不想使用不会导致流量到达打印机的网络路径/路由将流量发送出Wi-Fi卡。而且,如果您尝试使用Wi-Fi卡与无线设备进行通信,则您不希望流量流出以太网卡。

解决方案是让您指定哪个网络设备您要使用流量。因此,这就是区域ID的目的。

答案更新:



此答案的原始版本(恰好是我提供的答案中评分较高的答案)最初使用的是“接口标识符”一词,而不是“区域ID”。


我认为术语“接口标识符”只是我个人所用,并且基于术语“接口索引”,Microsoft Windows使用该术语来标识特定的网卡。但是,由于“接口ID”一词的选择并不理想,因为IETF RFC文档已将该术语用于其他用途:


RFC 1884:“ IP版本6寻址架构”将该短语用于IPv6地址末尾的某些位。 (在一些不同的示例中,位数似乎有所不同,但是该标识符通常基于网卡的MAC-48地址。)


RFC 5453:保留的IPv6接口标识符说道(早期),“ IPv6单播地址由两部分组成:子网前缀和
标识子网前缀内唯一接口的接口标识符(IID)。”




术语“区域ID”来自RFC 4007:“ IPv6范围内的地址体系结构”,第11节,“文本表示”(尤其是小节) 11.2)使用术语“ zone_id”。尽管我认为这样的IETF RFC最具权威性,但我同时也遇到了Microsoft Windows Server 2003文档:“了解IPv6的更新”,PDF第11页(印刷第7页)将其称为“区域标识符(ID)”,
,称为范围ID”。它给出了一个示例,其中fe80 :: / 64范围中的“区域ID”“是连接到包含目标地址的链接的接口的接口索引”,但与fec0 :: / 48范围中的示例不同。 “区域ID”“是包含目标地址的组织站点的站点ID。”



当我遇到IETF RFC使用的不同术语时,我决定立即更新此流行的答案,使其更符合这样一套更为正式的标准。 (尽管初始版本对书面内容有帮助,但我希望我的文档与以前已存在的官方IETF RFC标准在IPv6地址上记录的相同短语有所不同。因此,这是2020年1月19日更新的主要原因。)



除了将“接口标识符”更新为“区域ID”外,其他较小的更改发生在2020年1月19日更新中:


添加了WMIC命令以获取索引标识符(在Microsoft Windows中)


地址中的错字(表示为fd80而不是fe80)是固定的


进行细微调整,目的是使某些文本变得更加容易


添加了有关技术文档的超链接。 (实际上,此类超链接主要包含在本节中,该超链接描述了此答案的各个部分的更新方式。)






评论


好吧,重新阅读彼得·艾森特劳特的答案后,看来他在技术上是正确的。希望我的细节能使您更加清楚。我不同意斯蒂芬·詹宁斯的答案,因为该答案使“作用域ID”看起来像“链接本地”标识为范围。但是,两个不同的网络接口都可以是“本地链接”,但是它们将不使用相同的“作用域”(按照编号列表中显示的示例)。相反,我说这些数字标识网络的“接口”。

– TOOGAM
16年4月24日在4:27