Whois
A whois client is a program that will simply fetch the whois information for a domain/ip address from the whois servers. The code over here works according to the algorithm discussed here.
A whois server runs a whois service on port 43 (whois port). We need to connect to this port with sockets and send the domain name for which we want the details.
The first step is to find the whois server and then connect to it and make the query.
Whois Servers
To get the full whois data of a domain, there are several whois servers that need to be queried. For example if the domain name is wikipedia.org then the following whois servers are involved:
1. whois.iana.org will tell the authoritative whois server for the domain extension. In this case the extension is .org so the authoritative whois server is whois.pir.org.
2. Next contact the authoritative whois server to find the registrant whois server of the particular domain. In this case the registrant of wikipedia.org is MarkMonitor so the whois server is whois.markmonitor.com
3. Finally contact the registrant whois server for actual whois data of the domain. Here the registrant whois server is whois.markmonitor.com
Code
/* This program shall perform whois for a domain and get you the whois data of that domain */ #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 int get_whois_data(char * , char **); int hostname_to_ip(char * , char *); int whois_query(char * , char * , char **); char *str_replace(char *search , char *replace , char *subject ); char* str_copy(char*); int main(int argc , char *argv[]) { char *domain , *data = NULL; printf("Enter domain name to whois: "); scanf("%s" , domain); get_whois_data(domain , &data); //puts(data); return EXIT_SUCCESS; } /* Get the whois data of a domain */ int get_whois_data(char *domain , char **data) { char ext[1024] , *pch , *response = NULL , *response_2 = NULL , *wch , *dt; //remove "http://" and "www." domain = str_replace("http://" , "" , domain); domain = str_replace("www." , "" , domain); //get the extension , com , org , edu dt = strdup(domain); if(dt == NULL) { printf("strdup failed"); } pch = (char*)strtok(dt , "."); while(pch != NULL) { strcpy(ext , pch); pch = strtok(NULL , "."); } // This will tell the whois server for the particular TLD like com , org if( whois_query("whois.iana.org" , ext , &response) == EXIT_FAILURE) { printf("Whois query failed"); return 1; } printf("\n\nResponse is:\n\n"); printf("%s", response); // Now analysze the response 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"); } // Now we have the TLD whois server in wch , query again //This will provide minimal whois information along with the parent whois server of the specific domain :) free(response); //This should not be necessary , but segmentation fault without this , why ? response = NULL; if(wch != NULL) { printf("\nTLD Whois server is : %s" , wch); //wch[strcspn(wch, "\r\n")] = '/* This program shall perform whois for a domain and get you the whois data of that domain */ #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 int get_whois_data(char * , char **); int hostname_to_ip(char * , char *); int whois_query(char * , char * , char **); char *str_replace(char *search , char *replace , char *subject ); char* str_copy(char*); int main(int argc , char *argv[]) { char *domain , *data = NULL; printf("Enter domain name to whois: "); scanf("%s" , domain); get_whois_data(domain , &data); //puts(data); return EXIT_SUCCESS; } /* Get the whois data of a domain */ int get_whois_data(char *domain , char **data) { char ext[1024] , *pch , *response = NULL , *response_2 = NULL , *wch , *dt; //remove "http://" and "www." domain = str_replace("http://" , "" , domain); domain = str_replace("www." , "" , domain); //get the extension , com , org , edu dt = strdup(domain); if(dt == NULL) { printf("strdup failed"); } pch = (char*)strtok(dt , "."); while(pch != NULL) { strcpy(ext , pch); pch = strtok(NULL , "."); } // This will tell the whois server for the particular TLD like com , org if( whois_query("whois.iana.org" , ext , &response) == EXIT_FAILURE) { printf("Whois query failed"); return 1; } printf("\n\nResponse is:\n\n"); printf("%s", response); // Now analysze the response 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"); } // Now we have the TLD whois server in wch , query again //This will provide minimal whois information along with the parent whois server of the specific domain :) free(response); //This should not be necessary , but segmentation fault without this , why ? response = NULL; if(wch != NULL) { printf("\nTLD Whois server is : %s" , wch); //wch[strcspn(wch, "\r\n")] = '\0'; if( whois_query(wch , domain , &response) == EXIT_FAILURE) { printf("Whois query failed\n"); return EXIT_FAILURE; } } else { printf("\nTLD whois server for %s not found\n" , ext); return EXIT_SUCCESS; } response_2 = strdup(response); // Again search for a whois server in this response. :) 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 a registrar whois server is found then query it */ if(wch) { // Now we have the registrar whois server , this has the direct full information of the particular domain // so lets query again printf("\nRegistrar Whois server is : %s" , wch); if( whois_query(wch , domain , &response) == EXIT_FAILURE ) { printf("Whois query failed"); } else { printf("\n%s" , response); } } /* otherwise echo the output from the previous whois result */ else { printf("%s" , response_2); } return 0; } /* 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; int WHOIS_PORT = 43; 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; server = str_copy(server); server[strcspn(server, "\r\n")] = '\0'; printf("\nResolving: %s ...\n" , server); if( hostname_to_ip(server , ip) == EXIT_FAILURE ) { printf("Failed\n"); return EXIT_FAILURE; } printf("Found ip: %s \n" , ip); dest.sin_addr.s_addr = inet_addr( ip ); dest.sin_port = htons( WHOIS_PORT ); //Now connect to remote server if(connect( sock , (const struct sockaddr*) &dest , sizeof(dest) ) < 0) { perror("connect failed"); return EXIT_FAILURE; } //Now send some data or message printf("\nQuerying for: %s ...\n" , query); sprintf(message , "%s\r\n" , query); if( send(sock , message , strlen(message) , 0) < 0) { perror("send failed"); return EXIT_FAILURE; } //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"); return EXIT_FAILURE; } memcpy(*response + total_size , buffer , read_size); total_size += read_size; } printf("Done\n"); fflush(stdout); *response = realloc(*response , total_size + 1); *(*response + total_size) = '\0'; close(sock); return EXIT_SUCCESS; } /* 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; // create editable copy hostname = str_copy(hostname); // remove trailing LF CR hostname[strcspn(hostname, "\r\n")] = '\0'; if ( (he = gethostbyname( hostname ) ) == NULL) { // print the error herror("Error in gethostbyname: "); return EXIT_FAILURE; } if(he) { 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 0; } /* Search and replace a string with another string , in a string */ char *str_replace(char *search , char *replace , char *subject) { char *p = NULL , *old = NULL , *new_subject = NULL ; int c = 0 , search_size; search_size = strlen(search); //Count how many occurences for(p = strstr(subject , search) ; p != NULL ; p = strstr(p + search_size , search)) { c++; } //Final size c = ( strlen(replace) - search_size )*c + strlen(subject); //New subject with new size new_subject = malloc( c ); //Set it to blank strcpy(new_subject , ""); //The start position old = subject; for(p = strstr(subject , search) ; p != NULL ; p = strstr(p + search_size , search)) { //move ahead and copy some text from original subject , from a certain position strncpy(new_subject + strlen(new_subject) , old , p - old); //move ahead and copy the replacement text strcpy(new_subject + strlen(new_subject) , replace); //The new start position after this search match old = p + search_size; } //Copy the part after the last search match strcpy(new_subject + strlen(new_subject) , old); return new_subject; } char* str_copy(char *source) { char *copy = malloc(strlen(source) + 1); if(copy) { strcpy(copy, source); } return copy; }'; if( whois_query(wch , domain , &response) == EXIT_FAILURE) { printf("Whois query failed\n"); return EXIT_FAILURE; } } else { printf("\nTLD whois server for %s not found\n" , ext); return EXIT_SUCCESS; } response_2 = strdup(response); // Again search for a whois server in this response. :) 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 a registrar whois server is found then query it */ if(wch) { // Now we have the registrar whois server , this has the direct full information of the particular domain // so lets query again printf("\nRegistrar Whois server is : %s" , wch); if( whois_query(wch , domain , &response) == EXIT_FAILURE ) { printf("Whois query failed"); } else { printf("\n%s" , response); } } /* otherwise echo the output from the previous whois result */ else { printf("%s" , response_2); } return 0; } /* 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; int WHOIS_PORT = 43; 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; server = str_copy(server); server[strcspn(server, "\r\n")] = '/* This program shall perform whois for a domain and get you the whois data of that domain */ #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 int get_whois_data(char * , char **); int hostname_to_ip(char * , char *); int whois_query(char * , char * , char **); char *str_replace(char *search , char *replace , char *subject ); char* str_copy(char*); int main(int argc , char *argv[]) { char *domain , *data = NULL; printf("Enter domain name to whois: "); scanf("%s" , domain); get_whois_data(domain , &data); //puts(data); return EXIT_SUCCESS; } /* Get the whois data of a domain */ int get_whois_data(char *domain , char **data) { char ext[1024] , *pch , *response = NULL , *response_2 = NULL , *wch , *dt; //remove "http://" and "www." domain = str_replace("http://" , "" , domain); domain = str_replace("www." , "" , domain); //get the extension , com , org , edu dt = strdup(domain); if(dt == NULL) { printf("strdup failed"); } pch = (char*)strtok(dt , "."); while(pch != NULL) { strcpy(ext , pch); pch = strtok(NULL , "."); } // This will tell the whois server for the particular TLD like com , org if( whois_query("whois.iana.org" , ext , &response) == EXIT_FAILURE) { printf("Whois query failed"); return 1; } printf("\n\nResponse is:\n\n"); printf("%s", response); // Now analysze the response 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"); } // Now we have the TLD whois server in wch , query again //This will provide minimal whois information along with the parent whois server of the specific domain :) free(response); //This should not be necessary , but segmentation fault without this , why ? response = NULL; if(wch != NULL) { printf("\nTLD Whois server is : %s" , wch); //wch[strcspn(wch, "\r\n")] = '\0'; if( whois_query(wch , domain , &response) == EXIT_FAILURE) { printf("Whois query failed\n"); return EXIT_FAILURE; } } else { printf("\nTLD whois server for %s not found\n" , ext); return EXIT_SUCCESS; } response_2 = strdup(response); // Again search for a whois server in this response. :) 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 a registrar whois server is found then query it */ if(wch) { // Now we have the registrar whois server , this has the direct full information of the particular domain // so lets query again printf("\nRegistrar Whois server is : %s" , wch); if( whois_query(wch , domain , &response) == EXIT_FAILURE ) { printf("Whois query failed"); } else { printf("\n%s" , response); } } /* otherwise echo the output from the previous whois result */ else { printf("%s" , response_2); } return 0; } /* 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; int WHOIS_PORT = 43; 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; server = str_copy(server); server[strcspn(server, "\r\n")] = '\0'; printf("\nResolving: %s ...\n" , server); if( hostname_to_ip(server , ip) == EXIT_FAILURE ) { printf("Failed\n"); return EXIT_FAILURE; } printf("Found ip: %s \n" , ip); dest.sin_addr.s_addr = inet_addr( ip ); dest.sin_port = htons( WHOIS_PORT ); //Now connect to remote server if(connect( sock , (const struct sockaddr*) &dest , sizeof(dest) ) < 0) { perror("connect failed"); return EXIT_FAILURE; } //Now send some data or message printf("\nQuerying for: %s ...\n" , query); sprintf(message , "%s\r\n" , query); if( send(sock , message , strlen(message) , 0) < 0) { perror("send failed"); return EXIT_FAILURE; } //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"); return EXIT_FAILURE; } memcpy(*response + total_size , buffer , read_size); total_size += read_size; } printf("Done\n"); fflush(stdout); *response = realloc(*response , total_size + 1); *(*response + total_size) = '\0'; close(sock); return EXIT_SUCCESS; } /* 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; // create editable copy hostname = str_copy(hostname); // remove trailing LF CR hostname[strcspn(hostname, "\r\n")] = '\0'; if ( (he = gethostbyname( hostname ) ) == NULL) { // print the error herror("Error in gethostbyname: "); return EXIT_FAILURE; } if(he) { 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 0; } /* Search and replace a string with another string , in a string */ char *str_replace(char *search , char *replace , char *subject) { char *p = NULL , *old = NULL , *new_subject = NULL ; int c = 0 , search_size; search_size = strlen(search); //Count how many occurences for(p = strstr(subject , search) ; p != NULL ; p = strstr(p + search_size , search)) { c++; } //Final size c = ( strlen(replace) - search_size )*c + strlen(subject); //New subject with new size new_subject = malloc( c ); //Set it to blank strcpy(new_subject , ""); //The start position old = subject; for(p = strstr(subject , search) ; p != NULL ; p = strstr(p + search_size , search)) { //move ahead and copy some text from original subject , from a certain position strncpy(new_subject + strlen(new_subject) , old , p - old); //move ahead and copy the replacement text strcpy(new_subject + strlen(new_subject) , replace); //The new start position after this search match old = p + search_size; } //Copy the part after the last search match strcpy(new_subject + strlen(new_subject) , old); return new_subject; } char* str_copy(char *source) { char *copy = malloc(strlen(source) + 1); if(copy) { strcpy(copy, source); } return copy; }'; printf("\nResolving: %s ...\n" , server); if( hostname_to_ip(server , ip) == EXIT_FAILURE ) { printf("Failed\n"); return EXIT_FAILURE; } printf("Found ip: %s \n" , ip); dest.sin_addr.s_addr = inet_addr( ip ); dest.sin_port = htons( WHOIS_PORT ); //Now connect to remote server if(connect( sock , (const struct sockaddr*) &dest , sizeof(dest) ) < 0) { perror("connect failed"); return EXIT_FAILURE; } //Now send some data or message printf("\nQuerying for: %s ...\n" , query); sprintf(message , "%s\r\n" , query); if( send(sock , message , strlen(message) , 0) < 0) { perror("send failed"); return EXIT_FAILURE; } //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"); return EXIT_FAILURE; } memcpy(*response + total_size , buffer , read_size); total_size += read_size; } printf("Done\n"); fflush(stdout); *response = realloc(*response , total_size + 1); *(*response + total_size) = '/* This program shall perform whois for a domain and get you the whois data of that domain */ #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 int get_whois_data(char * , char **); int hostname_to_ip(char * , char *); int whois_query(char * , char * , char **); char *str_replace(char *search , char *replace , char *subject ); char* str_copy(char*); int main(int argc , char *argv[]) { char *domain , *data = NULL; printf("Enter domain name to whois: "); scanf("%s" , domain); get_whois_data(domain , &data); //puts(data); return EXIT_SUCCESS; } /* Get the whois data of a domain */ int get_whois_data(char *domain , char **data) { char ext[1024] , *pch , *response = NULL , *response_2 = NULL , *wch , *dt; //remove "http://" and "www." domain = str_replace("http://" , "" , domain); domain = str_replace("www." , "" , domain); //get the extension , com , org , edu dt = strdup(domain); if(dt == NULL) { printf("strdup failed"); } pch = (char*)strtok(dt , "."); while(pch != NULL) { strcpy(ext , pch); pch = strtok(NULL , "."); } // This will tell the whois server for the particular TLD like com , org if( whois_query("whois.iana.org" , ext , &response) == EXIT_FAILURE) { printf("Whois query failed"); return 1; } printf("\n\nResponse is:\n\n"); printf("%s", response); // Now analysze the response 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"); } // Now we have the TLD whois server in wch , query again //This will provide minimal whois information along with the parent whois server of the specific domain :) free(response); //This should not be necessary , but segmentation fault without this , why ? response = NULL; if(wch != NULL) { printf("\nTLD Whois server is : %s" , wch); //wch[strcspn(wch, "\r\n")] = '\0'; if( whois_query(wch , domain , &response) == EXIT_FAILURE) { printf("Whois query failed\n"); return EXIT_FAILURE; } } else { printf("\nTLD whois server for %s not found\n" , ext); return EXIT_SUCCESS; } response_2 = strdup(response); // Again search for a whois server in this response. :) 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 a registrar whois server is found then query it */ if(wch) { // Now we have the registrar whois server , this has the direct full information of the particular domain // so lets query again printf("\nRegistrar Whois server is : %s" , wch); if( whois_query(wch , domain , &response) == EXIT_FAILURE ) { printf("Whois query failed"); } else { printf("\n%s" , response); } } /* otherwise echo the output from the previous whois result */ else { printf("%s" , response_2); } return 0; } /* 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; int WHOIS_PORT = 43; 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; server = str_copy(server); server[strcspn(server, "\r\n")] = '\0'; printf("\nResolving: %s ...\n" , server); if( hostname_to_ip(server , ip) == EXIT_FAILURE ) { printf("Failed\n"); return EXIT_FAILURE; } printf("Found ip: %s \n" , ip); dest.sin_addr.s_addr = inet_addr( ip ); dest.sin_port = htons( WHOIS_PORT ); //Now connect to remote server if(connect( sock , (const struct sockaddr*) &dest , sizeof(dest) ) < 0) { perror("connect failed"); return EXIT_FAILURE; } //Now send some data or message printf("\nQuerying for: %s ...\n" , query); sprintf(message , "%s\r\n" , query); if( send(sock , message , strlen(message) , 0) < 0) { perror("send failed"); return EXIT_FAILURE; } //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"); return EXIT_FAILURE; } memcpy(*response + total_size , buffer , read_size); total_size += read_size; } printf("Done\n"); fflush(stdout); *response = realloc(*response , total_size + 1); *(*response + total_size) = '\0'; close(sock); return EXIT_SUCCESS; } /* 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; // create editable copy hostname = str_copy(hostname); // remove trailing LF CR hostname[strcspn(hostname, "\r\n")] = '\0'; if ( (he = gethostbyname( hostname ) ) == NULL) { // print the error herror("Error in gethostbyname: "); return EXIT_FAILURE; } if(he) { 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 0; } /* Search and replace a string with another string , in a string */ char *str_replace(char *search , char *replace , char *subject) { char *p = NULL , *old = NULL , *new_subject = NULL ; int c = 0 , search_size; search_size = strlen(search); //Count how many occurences for(p = strstr(subject , search) ; p != NULL ; p = strstr(p + search_size , search)) { c++; } //Final size c = ( strlen(replace) - search_size )*c + strlen(subject); //New subject with new size new_subject = malloc( c ); //Set it to blank strcpy(new_subject , ""); //The start position old = subject; for(p = strstr(subject , search) ; p != NULL ; p = strstr(p + search_size , search)) { //move ahead and copy some text from original subject , from a certain position strncpy(new_subject + strlen(new_subject) , old , p - old); //move ahead and copy the replacement text strcpy(new_subject + strlen(new_subject) , replace); //The new start position after this search match old = p + search_size; } //Copy the part after the last search match strcpy(new_subject + strlen(new_subject) , old); return new_subject; } char* str_copy(char *source) { char *copy = malloc(strlen(source) + 1); if(copy) { strcpy(copy, source); } return copy; }'; close(sock); return EXIT_SUCCESS; } /* 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; // create editable copy hostname = str_copy(hostname); // remove trailing LF CR hostname[strcspn(hostname, "\r\n")] = '/* This program shall perform whois for a domain and get you the whois data of that domain */ #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 int get_whois_data(char * , char **); int hostname_to_ip(char * , char *); int whois_query(char * , char * , char **); char *str_replace(char *search , char *replace , char *subject ); char* str_copy(char*); int main(int argc , char *argv[]) { char *domain , *data = NULL; printf("Enter domain name to whois: "); scanf("%s" , domain); get_whois_data(domain , &data); //puts(data); return EXIT_SUCCESS; } /* Get the whois data of a domain */ int get_whois_data(char *domain , char **data) { char ext[1024] , *pch , *response = NULL , *response_2 = NULL , *wch , *dt; //remove "http://" and "www." domain = str_replace("http://" , "" , domain); domain = str_replace("www." , "" , domain); //get the extension , com , org , edu dt = strdup(domain); if(dt == NULL) { printf("strdup failed"); } pch = (char*)strtok(dt , "."); while(pch != NULL) { strcpy(ext , pch); pch = strtok(NULL , "."); } // This will tell the whois server for the particular TLD like com , org if( whois_query("whois.iana.org" , ext , &response) == EXIT_FAILURE) { printf("Whois query failed"); return 1; } printf("\n\nResponse is:\n\n"); printf("%s", response); // Now analysze the response 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"); } // Now we have the TLD whois server in wch , query again //This will provide minimal whois information along with the parent whois server of the specific domain :) free(response); //This should not be necessary , but segmentation fault without this , why ? response = NULL; if(wch != NULL) { printf("\nTLD Whois server is : %s" , wch); //wch[strcspn(wch, "\r\n")] = '\0'; if( whois_query(wch , domain , &response) == EXIT_FAILURE) { printf("Whois query failed\n"); return EXIT_FAILURE; } } else { printf("\nTLD whois server for %s not found\n" , ext); return EXIT_SUCCESS; } response_2 = strdup(response); // Again search for a whois server in this response. :) 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 a registrar whois server is found then query it */ if(wch) { // Now we have the registrar whois server , this has the direct full information of the particular domain // so lets query again printf("\nRegistrar Whois server is : %s" , wch); if( whois_query(wch , domain , &response) == EXIT_FAILURE ) { printf("Whois query failed"); } else { printf("\n%s" , response); } } /* otherwise echo the output from the previous whois result */ else { printf("%s" , response_2); } return 0; } /* 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; int WHOIS_PORT = 43; 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; server = str_copy(server); server[strcspn(server, "\r\n")] = '\0'; printf("\nResolving: %s ...\n" , server); if( hostname_to_ip(server , ip) == EXIT_FAILURE ) { printf("Failed\n"); return EXIT_FAILURE; } printf("Found ip: %s \n" , ip); dest.sin_addr.s_addr = inet_addr( ip ); dest.sin_port = htons( WHOIS_PORT ); //Now connect to remote server if(connect( sock , (const struct sockaddr*) &dest , sizeof(dest) ) < 0) { perror("connect failed"); return EXIT_FAILURE; } //Now send some data or message printf("\nQuerying for: %s ...\n" , query); sprintf(message , "%s\r\n" , query); if( send(sock , message , strlen(message) , 0) < 0) { perror("send failed"); return EXIT_FAILURE; } //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"); return EXIT_FAILURE; } memcpy(*response + total_size , buffer , read_size); total_size += read_size; } printf("Done\n"); fflush(stdout); *response = realloc(*response , total_size + 1); *(*response + total_size) = '\0'; close(sock); return EXIT_SUCCESS; } /* 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; // create editable copy hostname = str_copy(hostname); // remove trailing LF CR hostname[strcspn(hostname, "\r\n")] = '\0'; if ( (he = gethostbyname( hostname ) ) == NULL) { // print the error herror("Error in gethostbyname: "); return EXIT_FAILURE; } if(he) { 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 0; } /* Search and replace a string with another string , in a string */ char *str_replace(char *search , char *replace , char *subject) { char *p = NULL , *old = NULL , *new_subject = NULL ; int c = 0 , search_size; search_size = strlen(search); //Count how many occurences for(p = strstr(subject , search) ; p != NULL ; p = strstr(p + search_size , search)) { c++; } //Final size c = ( strlen(replace) - search_size )*c + strlen(subject); //New subject with new size new_subject = malloc( c ); //Set it to blank strcpy(new_subject , ""); //The start position old = subject; for(p = strstr(subject , search) ; p != NULL ; p = strstr(p + search_size , search)) { //move ahead and copy some text from original subject , from a certain position strncpy(new_subject + strlen(new_subject) , old , p - old); //move ahead and copy the replacement text strcpy(new_subject + strlen(new_subject) , replace); //The new start position after this search match old = p + search_size; } //Copy the part after the last search match strcpy(new_subject + strlen(new_subject) , old); return new_subject; } char* str_copy(char *source) { char *copy = malloc(strlen(source) + 1); if(copy) { strcpy(copy, source); } return copy; }'; if ( (he = gethostbyname( hostname ) ) == NULL) { // print the error herror("Error in gethostbyname: "); return EXIT_FAILURE; } if(he) { 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 0; } /* Search and replace a string with another string , in a string */ char *str_replace(char *search , char *replace , char *subject) { char *p = NULL , *old = NULL , *new_subject = NULL ; int c = 0 , search_size; search_size = strlen(search); //Count how many occurences for(p = strstr(subject , search) ; p != NULL ; p = strstr(p + search_size , search)) { c++; } //Final size c = ( strlen(replace) - search_size )*c + strlen(subject); //New subject with new size new_subject = malloc( c ); //Set it to blank strcpy(new_subject , ""); //The start position old = subject; for(p = strstr(subject , search) ; p != NULL ; p = strstr(p + search_size , search)) { //move ahead and copy some text from original subject , from a certain position strncpy(new_subject + strlen(new_subject) , old , p - old); //move ahead and copy the replacement text strcpy(new_subject + strlen(new_subject) , replace); //The new start position after this search match old = p + search_size; } //Copy the part after the last search match strcpy(new_subject + strlen(new_subject) , old); return new_subject; } char* str_copy(char *source) { char *copy = malloc(strlen(source) + 1); if(copy) { strcpy(copy, source); } return copy; }
hostname_to_ip - This is a simple function to get an IP of a domain.
str_replace - This is a generic string processing function that is used to search for a string in another big string and replace it with another string.
Compile and Run
Compiling is simple, just use the gcc command. Then run the output file and it will ask for the domain name.
$ gcc whois.c $ ./a.out Enter domain name to whois:
Output
The output would look something like this:
$ ./a.out Enter domain name to whois: wikipedia.org Resolving: whois.iana.org ... Found ip: 192.0.32.59 Querying for: org ... Done Response is: % IANA WHOIS server % for more information on IANA, visit http://www.iana.org % This query returned 1 object domain: ORG organisation: Public Interest Registry (PIR) address: 1775 Wiehle Avenue address: Suite 100 address: Reston Virginia 20190 address: United States contact: administrative name: Director of Operations, Compliance and Customer Support organisation: Public Interest Registry (PIR) address: 1775 Wiehle Avenue address: Reston Virginia 20190 address: United States phone: +1 703 889 5778 fax-no: +1 703 889 5779 e-mail: [email protected] contact: technical name: Senior Director, DNS Infrastructure Group organisation: Afilias address: Building 3, Suite 105 address: 300 Welsh Road address: Horsham, Pennsylvania 19044 address: United States phone: +1 215.706.5700 fax-no: +1 215.706.5701 e-mail: [email protected] nserver: A0.ORG.AFILIAS-NST.INFO 199.19.56.1 2001:500:e:0:0:0:0:1 nserver: A2.ORG.AFILIAS-NST.INFO 199.249.112.1 2001:500:40:0:0:0:0:1 nserver: B0.ORG.AFILIAS-NST.ORG 199.19.54.1 2001:500:c:0:0:0:0:1 nserver: B2.ORG.AFILIAS-NST.ORG 199.249.120.1 2001:500:48:0:0:0:0:1 nserver: C0.ORG.AFILIAS-NST.INFO 199.19.53.1 2001:500:b:0:0:0:0:1 nserver: D0.ORG.AFILIAS-NST.ORG 199.19.57.1 2001:500:f:0:0:0:0:1 ds-rdata: 17883 7 2 d889cad790f01979e860d6627b58f85ab554e0e491fe06515f35548d1eb4e6ee ds-rdata: 17883 7 1 38c5cf93b369c7557e0515faaa57060f1bfb12c1 whois: whois.pir.org status: ACTIVE remarks: Registration information: http://www.pir.org created: 1985-01-01 changed: 2020-04-29 source: IANA TLD Whois server is : whois.pir.org Resolving: whois.pir.org ... Found ip: 199.15.84.131 Querying for: wikipedia.org ... Done Registrar Whois server is : whois.markmonitor.com Resolving: whois.markmonitor.com ... Found ip: 64.124.14.21 Querying for: wikipedia.org ... Done Domain Name: wikipedia.org Registry Domain ID: D51687756-LROR Registrar WHOIS Server: whois.markmonitor.com Registrar URL: http://www.markmonitor.com Updated Date: 2015-12-12T02:16:20-0800 Creation Date: 2001-01-12T16:12:14-0800 Registrar Registration Expiration Date: 2023-01-12T00:00:00-0800 Registrar: MarkMonitor, Inc. Registrar IANA ID: 292 Registrar Abuse Contact Email: [email protected] Registrar Abuse Contact Phone: +1.2083895770 Domain Status: clientUpdateProhibited (https://www.icann.org/epp#clientUpdateProhibited) Domain Status: clientTransferProhibited (https://www.icann.org/epp#clientTransferProhibited) Domain Status: clientDeleteProhibited (https://www.icann.org/epp#clientDeleteProhibited) Registrant Organization: Wikimedia Foundation, Inc. Registrant State/Province: CA Registrant Country: US Registrant Email: Select Request Email Form at https://domains.markmonitor.com/whois/wikipedia.org Admin Organization: Wikimedia Foundation, Inc. Admin State/Province: CA Admin Country: US Admin Email: Select Request Email Form at https://domains.markmonitor.com/whois/wikipedia.org Tech Organization: Wikimedia Foundation, Inc. Tech State/Province: CA Tech Country: US Tech Email: Select Request Email Form at https://domains.markmonitor.com/whois/wikipedia.org Name Server: ns2.wikimedia.org Name Server: ns1.wikimedia.org Name Server: ns0.wikimedia.org DNSSEC: unsigned URL of the ICANN WHOIS Data Problem Reporting System: http://wdprs.internic.net/ >>> Last update of WHOIS database: 2020-08-06T21:35:14-0700 <<< For more information on WHOIS status codes, please visit: https://www.icann.org/resources/pages/epp-status-codes
In the whois information, I’ve got creation date of the domain.
But different whois server responses has different date format of creation date.
Is there any way to get that date in a specific date format?
Very great work sir,got lots of information from your work…..thank you very much…..i Need your help sir……can you please give me code or the way/idea to find / detect the operating system of remote system most preferably in winsock…..inux also no problem.
I am building a port scanner for my academic project…..waiting for your reply
to find out the os of the remote system is called “os fingerprinting” and can be done by reading various fields of the tcp header from the packets of the remote system. Fields like ttl, window size etc.
this will require some raw socket programming/packet sniffing.
google for more information.
THANK YOU VERY MUCH SIR…….sorry for being late