是 ::ffff:127.0.0.1 本地主机吗?

问题描述 投票:0回答:2

我正在了解 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!");
linux network-programming ipv6 loopback getaddrinfo
2个回答
8
投票

如果您接受 IPv6 套接字上的传入 IPv4 连接,则必须将 IPv4 地址填充为 128 位。这是通过添加

::ffff:
来完成的。所以您看到的是 IPv4 环回地址。

检查该地址是否是 IPv6 环回地址时,答案是否定的,因为

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


0
投票

IN6_IS_ADDR_LOOPBACK
在物理上将其论证与
::1
进行比较。 它并不是实际检查给定地址是否可以用作环回地址。

将其 IP 套接字绑定到 INADDR_ANY 的本地服务器可以通过

127.0.0.1
::ffff:127.0.0.1
到达,但不能通过
::1
到达。 相比之下,将其 ipv6 套接字绑定到 IN6ADDR_ANY_INIT 的服务器可以通过所有这三个地址到达。

© www.soinside.com 2019 - 2024. All rights reserved.