2013-01-11 224 views
0

如何從IPv4映射的IPv6地址獲取IPv4地址?如何從IPv4映射的IPv6地址解析IPv4地址?

例如,我有一個IP地址::FFFF:129.144.52.38。從這裏,我需要提取129.144.52.38。有沒有用於此目的的API?

我可以使用下面的函數

int getaddrfamily(const char *addr) 
{ 
    struct addrinfo hint, *info =0; 
    memset(&hint, 0, sizeof(hint)); 
    hint.ai_family = AF_UNSPEC; 
    // Uncomment this to disable DNS lookup 
    //hint.ai_flags = AI_NUMERICHOST; 
    int ret = getaddrinfo(addr, 0, &hint, &info); 
    if (ret) 
     return -1; 
    int result = info->ai_family; 
    freeaddrinfo(info); 
    return result; 
} 

識別IPv6或IPv4地址族如果我給一個IPv4映射的IPv6地址,這又如何可能識別,如果它是一個映射ADRESS?是否有任何套接字API從映射的IPv6地址中提取IPv4?

+0

這個問題可能會感興趣:http://stackoverflow.com/q/13949750/175849 –

回答

3

嘗試這樣:

#ifndef IN6_IS_ADDR_V4MAPPED 
#define IN6_IS_ADDR_V4MAPPED(a) \ 
     ((((a)->s6_words[0]) == 0) && \ 
     (((a)->s6_words[1]) == 0) && \ 
     (((a)->s6_word[2]) == 0) && \ 
     (((a)->s6_word[3]) == 0) && \ 
     (((a)->s6_word[4]) == 0) && \ 
     (((a)->s6_word[5]) == 0xFFFF)) 
#endif 

unsigned long getIPv4addr(const char *addr) 
{ 
    struct addrinfo hint, *info = 0; 
    unsigned long result = INADDR_NONE; 
    memset(&hint, 0, sizeof(hint)); 
    hint.ai_family = AF_UNSPEC; 
    // Uncomment this to disable DNS lookup 
    //hint.ai_flags = AI_NUMERICHOST; 
    if (getaddrinfo(addr, 0, &hint, &info) == 0) 
    { 
     switch (info->ai_family) 
     { 
      case AF_INET: 
      { 
       struct sockaddr_in *addr = (struct sockaddr_in*)(info->ai_addr); 
       result = addr->sin_addr.s_addr; 
       break; 
      } 

      case AF_INET6: 
      { 
       struct sockaddr_in6 *addr = (struct sockaddr_in6*)(info->ai_addr); 
       if (IN6_IS_ADDR_V4MAPPED(&addr->sin6_addr)) 
        result = ((in_addr*)(addr->sin6_addr.s6_addr+12))->s_addr; 
       break; 
      } 
     } 
     freeaddrinfo(info); 
    } 
    return result; 
} 
1

您只需從IPv6地址中提取最後四個字節,將它們合併爲一個32位數字,並且您具有IPv4地址。

+0

我不知道爲什麼這是downvoted,這是100%正確和基本C. –