のようstruct sockaddr
な IPv4 マップ IPv6 アドレスを含む構造があります::ffff:10.0.0.1
。10.0.0.1
C言語の文字列(この場合は)でIPv4版のみ取得したい。どうすればそれを達成できますか?
質問する
7359 次
3 に答える
3
構造体には IPV6 アドレスが含まれているため、構造体を指すstruct sockaddr *
ポインター (名前を付けましょう) があると仮定します。addrPtr
struct sockaddr_in6
アドレスバイトを簡単に取得できます。
const uint8_t *bytes = ((const struct sockaddr_in6 *)addrPtr)->sin6_addr.s6_addr;
次に、最初の 12 バイトは重要ではないため (10 0x00
、次に 2 0xff
)、ポインターに 12 を追加します。最後の4つだけが重要です。
bytes += 12;
これで、これらの 4 バイトを使用して、必要なことを行うことができます。たとえば、それらを IPv4struct in_addr
アドレスに格納する場合があります。
struct in_addr addr = { *(const in_addr_t *)bytes };
次に、inet_ntop
(で宣言<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));
于 2012-06-27T19:36:48.617 に答える
1
他のタイプのアドレスと互換性を持たせたい場合は、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;
于 2012-06-27T21:52:29.347 に答える
0
IPv4 マップ アドレスを認識すると、IPv4 部分は単純にアドレスの最下位 4 バイトになります。これは次のようにできると思います。
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);
ドキュメントには、アドレスがネットワーク順 (最上位バイトが最初) に表示されると記載されています。これがマシン アーキテクチャと異なる場合は、バイト オーダーを逆にするために htonl() を呼び出す必要があります。
于 2012-06-27T19:41:35.787 に答える