我正在学习IPv6,我读到IPv4地址可以通过使用 ::ffff: 前缀这让我想到 ::ffff:127.0.0.1 指 localhost ,所以我编写了一个简单的C程序 getaddrinfo() 和 IN6_IS_ADDR_LOOPBACK 用于检查返回地址是否为环回地址的宏。
::ffff:
::ffff:127.0.0.1
localhost
getaddrinfo()
IN6_IS_ADDR_LOOPBACK
我已经用 ::1 以及环回地址的其他变体,正如预期的那样,程序表示这是环回。但是,令我惊讶的是,当我尝试 ::ffff:127.0.0.1 节目说不是!这怎么可能?我遗漏了什么吗?
::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!");
如果在IPv6套接字上接受传入的IPv4连接,则IPv4地址必须填充为128位。这是通过预加 ::ffff: 。因此,您看到的是IPv4环回地址。
当检查地址是否为IPv6环回地址时,答案将为否,因为 ::1 是IPv6环回地址。您看到的地址被分类为IPv4映射的IPv6地址。映射的IPv4地址恰好是IPv4环回地址,但从IPv6堆栈的角度来看,它只是一个映射的地址。