如何确定两个IPv6地址之间的相等性?

时间:2009-11-24 03:07:29

标签: ipv6

我有一个应用程序,允许管理员指定可以从中发出Web服务请求的有效IP地址。我只需获取配置的IP地址,并将它们与传入的请求进行比较。比较两个IPv4地址是微不足道的,我认为比较两个IPv6地址也是如此。

然而,当我注意到IPv6地址稍微复杂一点时,我的网络无知开始出现。我注意到的一个问题是,如果我查看机器上的IP地址(正在查看VMWare控制台显示的IP地址)与Web请求中的IP地址(.NET中的HttpContext.Current.Request.UserHostAddress),我注意到其中一个以%10结束,另一个以%11结束:

  • ipconfig显示:fe80:8179:5576:c6d0:8b16%11
  • UserHostAddress显示:fe80 :: 8179:5576:c6d0:8b16%10

唯一的区别是%10和%11 - 给出了什么?

我还看到IPv6地址以“/”结尾,后跟2位数。在进行比较时,我应该忽略这些最后的3位数(如果存在)吗?如果是这样,我需要寻找的有效替代结局是什么?

-----------编辑-------------

以下是基于所提供答案的解决方案......

我只是存储一个“已清理”的IP地址,并将其与“已清理”的IP地址进行比较。在这里使用.NET是我擦除IP地址的方法。从性能角度来看并不是最好的,但它确实有效。我宁愿只是对GetAddressBytes()进行比较,但我使用的是Dictionary,我决定不再创建自己的ByteComparer

IPAddress incomingIp = null;
bool ipAddressParsePassed = IPAddress.TryParse(userHostAddress, out incomingIp);
if (ipAddressParsePassed)
{
    IPAddress scrubbedIp = new IPAddress(incomingIp.GetAddressBytes());
    string scrubbedIpStr = scrubbedIp.ToString()
}

4 个答案:

答案 0 :(得分:17)

Wikipedia states

  

因为所有链接本地地址都在   主机有一个共同的前缀,正常   路由程序不能用于   选择出局界面时   将数据包发送到本地链路   目的地。特殊标识符,   被称为区域索引   提供额外的路由   信息;在链接本地的情况下   地址,区域索引对应   接口标识符。

     

当地址以文字方式书写时,   区域索引附加到   地址,以百分号分隔   “%”。区域索引的实际语法   取决于操作系统[...]

因此,这些后缀是区域指示符,它将地址与物理接口相关联。这也解释了为什么有线和无线接口之间的足够差异。例如。

为了帮助回答这个问题,我不认为后缀应该包含在任何比较中。根据定义,IPv6地址是128位,后缀是严格的本地信息,在您自己的机器和它当前的操作系统之外没有意义。

比较128位就足够了。

答案 1 :(得分:3)

  

唯一的区别是%10和%11    - 什么给了?

这些是IPv6 zone identifiers,链路本地地址,即fe80前缀,仅在本地链路上保证唯一。这意味着地址fe80:8179:5576:c6d0:8b16%11和fe80 :: 8179:5576:c6d0:8b16%10可以指代不同的机器,一个必须通过接口10访问而另一个必须通过接口11访问。

查看sockaddr_in6

的定义
struct sockaddr_in6 {
  short sin6_family;
  u_short sin6_port;
  u_long sin6_flowinfo;
  struct in6_addr sin6_addr;
  u_long sin6_scope_id;
};

您需要比较family,address和scope-id字段以获得完整匹配。

答案 2 :(得分:1)

最后使用/和数字的地址使用无类别域间路由(CIDR)表示法。它们可以表示实际地址或网络。如果在/之前有一个零或::那么它就是一个网络。

CIDR notation

答案 3 :(得分:0)

IPv6在IPv4中仅为128位而非32位;你应该能够进行逐字节比较。