0,0 → 1,319 |
/* |
WHOIS port for KolibriOS (Adapted by turbocat2001). |
The main code is taken from the site: |
https://www.binarytides.com/whois-client-code-in-c-with-linux-sockets/ |
*/ |
|
#include <stdio.h> |
#include <conio.h> |
#include <string.h> |
#include <stdlib.h> |
#include <net/socket.h> |
#include <net/network.h> |
|
#define stdout (FILE*)0 |
|
FILE *out=stdout; |
|
#ifdef DEBUG |
FILE *out=stderr; |
#endif |
|
#define EXIT_SUCCESS 0 |
#define EXIT_FAILURE 1 |
#define perror(STR) debug_printf(STR); |
|
int unix_fprintf(FILE* file, const char* format, ...) |
{ |
va_list arg; |
va_start (arg, format); |
if(file==stdout){ |
return vprintf(format, arg); |
}else if(file==stderr){ |
char log_board[300]; |
vsnprintf(log_board, sizeof log_board, format, arg); |
debug_out_str(log_board); |
return 0; |
}else{ |
return vfprintf(file, format, arg); |
} |
} |
|
void show_help() |
{ |
puts("Usage: whois <host> [-f <file>]\n"); |
puts(" host Connect to server host"); |
puts(" -f file Redirecting output to file\n"); |
puts("Example: whois google.com -f my.txt"); |
} |
|
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*); |
|
void start_console() |
{ |
con_init_console_dll(); |
con_set_title("Whois"); |
} |
|
int main(int argc , char *argv[]) |
{ |
networklib_init(); |
char *domain , *data = NULL; |
int f_flag=0; |
|
if(argc==2){ |
start_console(); |
domain=strdup(argv[1]); |
} |
|
else if(!strcmp(argv[2], "-f") && argc==4){ |
domain=strdup(argv[1]); |
if((out=fopen(argv[3],"w"))==NULL){ |
printf("Error writing to file: '%s' !\n", argv[3]); |
exit(0); |
} |
}else{ |
start_console(); |
show_help(); |
exit(0); |
} |
|
get_whois_data(domain , &data); |
exit(0); |
} |
|
/* |
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){ |
unix_fprintf(out, "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){ |
unix_fprintf(out, "Whois query failed"); |
return 1; |
} |
unix_fprintf(out, "\n\nResponse is:\n\n"); |
unix_fprintf(out, "%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){ |
unix_fprintf(out, "\nTLD Whois server is : %s" , wch); |
if( whois_query(wch , domain , &response) == EXIT_FAILURE){ |
unix_fprintf(out, "Whois query failed\n"); |
return EXIT_FAILURE; |
} |
}else{ |
unix_fprintf(out, "\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 |
|
unix_fprintf(out, "\nRegistrar Whois server is : %s" , wch); |
|
if( whois_query(wch , domain , &response) == EXIT_FAILURE ){ |
unix_fprintf(out, "Whois query failed"); |
}else{ |
unix_fprintf(out, "\n%s" , response); |
} |
} |
/* |
otherwise echo the output from the previous whois result |
*/ |
else{ |
unix_fprintf(out, "%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 dest; |
|
sock = socket(AF_INET4 , 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'; |
|
unix_fprintf(out, "\nResolving: %s ...\n" , server); |
if( hostname_to_ip(server , ip) == EXIT_FAILURE ){ |
unix_fprintf(out, "Failed\n"); |
return EXIT_FAILURE; |
} |
|
unix_fprintf(out, "Found ip: %s \n" , ip); |
|
dest.sin_addr = inet_addr(ip); |
dest.sin_port = PORT(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 |
unix_fprintf(out, "\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){ |
unix_fprintf(out, "realloc failed"); |
return EXIT_FAILURE; |
} |
memcpy(*response + total_size , buffer , read_size); |
total_size += read_size; |
} |
|
unix_fprintf(out, "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 addrinfo *addr_info; |
char port_str[16]; sprintf(port_str, "%d", 80); |
struct addrinfo hints; |
memset(&hints, 0, sizeof(hints)); |
hints.ai_family = AF_UNSPEC; // IPv4 or IPv6 doesnt matter |
hints.ai_socktype = SOCK_STREAM; // TCP stream sockets |
if (getaddrinfo(hostname, port_str, 0, &addr_info) != 0) { |
freeaddrinfo(addr_info); |
return EXIT_FAILURE; |
}else{ |
strcpy(ip, inet_ntoa(addr_info->ai_addr->sin_addr)); |
return EXIT_SUCCESS; |
} |
} |
/* |
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; |
} |