为什么在IPv6地址中存在百分号“%”?


125

我正在使用这些.NET Framework类来获取机器的IP地址。

Dns.GetHostAddresses(Dns.GetHostName())

我有一个同时具有IPv4和IPv6地址的VirtualBox适配器。使用.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确认

凉。真有趣!


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

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

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

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

Answers:


134

'%'之后的数字是作用域ID。

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

  1. 全球可寻址。这是您的ISP提供给您的IPv6地址。它可以在公共Internet上使用。

  2. 本地链接。这类似于169.254.XX范围。这是计算机分配给自己的地址,以便于进行本地通信。这些地址不会在全球范围内路由,因为它们不是全局唯一的。

  3. 本地节点。这是标识本地接口的地址,类似于127.0.0.1。基本上,这是地址:: 1。

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

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

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


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

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

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

通过实验,看来尾随%nn可以对于至少一些命令,例如可以省略pingtracert
马特·威尔基

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

21

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

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


18

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

我猜您正在使用Microsoft Windows。它使用数字作为接口标识符。

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

在这种情况下,接口标识符eth0匹配网卡的名称。

在Microsoft Windows中,可以使用检查路由表的命令行之一来获取(数字)接口标识符的列表。我更喜欢“ 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操作,并且它在本地IP6上附加了fe80 :: 2 IP地址。它的接口号16,那么这就是我要使用的接口:

ping fe80::2%14

因此,该ping命令会将ICMPv6数据包发送到属于远程计算机的远程IPv6地址(fd80 :: 2),并将使用带有标识符的接口14进行操作。接口标识符14是我正在使用的系统中的数字,而不是远程系统中的数字。

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

如果我想ping Google的IPv6地址(在我编写此答案时为2607:f8b0:400a:802 :: 200e),则路由表将检查哪个网卡处理以2607:f8b0:400a开头的地址: 802。路由表将指示我的网卡没有一个直接使用2607:f8b0:400a:802开头的地址直接连接到网络,因此我的计算机最终将使用“网关”地址。如果我要连接到我所在组织的另一个网络,则可能会有一个特殊的“网关”地址,可将流量路由到专用网络。在这种情况下,我没有更具体的网关,因此我将使用IPv6“默认网关”。这就是IPv6在大多数时间的工作方式,除了本地链接地址。这也是大多数时候IPv4的工作方式。

根据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链接本地地址,因为在子网中,每个单个(运行中的,活动的)网络接口都有一个以“ fe80:”开头的链接本地地址,其子网前缀/大小为“ /”。 64“。如果您使用的是笔记本电脑,则可能会发现以太网卡和Wi-Fi适配器都应该具有这样的IPv6地址。

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

解决方案是让您指定要使用流量的网络设备。因此,这就是网络标识符的目的。


2
好吧,重新阅读彼得·艾森特劳特的答案后,看来他在技术上是正确的。希望我的细节能使您更加清楚。我不同意斯蒂芬·詹宁斯(Stephen Jennings)的回答,因为该回答看起来像“作用域ID”将“本地链接”标识为范围。但是,两个不同的网络接口都可以是“本地链接”,但是它们将不使用相同的“作用域”(按照编号列表中显示的示例)。相反,我说这些数字标识网络的“接口”。
TOOGAM '16
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.