【问题标题】:Is ::ffff:127.0.0.1 localhost?::ffff:127.0.0.1 是本地主机吗?
【发布时间】:2018-09-22 10:25:21
【问题描述】:

我开始了解 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


    【解决方案1】:

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

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

    【讨论】:

    • 好的,所以如果我有一个在 localhost 监听的 IPv6 套接字,则不会接受以 :ffff:127.0.0.1 为目标的连接,因为它只是另一个不同于 ::1 的 IPv6 地址。谢谢!
    • 在监听IPv6未指定地址时,通常会遇到映射地址。当创建多个套接字来监听特定地址时,为每个地址的协议显式创建套接字会更容易。
    猜你喜欢
    • 2013-11-11
    • 1970-01-01
    • 2014-10-01
    • 2014-08-19
    • 1970-01-01
    • 2020-02-18
    • 2011-04-25
    • 2010-12-23
    • 2015-06-07
    相关资源
    最近更新 更多