C program for 'Reverse DNS lookup' I have written the following code for doing a reverse dns lookup. I'm not sure if there are any errors in it. Please have a look:

#include &lt;stdio.h&gt; //for printf()
#include &lt;stdlib.h&gt; //for exit()
#include &lt;arpa/inet.h&gt; //for inet_pton()
#include &lt;netdb.h&gt; // for NI_MAXHOST, getnameinfo() and gai_strerror()
#include &lt;errno.h&gt; // for errno
#include &lt;string.h&gt; // for strerror()

int main(int argc, char** argv) {
  if(argc&lt;2) {
    printf("\n%s [IP]\n",argv[0]);
    printf("For e.g. %s 10.32.129.77\n",argv[0]);
    exit(-1);
  }
  struct sockaddr_in sa;
  int res = inet_pton(AF_INET, argv[1] , &amp;sa.sin_addr);
  switch(res) {
    case 0: printf("\nInput address is not a valid IPv4 address.\n");
    case -1: if(res == -1)
               printf("\nError(%s)\n",strerror(errno));
             int n_res = inet_pton(AF_INET6, argv[1] , &amp;sa.sin_addr);
             switch(n_res) {
               case 0: printf("\nInput address is not a valid IPv6 address.\n");
               case -1: if(n_res == -1)
                          printf("\nError(%s)\n",strerror(errno));
                        exit(-1);
               case 1: sa.sin_family = AF_INET6;
             }
    case 1: sa.sin_family = AF_INET;
  }

  printf("\nsa.sin_addr.s_addr[%d]\n",sa.sin_addr.s_addr);

  char node[NI_MAXHOST];
  memset(node,0,NI_MAXHOST);
  res = getnameinfo((struct sockaddr*)&amp;sa, sizeof(sa), node, sizeof(node), NULL, 0, 0);
  if (res) {
    printf("%s\n", gai_strerror(res));
    exit(1);
  }

  printf("\nIP[%s]\n",argv[1]);
  printf("HOSTNAME[%s]\n", node);

  return 0;
}
It's generally best to divide your code into separate sections (possibly separate functions) for argument handling and actual computation.

Errors should be printed to standard error rather than standard output.  Also, prefer small integer values for exit status (and since we're in main(), we can use simple return rather than exit() - note the useful EXIT_FAILURE macro for the return value).

It's worth documenting case fallthroughs.  This one is especially suspect:


               case 1: sa.sin_family = AF_INET6;
             }
    case 1: sa.sin_family = AF_INET;
  }



After we store AF_INET6, it's immediately overwritten with AF_INET - is that really intended?

This fallthrough would be clearer as two independent cases:


    case 0:
        printf("\nInput address is not a valid IPv6 address.\n");
        /* fallthrough */
    case -1:
        if (n_res == -1)
            printf("\nError(%s)\n",strerror(errno));
        exit(-1);



Compare:

    case 0:
        fprintf(stderr, "\nInput address is not a valid IPv6 address.\n");
        return 1;
    case -1:
        fprintf(stderr, "\nError(%s)\n", strerror(errno));
        return 1;


This line seems to be no use to a user:


printf("\nsa.sin_addr.s_addr[%d]\n",sa.sin_addr.s_addr);



We check for argv less than 2, but we neither complain about nor use any excess arguments.

There's no need to null out the node storage, as getnameinfo() will either fail (in which case we'll never access it) or write a valid string.

Minor (grammar): don't use "for" with "e.g." - that reads like, "for for example".



When I tried running the program, I found it wouldn't work at all with IPv6 addresses, because sockaddr_in is too small for IPv6 addresses.  I had to totally rewrite with a union of address types:

#include &lt;arpa/inet.h&gt; //for inet_pton()
#include &lt;netdb.h&gt; // for NI_MAXHOST, getnameinfo() and gai_strerror()

#include &lt;errno.h&gt;
#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;string.h&gt;

static int convert4(struct sockaddr_in *sa, const char *name)
{
    return inet_pton(sa-&gt;sin_family = AF_INET, name, &amp;sa-&gt;sin_addr);
}

static int convert6(struct sockaddr_in6 *sa, const char *name)
{
    return inet_pton(sa-&gt;sin6_family = AF_INET6, name, &amp;sa-&gt;sin6_addr);
}


int main(int argc, char** argv)
{
    if (argc != 2) {
        fprintf(stderr, "Usage: %s [IP]\nE.g. %s 10.32.129.77\n", argv[0], argv[0]);
        return EXIT_FAILURE;
    }

    union {
        struct sockaddr         sa;
        struct sockaddr_in      s4;
        struct sockaddr_in6     s6;
        struct sockaddr_storage ss;
    } addr;

    if (convert4(&amp;addr.s4, argv[1]) != 1 &amp;&amp; convert6(&amp;addr.s6, argv[1]) != 1) {
        fprintf(stderr, "%s: not a valid IP address.\n", argv[1]);
        return EXIT_FAILURE;
    }

    char node[NI_MAXHOST];
    int res = getnameinfo(&amp;addr.sa, sizeof addr, node, sizeof node, NULL, 0, NI_NAMEREQD);
    if (res) {
        fprintf(stderr, "%s: %s\n", argv[1], gai_strerror(res));
        return EXIT_FAILURE;
    }

    puts(node);
}