Comparing a peer's IPv6 address with localhost

c, ipv6, sockets

Solution

I guess this is how to see whether the incoming connection is localhost, assuming you have the peer in a `struct sockaddr_in6`, obtained from `getpeername` like so:

    struct sockaddr_in6 peer;
    socklen_t len = sizeof(peer);
    getpeername( sock, (struct sockaddr *) &peer, &len); // todo: error check

From there, you can fill in your own `struct sockaddr_in6` with the localhost address `::1` and compare the memory for equality:

    struct sockaddr_in6 localhost;
    memset(localhost.sin6_addr.s6_addr, 0, 16);
    localhost.sin6_addr.s6_addr[15] = 1;

    if( memcmp(peer.sin6_addr.s6_addr, localhost.sin6_addr.s6_addr, 16) == 0)
        printf("localhost!\n");

Or you can create an array of bytes that correspond with the localhost address:

    static const unsigned char localhost_bytes[] =
        { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };

    if( memcmp(peer.sin6_addr.s6_addr, localhost_bytes, 16) == 0)
        printf("localhost!\n");

And watch out for the mapped IPv4 localhost, `::ffff:127.0.0.1`. You may have to check that, too.

    static const unsigned char mapped_ipv4_localhost[] =
        { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 0x7f, 0, 0, 1 };

    if( memcmp(peer.sin6_addr.s6_addr, mapped_ipv4_localhost, 16) == 0)
        printf("mapped IPv4 localhost!\n");

Problem

I have called `getpeername` on my connected socket and now have an IPv6 address of the connected peer. How do I tell whether my peer's IP address is localhost? Edit: To clarify, I mean specifically localhost, as in the loopback IP address.

Original source