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