Is ::ffff:127.0.0.1 localhost?
Asked Answered
T

2

5

I'm getting introduced into IPv6 and I've read that IPv4 addresses can be mapped to IPv6 by using the ::ffff: prefix. This led me to think whether address ::ffff:127.0.0.1 refers to localhost, so I wrote a simple C program that uses getaddrinfo() and IN6_IS_ADDR_LOOPBACK macro for checking if the returned address is the loopback one.

I have tested the program with ::1 and other variations of the loopback address and, as expected, the program says that it's loopback. But, to my surprise, when I try ::ffff:127.0.0.1 the program says that it's not! How is this possible? Am I missing anything?

Here's the simplified version of the source code of my program:

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!");
Trescott answered 12/4, 2018 at 9:59 Comment(0)
E
9

If you accept incoming IPv4 connections on an IPv6 socket then the IPv4 address has to be padded to 128 bits. That is done by prepending ::ffff:. So what you are seeing is the IPv4 loopback address.

When checking if the address is the IPv6 loopback address then the answer will be no, because ::1 is the IPv6 loopback address. The address you see is classified as an IPv4-mapped IPv6 address. The mapped IPv4 address just happens to be the IPv4 loopback address, but from the point of view of the IPv6 stack it's just a mapped address.

Edessa answered 12/4, 2018 at 12:4 Comment(2)
Ok, so if I have an IPv6 socket listening at localhost, no connections targetted to :ffff:127.0.0.1 will be accepted because it's just another IPv6 address different than ::1. Thank you!Trescott
The mapped address are usually encountered when listening to the IPv6 unspecified address. When creating multiple sockets to listen on specific address then it's easier to explicitly create the sockets for the protocol of each address.Edessa
S
0

IN6_IS_ADDR_LOOPBACK physically compares its argument with ::1. It is not an actual check of whether a given address can be used as a loopback address.

A local server binding its ip socket to INADDR_ANY can be reached by 127.0.0.1, ::ffff:127.0.0.1 but not by ::1. By contrast, a server binding its ipv6 socket to IN6ADDR_ANY_INIT can be reached by all those three addresses.

That's on Linux 6.1. Not sure other systems (have to) behave the same.

Sheng answered 10/6 at 12:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.