2

Goal: return FQDN given the sockaddr

I'm trying to use getnameinfo to perform a reverse DNS lookup and return the FQDN for example.com, however the code below fails to print the FQDN with error EAI_NONAME (8). Prior to running the code below, I open example.com in the browser to make sure the DNS cache contains a mapping of domain_name to ip_address, but the code below seems to fail to return "example.com" as the FQDN. Am I missing something? I'm using macOS 10.14.4 and compiling the code with gcc "filename.c"

#include <arpa/inet.h>
#include <netdb.h>
#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>

int main()
{
    const char* EXAMPLE_COM_IP_ADDR = "93.184.216.34"; // check this with `ping example.com`
    struct sockaddr_in sa = {0};
    char host[NI_MAXHOST] = "";
    char serv[NI_MAXSERV] = "";
    int rc = 0;

    // fill sockaddr_in with data - https://beej.us/guide/bgnet/html/multi/sockaddr_inman.html
    sa.sin_family = AF_INET;
    sa.sin_port = htons(80);
    rc = inet_pton(AF_INET, EXAMPLE_COM_IP_ADDR, &(sa.sin_addr));
    if (rc != 1)
        printf("inet_pton rc = %d\n", rc);

    // translate sockaddr to host + service - https://beej.us/guide/bgnet/html/multi/getnameinfoman.html
    printf("getnameinfo with NI_NAMEREQD flag:\n");
    rc = getnameinfo((struct sockaddr*)(&sa), sizeof(sa), host, sizeof(host), serv, sizeof(serv), NI_NAMEREQD);
    if (rc != 0)
        printf("getnameinfo rc = %d, err= %s\n", rc, gai_strerror(rc));
    printf("host: %s\n", host); // should print - "www.example.com"
    printf("serv: %s\n", serv); // should print - "http"

    return 0;
}
Unglued
  • 419
  • 6
  • 15

1 Answers1

1

The reverse lookup does not use the DNS cache. Instead it uses the rDNS lookup, i.e. the in-addr.arpa pseudo-domain. Well, it turns out that:

% host 93.184.216.34
Host 34.216.184.93.in-addr.arpa. not found: 3(NXDOMAIN)

There is no reverse PTR record for the IP address.

If you replace the address with 8.8.8.8, say, you get

% ./a.out           
getnameinfo with NI_NAMEREQD flag:
host: google-public-dns-a.google.com
serv: http

And this is only because:

% host 8.8.8.8      
8.8.8.8.in-addr.arpa domain name pointer google-public-dns-a.google.com.
  • oh snap! so in this case, it seems getnameinfo won't do what I was thinking it would. Is there anything else I can use in C to return FQDN given a sockaddr struct? – Unglued May 13 '19 at 18:49
  • @Unglued well I doubt there are good options. Even worse, in the current age of virtual hosting an IP address can have gazillions of names for it in the name cache... It is either the rDNS one or the one that *your user* or similar supplied to the program. – Antti Haapala -- Слава Україні May 13 '19 at 18:51