getnameinfo() - 反向DNS查找(IP地址到主机名)C / C ++

时间:2014-04-24 02:02:03

标签: c++ dns ip

对于IPAddress 66.249.68.9(" dig -x"正确地说" crawl-66-249-68-9.googlebot.com")我可爱的节目声称它&#39 ; s ip68-9-0-0.ri.ri.cox.net。

我不在乎我是否愿意以类似下面的代码的方式进行操作,只是希望能够从IPV4 IP地址开始并使用主机名结束。

奖金问题,什么服务?我想我不会需要它,并且会给getnameinfo NULL。但是,该计划正在输出" 17145"对于serviceBuffer。

#include <string>
#include <iostream>
using namespace std;

#include <netdb.h> // struct sockaddr, AF_INET, NI_NAMEREQD, getnameinfo
#include <string.h> // memset
#include <arpa/inet.h> // inet_pton

int main() {
   const string IPAddress { "66.249.68.9" };

   struct sockaddr structSockAddr;
   memset(&structSockAddr, 0, sizeof(structSockAddr));

   structSockAddr.sa_family = AF_INET;
   int inetPtonReturnValue { inet_pton(AF_INET, IPAddress.c_str(), &structSockAddr.sa_data) };
   if(1 != inetPtonReturnValue) {
      cout << "inetPtonReturnValue : " << inetPtonReturnValue << endl; // 0 = src doesn't contain valid address, -1 = af isn't a valid family
   }

   char hostBuffer[10000];
   char serviceBuffer[1000];

   int getNameInfoReturnValue { getnameinfo(&structSockAddr, sizeof(structSockAddr), hostBuffer, sizeof(hostBuffer), serviceBuffer, sizeof(serviceBuffer), NI_NAMEREQD) };

   if(0 != getNameInfoReturnValue) {
      cout << "getNameInfoReturnValue : " << getNameInfoReturnValue << endl
           << "gai_strerror() : " << gai_strerror(getNameInfoReturnValue) << endl;
   } else {
      cout << "IPAddress : " << IPAddress << endl
           << "hostBuffer : " << hostBuffer << endl
           << "serviceBuffer : " << serviceBuffer << endl;
   }
}

2 个答案:

答案 0 :(得分:2)

您在调用struct sockaddr时使用的是inet_pton,但调用签名要求AF_INET为struct in_addr(IPv6为struct in6_addr)。然后你必须使用它为后面的函数构建struct sockaddr

目前的情况是,您将地址的一些字节写入包含实际IP地址的字段之前的字段中,因此您最终只得到sockaddr字段中IP的最后2个八位字节。

答案 1 :(得分:0)

这是一个细分的C ++反向DNS查找示例

// Variables
WSADATA wsaData = { 0 };
int iResult = 0;
DWORD dwRetval;
struct sockaddr_in saGNI;
char hostname[NI_MAXHOST];
char servInfo[NI_MAXSERV];
std::string ip = "YOUR_SERVER_IP";
int port = 25;

iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult == 0 /*initialization success*/) {
    saGNI.sin_family = AF_INET;
    saGNI.sin_addr.s_addr = inet_addr(ip.c_str());
    saGNI.sin_port = htons(port);

    dwRetval = getnameinfo((struct sockaddr*) & saGNI,
        sizeof(struct sockaddr),
        hostname,
        NI_MAXHOST, servInfo, NI_MAXSERV, NI_NUMERICSERV);

    if (dwRetval == 0) {
        // save hostname result
    }
}