Browsed by
Tag: local

linux环境中getnameinfo的问题

linux环境中getnameinfo的问题

在linux环境下获取本地IP地址的方法,通常都是先getifaddrs获取当前计算机中所有的接口信息,然后循环调用getnameinfo获取各接口的IP地址。

这是网络上常见的描述方式。在IPv4组网时,没有任何问题。但是在IPv6组网(获取IPv6地址)时,出现了问题。由该函数返回的IP地址字符串中包含了当前接口的名称,例如以下返回值:

fe80::5a94:6bff:fe48:4cec%wlan1

如果想获得纯粹的IPv6地址,应当通过接口地址信息,调用inet_ntop来转换IP地址为字符串,如下处理:

char ipstr[512]={0};
sockaddr_in6* sockaddr_ipv6=reinterpret_cast<sockaddr_in6*>(ifa->ifa_addr);
inet_ntop(AF_INET6,&sockaddr_ipv6->sin6_addr,ipstr,sizeof(ipstr));

此时获取的IP地址字符串信息就不再包含当前接口的名称:

fe80::5a94:6bff:fe48:4cec

IPv6地址带接口名称实际是“zone identifier (区域标识)”,在RFC6874规范中有相应的定义。

2014-06-08 updated:

在Linux系统中,要使用ping6命令来ping IPv6的地址,并且要求带上接口索引。例如如果只是ping IPv6地址,会返回以下错误:

ping6 fe80::a00:27ff:fe37:a9d0
connect: Invalid argument

正确的使用方法如下所示:

ping6 fe80::a00:27ff:fe37:a9d0%eth0