我有一个struct sockaddr
包含 IPv4 映射 IPv6 地址的结构,例如::ffff:10.0.0.1
. 我只想10.0.0.1
在 C 编程语言的字符串(在本例中为 )中获取它的 IPv4 版本。我该如何去实现它?
问问题
7359 次
3 回答
3
由于您的结构包含 IPV6 地址,我假设您有一个指向结构的struct sockaddr *
指针(让我们命名它addrPtr
)struct sockaddr_in6
。
您可以轻松获取地址字节。
const uint8_t *bytes = ((const struct sockaddr_in6 *)addrPtr)->sin6_addr.s6_addr;
然后将 12 添加到指针,因为前 12 个字节不感兴趣(10 0x00
,然后 2 0xff
)。只有最后 4 个重要。
bytes += 12;
现在,我们可以使用这四个字节来做任何我们想做的事情。例如,我们可能会将它们存储到 IPv4struct in_addr
地址中。
struct in_addr addr = { *(const in_addr_t *)bytes };
然后我们可以使用inet_ntop
(declared in <arpa/inet.h>
) 得到一个字符串。
char buffer[16]; // 16 characters at max: "xxx.xxx.xxx.xxx" + NULL terminator
const char *string = inet_ntop(AF_INET, &addr, buffer, sizeof(buffer));
于 2012-06-27T19:36:48.617 回答
1
如果您想与其他类型的地址兼容,请使用 getnameinfo。
char hostbuf[NI_MAXHOST];
char *host;
if (getnameinfo(addr, addrlen, hostbuf, sizeof(hostbuf), NULL, 0, NI_NUMERICHOST))
;//error
if (strncmp(hostbuf, "::ffff:", sizeof("::ffff:") - 1) == 0)
host = hostbuf + sizeof("::ffff:") - 1;
else
host = hostbuf;
于 2012-06-27T21:52:29.347 回答
0
一旦您识别出 IPv4 映射地址,IPv4 部分就是地址的最低有效四个字节。我相信这可以通过以下方式完成:
struct sockaddr *address; // this is the address
struct sockaddr_in6 *addrv6 = (struct sockaddr_in6 *)address;
unsigned long address;
memcpy(&address, addrv6->sin6_addr.s6_addr + 11, 4);
该文档指出该地址以网络顺序出现(最高有效字节在前)。如果这与您的机器架构不同,您需要调用 htonl() 以反转字节顺序。
于 2012-06-27T19:41:35.787 回答