如何将链路本地地址绑定到IPv6套接字上

12

这个问题可以看作是我之前发布的那个问题的姐妹问题。当你想要将链路本地地址绑定到IPv6套接字时,需要设置sockaddr_in6结构体的sin6_scope_id字段,这非常繁琐。我想知道是否有人可以提供遵循良好实践的解决方案。

3个回答

14

IPv6的本地链接地址在节点上不是唯一的,它只对NIC而言是唯一的,这就是为什么您必须指定范围标识符的原因。换句话说,使用完全相同的IPv6地址拥有多个适配器是完全有效的。

这意味着您应该将范围标识符或适当的文本形式(%eth0,%1)作为输入传递给getaddrinfo()

一种方法是输入IPv6本地链接地址,枚举接口,如果只有一个匹配,则使用该接口,如果有多个匹配,则退出并获取用户指定完整形式的接口列表。


链路本地地址由其路由前缀和接口的 MAC 地址组成。因此,如果同一主机上有多个适配器可用,则每个网络适配器都具有不同的链路本地地址。 - zeekvfu
1
@Zind,你错误地假设每个接口都有唯一的MAC地址。可以看看Sun硬件作为反例。 - Steve-o

4

对于IPv6链路本地地址(fe80::/10前缀),sockaddr_in6结构体中的sin6_scope_id成员是接口号,可以通过以下方式获取该数字:

if_nametoindex(const char *ifname);

3
问题只有在硬编码链接本地地址时才会出现,这对于非平凡的应用程序来说并不是一个实际的解决方案。
否则,您应该从 getifaddrs() 获取您的 sockaddr 来绑定,这将为您填写范围 ID(例如,您可以允许用户指定接口名称,然后通过 getifaddrs() 返回的列表搜索与该接口关联的链接本地地址)。

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