19

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

然而,当我注意到 IPv6 地址有点复杂时,我的网络无知开始显现。我注意到的一个问题是,如果我查看机器上的 IP 地址(正在查看 VMWare 控制台显示的 IP 地址)与来自 Web 请求的 IP 地址(HttpContext.Current.Request.UserHostAddress在 .NET 中),我注意到其中一个以%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()但我正在使用 aDictionary并且我决定反对创建自己的ByteComparer.

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

4 回答 4

18

维基百科指出

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

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

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

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

比较 128 位就足够了。

于 2009-11-24T13:24:40.083 回答
4

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

这些是 IPv6区域标识符,链路本地地址,即 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;
};

您将需要比较家庭、地址和范围 ID 字段以获得完整匹配。

于 2010-02-06T04:15:13.633 回答
1

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

CIDR 符号

于 2009-11-24T04:55:19.250 回答
-1

IPv6 只是 128 位与 IPv4 中的 32 位;您应该能够进行逐字节比较。

于 2009-11-24T03:28:44.963 回答