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

getnameinfo() - Reverse DNS lookup (IP Address to hostname) C/C++

本文关键字:主机 C++ IP 反向 DNS 查找 getnameinfo 地址      更新时间:2023-10-16

对于IPAddress 66.249.68.9("dig-x"正确地说是"crawl-66-249-68-9.googlebot.com"),我可爱的程序声称它是ip68-9-0-0.ri.cox.net.

我不在乎是否以类似下面代码的方式完成,只想能够从IPV4 IP地址开始,然后以主机名结束。

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

#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;
   }
}

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

目前,您正在将地址的一些字节写入包含实际IP地址的字段之前的字段中,因此您的sockaddr字段中只有IP的最后2个八位字节。

下面是一个分解的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
    }
}