Theory
The whois information of an ip address provides various details like its network, range, isp etc.
This information is maintained by various regional registry servers.
Read the wikipedia article on regional internet registries for more information.
There are a total of 5 regional registries spanning various geographical regions of the world. For example if an ip address is allocated to some isp in USA then the ARIN registry would provide its whois information.
To get the whois data of an ip address, all that needs to be done is to query the particular registry server and send a query.
However first we need to know under registry is the ip address currently allocated. The iana whois server has this information and will provide us for free.
So first whois.iana.org is queried to find out the regional internet registry of the specified IP address.
Then the whois server of the corresponding RIR is queried to get the actual whois information about the ip.
Code
Following is a whois program implemented in C. Note that it will work on Linux.
/* This program shall fetch whois data for a IPv4 address. */ #include <stdio.h> //scanf , printf #include <string.h> //strtok #include <stdlib.h> //realloc #include <sys/socket.h> //socket #include <netinet/in.h> //sockaddr_in #include <arpa/inet.h> //getsockname #include <netdb.h> //hostent #include <unistd.h> //close void get_whois(char *ip , char **data); int whois_query(char *server , char *query , char **response); int hostname_to_ip(char * hostname , char* ip); int main(int argc , char *argv[]) { char ip[100] , *data = NULL; printf("Enter ip address to whois : "); scanf("%s" , ip); get_whois(ip , &data); printf("\n\n"); puts(data); free(data); return EXIT_SUCCESS; } /* Get the whois content of an ip by selecting the correct server */ void get_whois(char *ip , char **data) { char *wch = NULL, *pch , *response = NULL; if(whois_query("whois.iana.org" , ip , &response)) { printf("Whois query failed"); } pch = strtok(response , "\n"); while(pch != NULL) { //Check if whois line wch = strstr(pch , "whois."); if(wch != NULL) { break; } //Next line please pch = strtok(NULL , "\n"); } if(wch != NULL) { printf("\nWhois server is : %s" , wch); whois_query(wch , ip , data); } else { *data = malloc(100); strcpy(*data , "No whois data"); } return; } /* Perform a whois query to a server and record the response */ int whois_query(char *server , char *query , char **response) { char ip[32] , message[100] , buffer[1500]; int sock , read_size , total_size = 0; struct sockaddr_in dest; sock = socket(AF_INET , SOCK_STREAM , IPPROTO_TCP); //Prepare connection structures :) memset( &dest , 0 , sizeof(dest) ); dest.sin_family = AF_INET; printf("\nResolving %s..." , server); if(hostname_to_ip(server , ip)) { printf("Failed"); return EXIT_FAILURE; } printf("%s" , ip); dest.sin_addr.s_addr = inet_addr( ip ); dest.sin_port = htons( 43 ); //Now connect to remote server if(connect( sock , (const struct sockaddr*) &dest , sizeof(dest) ) < 0) { perror("connect failed"); } //Now send some data or message printf("\nQuerying for ... %s ..." , query); sprintf(message , "%s\r\n" , query); if( send(sock , message , strlen(message) , 0) < 0) { perror("send failed"); } // Now receive the response while( (read_size = recv(sock , buffer , sizeof(buffer) , 0) ) ) { *response = realloc(*response , read_size + total_size); if(*response == NULL) { printf("realloc failed"); } memcpy(*response + total_size , buffer , read_size); total_size += read_size; } printf("Done"); fflush(stdout); *response = realloc(*response , total_size + 1); *(*response + total_size) = '/* This program shall fetch whois data for a IPv4 address. */ #include <stdio.h> //scanf , printf #include <string.h> //strtok #include <stdlib.h> //realloc #include <sys/socket.h> //socket #include <netinet/in.h> //sockaddr_in #include <arpa/inet.h> //getsockname #include <netdb.h> //hostent #include <unistd.h> //close void get_whois(char *ip , char **data); int whois_query(char *server , char *query , char **response); int hostname_to_ip(char * hostname , char* ip); int main(int argc , char *argv[]) { char ip[100] , *data = NULL; printf("Enter ip address to whois : "); scanf("%s" , ip); get_whois(ip , &data); printf("\n\n"); puts(data); free(data); return EXIT_SUCCESS; } /* Get the whois content of an ip by selecting the correct server */ void get_whois(char *ip , char **data) { char *wch = NULL, *pch , *response = NULL; if(whois_query("whois.iana.org" , ip , &response)) { printf("Whois query failed"); } pch = strtok(response , "\n"); while(pch != NULL) { //Check if whois line wch = strstr(pch , "whois."); if(wch != NULL) { break; } //Next line please pch = strtok(NULL , "\n"); } if(wch != NULL) { printf("\nWhois server is : %s" , wch); whois_query(wch , ip , data); } else { *data = malloc(100); strcpy(*data , "No whois data"); } return; } /* Perform a whois query to a server and record the response */ int whois_query(char *server , char *query , char **response) { char ip[32] , message[100] , buffer[1500]; int sock , read_size , total_size = 0; struct sockaddr_in dest; sock = socket(AF_INET , SOCK_STREAM , IPPROTO_TCP); //Prepare connection structures :) memset( &dest , 0 , sizeof(dest) ); dest.sin_family = AF_INET; printf("\nResolving %s..." , server); if(hostname_to_ip(server , ip)) { printf("Failed"); return EXIT_FAILURE; } printf("%s" , ip); dest.sin_addr.s_addr = inet_addr( ip ); dest.sin_port = htons( 43 ); //Now connect to remote server if(connect( sock , (const struct sockaddr*) &dest , sizeof(dest) ) < 0) { perror("connect failed"); } //Now send some data or message printf("\nQuerying for ... %s ..." , query); sprintf(message , "%s\r\n" , query); if( send(sock , message , strlen(message) , 0) < 0) { perror("send failed"); } // Now receive the response while( (read_size = recv(sock , buffer , sizeof(buffer) , 0) ) ) { *response = realloc(*response , read_size + total_size); if(*response == NULL) { printf("realloc failed"); } memcpy(*response + total_size , buffer , read_size); total_size += read_size; } printf("Done"); fflush(stdout); *response = realloc(*response , total_size + 1); *(*response + total_size) = '\0'; close(sock); return 0; } /* Get the ip address of a given hostname */ int hostname_to_ip(char * hostname , char* ip) { struct hostent *he; struct in_addr **addr_list; int i; if ( (he = gethostbyname( hostname ) ) == NULL) { // get the host info herror("gethostbyname"); return EXIT_FAILURE; } addr_list = (struct in_addr **) he->h_addr_list; for(i = 0; addr_list[i] != NULL; i++) { //Return the first one; strcpy(ip , inet_ntoa(*addr_list[i]) ); return EXIT_SUCCESS; } return EXIT_SUCCESS; }'; close(sock); return 0; } /* Get the ip address of a given hostname */ int hostname_to_ip(char * hostname , char* ip) { struct hostent *he; struct in_addr **addr_list; int i; if ( (he = gethostbyname( hostname ) ) == NULL) { // get the host info herror("gethostbyname"); return EXIT_FAILURE; } addr_list = (struct in_addr **) he->h_addr_list; for(i = 0; addr_list[i] != NULL; i++) { //Return the first one; strcpy(ip , inet_ntoa(*addr_list[i]) ); return EXIT_SUCCESS; } return EXIT_SUCCESS; }
Compile and Run
The gcc compiler can be used to compile the program. So start a terminal and issue the following command. It will compile the above program and also run it.
$ gcc whois_ip.c
It first asks for an ip address and then tries to retrive its whois information as described in the theory previously.
$ ./a.out Enter ip address to whois : 77.65.12.44 Resolving whois.iana.org...192.0.32.59 Querying for ... 77.65.12.44 ...Done Whois server is : whois.ripe.net Resolving whois.ripe.net...193.0.6.135 Querying for ... 77.65.12.44 ...Done % This is the RIPE Database query service. % The objects are in RPSL format. % % The RIPE Database is subject to Terms and Conditions. % See http://www.ripe.net/db/support/db-terms-conditions.pdf % Note: this output has been filtered. % To receive output for a database update, use the "-B" flag. % Information related to '77.65.0.0 - 77.65.23.255' % Abuse contact for '77.65.0.0 - 77.65.23.255' is '[email protected]' inetnum: 77.65.0.0 - 77.65.23.255 netname: ICPNET-5 descr: ICP Network descr: static assignment address space country: PL admin-c: INEA-RIPE tech-c: INEA-RIPE status: ASSIGNED PA mnt-by: INEA-MNT mnt-lower: INEA-MNT mnt-routes: INEA-MNT created: 2010-12-01T15:14:27Z last-modified: 2015-01-09T14:19:28Z source: RIPE role: INEA S.A. address: ul. Klaudyny Potockiej 25 address: 60-211 Poznan nic-hdl: INEA-RIPE mnt-by: INEA-MNT admin-c: PA7317-RIPE tech-c: PA7317-RIPE tech-c: PSZY created: 2014-07-14T09:26:21Z last-modified: 2015-01-21T10:25:56Z source: RIPE # Filtered % Information related to '77.65.0.0/17AS13110' route: 77.65.0.0/17 descr: INEA S.A. descr: Poznan origin: AS13110 mnt-by: INEA-MNT created: 2007-02-12T09:03:39Z last-modified: 2015-01-27T10:14:29Z source: RIPE % This query was served by the RIPE Database Query Service version 1.97.2 (HEREFORD)
The part from "% This is the RIPE Database query service." is the whois information.
Conclusion
Just like ip addresses, domains also have whois information. The process to find the whois information of a domain is also quite similar to the above one.
Check out the following post
How to Get Domain Whois Data in C with Sockets on Linux - Code ExampleFurther Reading:
http://en.wikipedia.org/wiki/Regional_Internet_registry