OSX上的IPv6“嵌入式”范围本地地址

3
我已经编写了一些简单的代码,使用ioctl SIOCGIFCONF查询系统上的所有网络接口,使用inet_ntop返回找到的地址的文本表示。奇怪的是,当发现一个链路本地IPv6地址时,OSX版本的代码似乎将范围嵌入到地址中。
以下是在OSX上自动配置接口后/sbin/ifconfig中的一行:
en1: flags=8963<UP,BROADCAST,SMART,RUNNING,PROMISC,SIMPLEX,MULTICAST> mtu 1500
        ether 00:17:f2:0b:52:73 
        inet6 fe80::217:f2ff:fe0b:5273%en1 prefixlen 64 scopeid 0x5 

并且使用ioctl SIOCGIFCONF返回的IP地址:

IPv6地址:fe80:5::217:f2ff:fe0b:5273

看起来作用域值(5)是直接插入到fe80后面的。

在Linux上相同的代码返回ipv6地址而没有任何额外的数据。

我有两个问题: 1)像这样编写ipv6地址是否合法? 2)OSX行为是否在任何地方有记录?

请提供参考资料!


1
在大多数平台上,inet_ntopinet_pton不支持IPv6区域,你只能使用getnameinfogetaddrinfo - Steve-o
谢谢,Steve,我不知道这一点。我的问题仍然是:IPv6地址是否应该有区域信息?RFC4291第2.2章节中没有提及。地址的文本表示。 - Spaceghost
仅限于本地链路地址,即fe80::前缀。 - Steve-o
1个回答

4

我不确定你的第二个问题,但对于你的第一个问题,是的,经常会看到需要作用域(例如链路本地地址)的IPv6地址写成这样,但在不同平台上并不一致。原因是没有它,链路本地地址将是模棱两可的。

我的另一个问题的答案可能会有所帮助。


编辑:我刚意识到这个问题的微妙之处。BSD IPv6堆栈在链路本地IPv6地址的第2个16位字中内部存储接口索引。这应该永远不会发送到网络上。实际上,这是RFC违规行为,因为链路本地地址被定义为在此区域具有0。(这也是他们可以在此处存储额外信息的原因)我认为这是一个错误,应该以其他方式向系统的其余部分传递范围。因此,您应该检查它并手动删除它。


编辑2:我去挖出了他们设置此值的内核源代码中的位置

  466 static int
  467 in6_ifattach_linklocal(
  468         struct ifnet *ifp,
  469         struct ifnet *altifp,   /* secondary EUI64 source */
  470         struct in6_aliasreq *ifra_passed)
  471 {
      ...
  494                 ifra.ifra_addr.sin6_family = AF_INET6;
  495                 ifra.ifra_addr.sin6_len = sizeof(struct sockaddr_in6);
  496                 ifra.ifra_addr.sin6_addr.s6_addr16[0] = htons(0xfe80);
  497 #if SCOPEDROUTING
  498                 ifra.ifra_addr.sin6_addr.s6_addr16[1] = 0
  499 #else
  500                 ifra.ifra_addr.sin6_addr.s6_addr16[1] = htons(ifp->if_index); /* XXX */
  501 #endif

请注意第500行的/* XXX */。;-) 我猜这是一种临时解决方案/黑客方法,以使路由正常工作而不需要重写部分路由代码。对于链路本地地址,您需要基于源和目标接口做出路由决策。通过将if_index放在地址的那个位置,他们可能只需对128位地址执行最长前缀匹配,而无需依赖某种元数据。

谢谢,迈克。似乎路由需要范围,但它并不是地址的一部分,但没有它,地址就没有什么用处了。 - Spaceghost
@Spaceghost,是的,完全正确。还有一件事可能对您有帮助,就是在您的问题中,您说这是“自动配置接口”后的输出。这并不完全正确。当您谈论IPv6中的“自动配置”地址时,通常指的是通过路由器广告自动配置的全局单播地址。本地链接地址是规范要求的,但实际上并不符合“自动配置”的条件。 - mpontillo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接