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

倾然丶 夕夏残阳落幕 提交于 2019-12-10 09:36:59

问题


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?


回答1:


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));



回答2:


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;



回答3:


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.



来源:https://stackoverflow.com/questions/11233246/how-to-convert-ipv4-mapped-ipv6-address-to-ipv4-string-format

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!