Saturday, August 27, 2011

gethostbyaddr example C code

//
//srvr2.c:
// 
//Example daytime server, with gethostbyaddr(3):
//
//Note : Below example shows a  server that opens a log file  //named srvr2.log in the current directory and logs each connect //request it receives. The server logs both the IP number and the //name if possible, of the connecting
//client.
//

  #include <stdio.h>

  #include <unistd.h>
  #include <stdlib.h>
  #include <errno.h>
  #include <string.h>
  #include <time.h>
  #include <sys/types.h>
  #include <sys/socket.h>
  #include <netinet/in.h>
  #include <arpa/inet.h>
  #include <netdb.h>

 /*
  * This function reports the error and
  * exits back to the shell:
  */
  static void displayError(const char *on_what) {
     if ( errno != 0 ) {
        fputs(strerror(errno),stderr);
        fputs(": ",stderr);
     }
     fputs(on_what,stderr);
     fputc('\n',stderr);
     exit(1);
  }

  int main(int argc,char **argv) {
     int z;
     char *srvr_addr = NULL;
     char *srvr_port = "9099";
     struct sockaddr_in adr_srvr;/* AF_INET */
     struct sockaddr_in adr_clnt;/* AF_INET */
     int len_inet;               /* length */
     int s;                      /* Socket */
     int c;                      /* Client socket */
     int n;                      /* bytes */
     time_t td;                  /* Current date&time */
     char dtbuf[128];            /* Date/Time info */
     FILE *logf;                 /* Log file for server */
     struct hostent *hp;         /* Host entry ptr */

 /*
  * Open the log file:
  */
  if ( !(logf = fopen("gethostbyaddr.log","w")) ) {
     displayError("fopen(3)");
  }

 /*
  * Use a server address from the command
  * line, if one has been provided.
  * Otherwise, this program will default
  * to using the arbitrary address
  * 127.0.0.:
  */
  if ( argc >= 2 ) {
     srvr_addr = argv[1];     /* Addr on cmdline: */
  }
  else {
     srvr_addr = "127.0.0.1"; /* Use default address: */
  }

 /*
  * If there is a second argument on the
  * command line, use it as the port #:
  */
  if ( argc >= 3 ) {
     srvr_port = argv[2];
  }

 /*
  * Create a TCP/IP socket to use:
  */
  s = socket(PF_INET,SOCK_STREAM,0);
  if ( s == -1 ) {
     displayError("socket()");
  }

 /*
  * Create a server socket address:
  */
  memset(&adr_srvr,0,sizeof adr_srvr);
  adr_srvr.sin_family = AF_INET;
  adr_srvr.sin_port = htons(atoi(srvr_port));

  if ( strcmp(srvr_addr,"*") != 0 ) {
     adr_srvr.sin_addr.s_addr =
     inet_addr(srvr_addr);  /* Normal Address */

  if ( adr_srvr.sin_addr.s_addr == INADDR_NONE )
     displayError("bad address.");
  }
  else { /* Wild Address */
     adr_srvr.sin_addr.s_addr = INADDR_ANY;
  }

 /*
  * Bind the server address:
  */
  len_inet = sizeof adr_srvr;
  z = bind(s,(struct sockaddr *)&adr_srvr, len_inet);
 
  if ( z == -1 ) {
     displayError("bind(2)");
  }

 /*
  * Make it a listening socket:
  */
  z = listen(s,10);
  if ( z == -1 ) {
     displayError("listen(2)");
  }

 /*
  * Start the server loop:
  */
  for (;;) { /* Wait for a connect: */
     len_inet = sizeof adr_clnt;
     c = accept(s,
               (struct sockaddr *)&adr_clnt,
               &len_inet);

     if ( c == -1 ) {
        displayError("accept(2)");
     }

     /*
      * Log the address of the client
      * who connected to us:
      */
      fprintf(logf,
              "Client %s:",
              inet_ntoa(adr_clnt.sin_addr));

      hp = gethostbyaddr(
                        (char *)&adr_clnt.sin_addr,
                         sizeof adr_clnt.sin_addr,
                         adr_clnt.sin_family
                         );

      if ( !hp ) {
         fprintf(logf," Error: %s\n", hstrerror(h_errno));
      }
      else {
         fprintf(logf," %s\n", hp->h_name);
      }
      fflush(logf);

     /*
      * Generate a time stamp:
      */
      time(&td);
      n = (int) strftime(dtbuf,sizeof dtbuf,
                        "%A %b %d %H:%M:%S %Y\n",
                        localtime(&td));

     /*
      * Write result back to the client:
      */
      z = write(c,dtbuf,n);
      if ( z == -1 ) {
         displayError("write(2)");
      }

     /*
      * Close this client's connection:
      */
      close(c);
    }

  /* Control never gets here */
  return 0;
  }
/*
 * OUTPUT
 *
[sgupta@rhel55x86 chap9]$
[1]+  Killed                  ./gethostbyaddr '*'
[sgupta@rhel55x86 chap9]$
[sgupta@rhel55x86 chap9]$
[sgupta@rhel55x86 chap9]$ ./gethostbyaddr '*' &
[1] 10292
[sgupta@rhel55x86 chap9]$ telnet rhel55x86.nc.com 9099
Trying 192.168.22.55...
Connected to rhel55x86.nc.com (192.168.22.55).
Escape character is '^]'.
Saturday Aug 27 00:33:52 2011
Connection closed by foreign host.
[sgupta@rhel55x86 chap9]$
[sgupta@rhel55x86 chap9]$ cat gethostbyaddr.log
Client 192.168.22.55: rhel55x86.nc.com
[sgupta@rhel55x86 chap9]$


 */



The server here is started and put into the background, using a wild server address '*'. This allows the server to be tested, in this example, from two different IP addresses:
• 127.0.0.1, which is named as localhost (as it is on most Linux systems)
• 192.168.0.1, which is named tux in the example penguins.org network

After starting the server with its wild address, a telnet to the address localhost on default port 9099 is performed. Later, another telnet is performed using the name tux. In the example, this causes telnet to use 192.168.0.1 to contact the server.
After both of those tests are performed, the log file is inspected using the cat command on the file gethostbyaddr.log. Notice that the log entries show 127.0.0.1 as localhost and 192.168.22.55 as rhel55x86.nc.com. The server demonstrated that it was able to convert the client's IP numbers back into names for logging purposes.

No comments:

Post a Comment