我有一个应用程序,允许管理员指定可以从中发出Web服务请求的有效IP地址。我只需获取配置的IP地址,并将它们与传入的请求进行比较。比较两个IPv4地址是微不足道的,我认为比较两个IPv6地址也是如此。
然而,当我注意到IPv6地址稍微复杂一点时,我的网络无知开始出现。我注意到的一个问题是,如果我查看机器上的IP地址(正在查看VMWare控制台显示的IP地址)与Web请求中的IP地址(.NET中的HttpContext.Current.Request.UserHostAddress
),我注意到其中一个以%10结束,另一个以%11结束:
唯一的区别是%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()
}
答案 0 :(得分:17)
因为所有链接本地地址都在 主机有一个共同的前缀,正常 路由程序不能用于 选择出局界面时 将数据包发送到本地链路 目的地。特殊标识符, 被称为区域索引 提供额外的路由 信息;在链接本地的情况下 地址,区域索引对应 接口标识符。
当地址以文字方式书写时, 区域索引附加到 地址,以百分号分隔 “%”。区域索引的实际语法 取决于操作系统[...]
因此,这些后缀是区域指示符,它将地址与物理接口相关联。这也解释了为什么有线和无线接口之间的足够差异。例如。
为了帮助回答这个问题,我不认为后缀应该包含在任何比较中。根据定义,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)表示法。它们可以表示实际地址或网络。如果在/之前有一个零或::那么它就是一个网络。
答案 3 :(得分:0)
IPv6在IPv4中仅为128位而非32位;你应该能够进行逐字节比较。