简体   繁体   中英

How to convert IPv4-mapped-IPv6 address to IPv4 (string format)?

I have a struct sockaddr structure containing an IPv4-mapped-IPv6 address like ::ffff:10.0.0.1 . I want to obtain only the IPv4 version of it in a string (in this case, 10.0.0.1 ) in C programming language. How do I go about achieving it?

As your structure contains an IPV6 address, I'll assume your have a struct sockaddr * pointer (let's name it addrPtr ) pointing to a struct sockaddr_in6 structure.

You can get the address bytes easily.

const uint8_t *bytes = ((const struct sockaddr_in6 *)addrPtr)->sin6_addr.s6_addr;

Then add 12 to the pointer because the 12 first bytes are not interesting (10 0x00 , then 2 0xff ). Only the 4 last ones mater.

bytes += 12;

Now, we can use those four bytes to do whatever we want. For example, we might store them into a IPv4 struct in_addr address.

struct in_addr addr = { *(const in_addr_t *)bytes };

Then we can get a string using inet_ntop (declared in <arpa/inet.h> ).

char buffer[16]; // 16 characters at max: "xxx.xxx.xxx.xxx" + NULL terminator
const char *string = inet_ntop(AF_INET, &addr, buffer, sizeof(buffer));

If you want to be compatible with other types of addresses, use getnameinfo.

char hostbuf[NI_MAXHOST];
char *host;

if (getnameinfo(addr, addrlen, hostbuf, sizeof(hostbuf), NULL, 0, NI_NUMERICHOST))
    ;//error

if (strncmp(hostbuf, "::ffff:", sizeof("::ffff:") - 1) == 0)
    host = hostbuf + sizeof("::ffff:") - 1;
else
    host = hostbuf;

Once you have recognised an IPv4 mapped address, the IPv4 portion is simply the least significant four bytes of the address. I believe that this can be done as follows:

struct sockaddr *address;  // this is the address
struct sockaddr_in6 *addrv6 = (struct sockaddr_in6 *)address;
unsigned long address;
memcpy(&address, addrv6->sin6_addr.s6_addr + 11, 4);

The documentation states that the address appears in network order (most significant byte first). If this differs from you machine architecture, you need to call htonl() in order to reverse byte order.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM