我想使用规范化的IP地址将数据保存在数据库中。
此时,软件可能会获得IPv4或IPv6地址。我希望通过将所有地址转换为IPv6地址来进行规范化。
我知道inet_pton()
将字符串转换为二进制地址。所以我可以使用IPv6尝试一次,如果失败,请再次使用IPv4:
struct sockaddr_in6 sa;
int r = inet_pton(AF_INET6, input_addr, &sa.sin6_addr);
if(r != 1)
{
// try again with IPv4
struct sockaddr_in sa4;
int r = inet_pton(AF_INET, input_addr, &sa4.sin_addr);
// is there such a function?!
inet_convert_ipv4_to_ipv6(&sa4, &sa);
}
char output_addr[INET6_ADDRSTRLEN];
inet_ntop(AF_INET6, &sa, output_addr, sizeof(output_addr));
// in C++, I can do that if function returns std::string
// in C you cannot return a pointer on the stack, watch out!
return output_addr;
所以,我正在寻找inet_convert_ipv4_to_ipv6(&sa4, &sa);
这样的函数来将sockaddr_in
转换为sockaddr_in6
。我们在C库中有这样的吗?
如果我们没有这样的功能,那么解决方案是使用' :: ffff:'介绍人如:
// try again with IPv4
std::string ipv4_to_ipv6("::ffff:");
ipv4_to_ipv6 += input_addr;
int r = inet_pton(AF_INET6, ipv4_to_ipv6.c_str(), &sa.sin_addr);
我希望我们有办法将IPv4 sockaddr_in
转换为IPv6 sockaddr_in6
功能。我认为它会更干净......我认为最后一段代码不是100%安全(我想我可以先测试IPv4转换,如果成功,那么使用IPv6转换使其安全。真是浪费时间虽然!)
答案 0 :(得分:1)
你可以在两次调用inet_pton时继续使用sockaddr_in6。成功转换IPv4后,您可以转移到正确的位置。 Here是map4to6()方法中的一个示例。
编辑:修复提到的错误方法名称。
答案 1 :(得分:1)
unsigned char *ip = in6_addr.s6_addr;
((uint64*)ip)[0] = 0;
((uint16*)ip)[4] = 0;
ip[10] = 0xFF;
ip[11] = 0xFF;
((in_addr_t*)(ip + 12))[0] = in_addr.s_addr