是:: ffff:127.0.0.1 localhost?

时间:2018-04-12 09:59:59

标签: linux network-programming ipv6 loopback getaddrinfo

我已经了解了IPv6,并且我已经读过可以使用::ffff:前缀将IPv4地址映射到IPv6。这让我想到地址::ffff:127.0.0.1是否引用localhost,所以我编写了一个简单的C程序,它使用getaddrinfo()IN6_IS_ADDR_LOOPBACK宏来检查返回的地址是否是环回之一。

我已使用::1和其他环回地址变体对程序进行了测试,并且正如预期的那样,程序会说它是环回的。但是,令我惊讶的是,当我尝试::ffff:127.0.0.1时,程序会说它不是!这怎么可能?我错过了什么吗?

这是我的程序源代码的简化版本:

struct addrinfo hints, *servinfo;
int rv;

memset(&hints, 0, sizeof(hints));

hints.ai_family = AF_UNSPEC; // IPv4 or IPv6
hints.ai_socktype = SOCK_STREAM;

/* hostname_or_ip is entered from the command line */
if ( (rv = getaddrinfo(hostname_or_ip, NULL, &hints, &servinfo)) != 0) {
    exit(1);
}

struct addrinfo *p = servinfo;
struct sockaddr_in6 *h = (struct sockaddr_in6 *) p->ai_addr;
int is_loopback = IN6_IS_ADDR_LOOPBACK(&h->sin6_addr) ? 1 : 0;

printf("%s\n", is_loopback ? "YES!" : "NO!");

1 个答案:

答案 0 :(得分:3)

如果接受IPv6套接字上的传入IPv4连接,则必须将IPv4地址填充为128位。这是通过预先::ffff:来完成的。所以你看到的是IPv4环回地址。

检查地址是否为IPv6环回地址时,答案为否,因为::1是IPv6环回地址。您看到的地址被归类为IPv4映射的IPv6地址。映射的IPv4地址恰好是IPv4环回地址,但从IPv6堆栈的角度来看,它只是一个映射地址。