JohnB JohnB - 3 months ago 18
C Question

inet_ntop printing incorrect IPv6 address

I seem to be getting back bad IPv6 character strings from inet_ntop especially with addresses where it tries to drop sequences of zeros in favor of "::".

Here is the code;

#include <stdio.h>
#include <stdint.h>
#include <arpa/inet.h>

int main (void)
{
uint32_t ip[4] = {0xe0e0e0e0, 0xf0f0f0f0, 0x0, 0x1};
char addr[INET6_ADDRSTRLEN] = "";

inet_ntop(AF_INET6, ip, addr, INET6_ADDRSTRLEN);
printf("address = %s",addr);
return 0;
}


When i run this i get the following output;

address = address = e0e0:e0e0:f0f0:f0f0::100:0


This looks quite wrong to me and i would have expect something like;

address = e0e0:e0e0:f0f0:f0f0::1


Does anyone know whats wrong with this?

Thanks

Answer

The comment, pay attention to byte order is correct. You should also use the struct in6_addr for the IP address really. Here is an example initialising that as a sequence of bytes, which gives the expected output:

#include <stdio.h>
#include <stdint.h>
#include <arpa/inet.h>

int main (void)
{
    const struct in6_addr ip = { 0xe0, 0xe0, 0xe0, 0xe0,
                                 0xf0, 0xf0, 0xf0, 0xf0,
                                 0x00, 0x00, 0x00, 0x00,
                                 0x00, 0x00, 0x00, 0x01 };
    //const uint32_t ip[4] = { 0xe0e0e0e0, 0xf0f0f0f0, 0x0, 0x1 };
    char addr[INET6_ADDRSTRLEN];

    inet_ntop(AF_INET6, &ip, addr, INET6_ADDRSTRLEN);
    printf("address = %s",addr);
    return 0;
}

gcc main.c && ./a.out results in: address = e0e0:e0e0:f0f0:f0f0::1

Here's a quick example to compare the byte ordering on an x86 machine:

#include <stdio.h>
#include <stdint.h>
#include <arpa/inet.h>

int main (void)
{
    const struct in6_addr ip_uint8 = { 0xe0, 0xe0, 0xe0, 0xe0,
                                       0xf0, 0xf0, 0xf0, 0xf0,
                                       0x00, 0x00, 0x00, 0x00,
                                       0x00, 0x00, 0x00, 0x01 };
    const uint32_t ip_uint32[4] = { 0xe0e0e0e0, 0xf0f0f0f0, 0x0, 0x1 };
    char addr[INET6_ADDRSTRLEN];

    inet_ntop(AF_INET6, &ip_uint8, addr, INET6_ADDRSTRLEN);
    printf("address = %s\n",addr);

    unsigned char* b = (unsigned char*)&ip_uint8;
    printf("address bytes uint8 :");
    for( int i=0; i<16; i++) {
      printf(" %2.2X", b[i]);
    }
    printf("\n");

    b = (unsigned char*)&ip_uint32;
    printf("address bytes uint32:");
    for( int i=0; i<16; i++) {
      printf(" %2.2X", b[i]);
    }
    printf("\n");

    return 0;
}

Gives the output:

address = e0e0:e0e0:f0f0:f0f0::1
address bytes uint8 : E0 E0 E0 E0 F0 F0 F0 F0 00 00 00 00 00 00 00 01
address bytes uint32: E0 E0 E0 E0 F0 F0 F0 F0 00 00 00 00 01 00 00 00

The example words of repetitive bytes like 0xe0e0e0e0 don't do you any favours when trying to debug these sorts of problems, 0x01020304 would give you a much better idea of what was going wrong.

Comments