在OSX上具有“嵌入式”范围的IPv6链路本地地址

时间:2011-05-04 18:43:24

标签: linux macos ipv6

我编写了一些简单的代码,使用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

看起来在fe80之后立即插入范围(5)的值。

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

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

请参考!

1 个答案:

答案 0 :(得分:4)

我不确定你的第二个问题,但至于你的第一个问题,是的,通常会看到这样编写的IPv6地址(例如链接本地地址),但绝对不是跨平台保持一致。原因是没有它,链接本地地址将是模糊的。

我对this other question的回答可能会有所帮助。


编辑:我刚刚意识到这个问题的微妙之处。 BSD IPv6堆栈在内部将接口索引存储在链路本地IPv6地址的第二个16位字中。这应该永远不会在线上。它实际上是RFC违规,because link-local addresses are defined to have 0 bits in this area。 (顺便说一下,为什么他们可以在这里存储额外的信息)我相信这是一个错误,范围应该以其他方式真正传达给系统的其余部分。所以你应该检查它并手工剥离它。


编辑2 :我去挖掘place in the kernel source where they set this value

  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位地址上进行最长的前缀匹配,而不是依赖某种元数据。