【问题标题】:getnameinfo() - Reverse DNS lookup (IP Address to hostname) C/C++getnameinfo() - 反向 DNS 查找(IP 地址到主机名)C/C++
【发布时间】:2014-06-09 02:56:14
【问题描述】:

对于 IPAddress 66.249.68.9(“dig -x”正确表示“crawl-66-249-68-9.googlebot.com”),我可爱的程序声称它是 ip68-9-0-0.ri.ri。考克斯网。

我不在乎我是否以类似于下面代码的方式结束,只是希望能够以 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;
   }
}

【问题讨论】:

  • 作为一个风格点,你做int inetPtonReturnValue { inet_pton(AF_INET, IPAddress.c_str(), &amp;structSockAddr.sa_data) };而不是实际分配inet_ptoninetPtonReturnValue是有原因的吗?
  • 您的实际(不是“奖励”)问题是什么?
  • Joe - 只喜欢大括号初始化。
  • 克里斯 - 抱歉,实际问题是为什么我的程序给出 hostBuffer "ip68-9-0-0.ri.ri.cox.net" 而不是正确答案 "crawl-66-249- 68-9.googlebot.com"

标签: c++ dns ip


【解决方案1】:

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

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

【讨论】:

  • 你成功了。谢谢!
【解决方案2】:

这里是反向 DNS 查找的分解 C++ 示例

// 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
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-10-08
    • 1970-01-01
    • 2011-04-07
    • 1970-01-01
    • 2014-12-02
    • 1970-01-01
    • 1970-01-01
    • 2013-01-15
    相关资源
    最近更新 更多