Explanation:
Usually for obtaining IP Address of a remote host makes us
to use gethostbyname() function call.
It actually gets the IP Address by looking up the DNS. But
but…. This happens for the first time only, next time onward's it reads the IP
Address from the cache i.e. maintained by “nscd”.
Till the time it is available
their the request is fulfilled. Once the cache is cleared, again DNS look up is
performed.
So consider the case where our software is making
gethostbyname() call & suddenly a switch over is made at DNS. But as our
software is reading the IP address from the cache thus we are unaware of the
switch.
In this case it is possible that the software keeps on requesting the
old IP, till the cache is not cleared & a fresh look up call is made.
To avoid such scenario, C/C++ has an inbuilt library i.e.
“resolver api (libresolv.a/libresolv.so)”.
It has the required function calls
which do the DNS lookup & provide the required info like IP addresses,
hostname, Start of Authority Record, Name-server’s list etc.. etc…..
This API is really powerful & useful utility. If someone
has used DIG Command than one can easily relate to this as well.
All the options available with DIG, can be performed with
this Resolver API as well.
Eg: This sample program prints the IP Address for the provided hostname.
#include<cstdlib>
#include<iostream>
#include<string>
#include <algorithm>
using namespace std;
int main(int argc, char **argv){
u_char nsbuf[NS_PACKETSZ]; /* Response Buffer NS_PACKETSZ=512 ( maximum packet size) */
char dispbuf[4096]; /* buffer to display the resource record */
char ipadd[INET_ADDRSTRLEN]; /* saves the Host Address for IPv4 */
string readall;
ns_msg msg; /* handle for response message */
ns_rr rr; /* expanded resource record */
int i, j, l;
char * hostname=argv[1];
/*
* Look up the records for the given domain name.
* We expect the domain name to be a fully qualified, so
* we use res_query( ). If we'd wanted the resolver search
* algorithm, we would have used res_search( ) instead.
*/
//l=res_search (argv[i], ns_c_any, ns_t_a, nsbuf, sizeof (nsbuf));
l = res_query ( hostname, /* domain name */
ns_c_any, /* Internet class records */
ns_t_a, /* Look up Host address */
nsbuf, /*response buffer*/
sizeof (nsbuf) /*buffer size */
);
if (l < 0) {
perror (hostname);
} else {
/*
* Initialize a handle to this response. The handle will
* be used later to extract information from the response.
*/
ns_initparse (nsbuf, l, &msg);
/* Count total answers received in the record. */
l = ns_msg_count (msg, ns_s_an);
for (j = 0; j < l; j++) {
/*
* Expand the answer section record into rr.
*/
ns_parserr (&msg, ns_s_an, j, &rr);
/* fill the buffer with the record data */
ns_sprintrr (&msg, &rr, NULL, NULL, dispbuf, sizeof (dispbuf));
/* ns_sprintrrf(ns_msg_base(msg), ns_msg_size(msg),ns_rr_name(rr), ns_rr_class(rr),
ns_rr_type(rr),ns_rr_ttl(rr), ns_rr_rdata(rr), ns_rr_rdlen(rr),NULL, NULL, dispbuf,sizeof(dispbuf));
printf ("%s\n", dispbuf);
*/
cout<<dispbuf<<endl;
/* Get the Host IP Address */
inet_ntop(AF_INET,ns_rr_rdata(rr),ipadd,INET_ADDRSTRLEN);
// printf("%s\n",ipadd);
readall += ipadd;
readall.erase(remove(readall.begin(), readall.end(), '\n'), readall.end());
readall.append(";");
//cout<<ipadd<<endl;
}
cout<<readall<<endl;
}
}
Complie & Link: g++ socket.cpp -o socket_pgm /usr/lib64/libresolv.a
Execute: ./socket_pgm <hostname>
./socket_pgm www.google.com
Enjoy............. :-)