问题描述
我使用getifaddrs()和inet_ntop()来获取系统中的IP地址。当系统被设置到IPv6的地址返回在缩短的版本(使用::为零)。有没有什么办法,以该地址扩展为一个完整的吗?
这是code我使用的:
结构ifaddrs * myaddrs,* IFA;
无效* in_addr等;
焦炭BUF [64];如果(getifaddrs(安培;!myaddrs)= 0)
{
PERROR(getifaddrs);
出口(1);
}对于(IFA = myaddrs;!IFA = NULL; IFA = IFA-GT&; ifa_next)
{
如果(IFA-GT&; ifa_addr == NULL)
继续;
如果((IFA-GT&;!ifa_flags&安培; IFF_UP))
继续; 开关(IFA-GT&;&ifa_addr- GT;上sa_family)
{
案例AF_INET:
{
结构SOCKADDR_IN * S4 =(结构SOCKADDR_IN *)IFA-GT&; ifa_addr;
in_addr结构=安培; S4-> sin_addr;
打破;
} 案例AF_INET6:
{
结构* sockaddr_in6的S6 =(结构* sockaddr_in6的)IFA-GT&; ifa_addr;
in_addr结构=安培; s6-> sin6_addr;
打破;
} 默认:
继续;
} (!inet_ntop(IFA-GT&;&ifa_addr- GT;上sa_family,in_addr结构,BUF,sizeof的(BUF)))如果
{
的printf(%S:inet_ntop失败\\ n,IFA-GT&; ifa_name);
}
其他
{
的printf(IP地址:%S \\ n,BUF);
}
}freeifaddrs(myaddrs);
code是大大AP preciated。
编辑:结果
由于这显然是很难COM prehend我会给你一个例子:
如果我得到ABCD:12:3我需要把它扩大到ABCD:0012:0000:0000:0000:0000:0000:0003结果
原因?因为它的需求的一部分。就这么简单。
无效ipv6_to_str_unexpanded(的char * str中,常量结构in6_addr *地址){
sprintf的(STR,%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X
(INT)addr-> s6_addr [0],(int)的addr-> s6_addr [1],
(INT)addr-> s6_addr [2],(int)的addr-> s6_addr [3],
(INT)addr-> s6_addr [4],(int)的addr-> s6_addr [5],
(INT)addr-> s6_addr [6],(int)的addr-> s6_addr [7],
(INT)addr-> s6_addr [8],(int)的addr-> s6_addr [9],
(INT)addr-> s6_addr [10],(int)的addr-> s6_addr [11],
(INT)addr-> s6_addr [12],(int)的addr-> s6_addr [13],
(INT)addr-> s6_addr [14],(int)的addr-> s6_addr [15]);
}
I am using getifaddrs() and inet_ntop() to get the ip addresses on the system. When the system is set to IPv6 the address returned is in the shortened version (using :: for zeros). Is there any way to expand that address to a full one?
This is the code I am using:
struct ifaddrs *myaddrs, *ifa;
void *in_addr;
char buf[64];
if(getifaddrs(&myaddrs) != 0)
{
perror("getifaddrs");
exit(1);
}
for (ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next)
{
if (ifa->ifa_addr == NULL)
continue;
if (!(ifa->ifa_flags & IFF_UP))
continue;
switch (ifa->ifa_addr->sa_family)
{
case AF_INET:
{
struct sockaddr_in *s4 = (struct sockaddr_in *)ifa->ifa_addr;
in_addr = &s4->sin_addr;
break;
}
case AF_INET6:
{
struct sockaddr_in6 *s6 = (struct sockaddr_in6 *)ifa->ifa_addr;
in_addr = &s6->sin6_addr;
break;
}
default:
continue;
}
if (!inet_ntop(ifa->ifa_addr->sa_family, in_addr, buf, sizeof(buf)))
{
printf("%s: inet_ntop failed!\n", ifa->ifa_name);
}
else
{
printf("IP address: %s\n", buf);
}
}
freeifaddrs(myaddrs);
Code is greatly appreciated.
EDIT:
Since this is apparently very hard to comprehend I will give you an example:
If I get abcd:12::3 I need to expand it to abcd:0012:0000:0000:0000:0000:0000:0003
The reason? because it's part of the requirements. Simple as that.
void ipv6_to_str_unexpanded(char * str, const struct in6_addr * addr) {
sprintf(str, "%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x",
(int)addr->s6_addr[0], (int)addr->s6_addr[1],
(int)addr->s6_addr[2], (int)addr->s6_addr[3],
(int)addr->s6_addr[4], (int)addr->s6_addr[5],
(int)addr->s6_addr[6], (int)addr->s6_addr[7],
(int)addr->s6_addr[8], (int)addr->s6_addr[9],
(int)addr->s6_addr[10], (int)addr->s6_addr[11],
(int)addr->s6_addr[12], (int)addr->s6_addr[13],
(int)addr->s6_addr[14], (int)addr->s6_addr[15]);
}
这篇关于扩大IPv6地址,所以我可以将其打印到标准输出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!