Rev 9553 | Rev 9620 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
8687 | turbocat | 1 | /* |
2 | WHOIS port for KolibriOS (Adapted by turbocat2001). |
||
3 | The main code is taken from the site: |
||
4 | https://www.binarytides.com/whois-client-code-in-c-with-linux-sockets/ |
||
5 | */ |
||
6 | |||
7 | #include |
||
9558 | turbocat | 8 | int errno; |
9 | |||
8687 | turbocat | 10 | #include "sys/ksys.h" |
11 | #include |
||
12 | #include |
||
13 | #include |
||
14 | #include |
||
15 | #include |
||
8787 | turbocat | 16 | #include |
8687 | turbocat | 17 | |
18 | FILE *out=stdout; |
||
19 | |||
20 | #ifdef DEBUG |
||
21 | FILE *out=stderr; |
||
22 | #endif |
||
23 | |||
24 | #define EXIT_SUCCESS 0 |
||
25 | #define EXIT_FAILURE 1 |
||
26 | |||
27 | #define fprintf fprintf |
||
28 | |||
29 | void show_help() |
||
30 | { |
||
31 | puts("Usage: whois |
||
32 | puts(" host Connect to server host"); |
||
33 | puts(" -f file Redirecting output to file\n"); |
||
34 | puts("Example: whois google.com -f my.txt"); |
||
35 | } |
||
36 | |||
37 | int get_whois_data(char * , char **); |
||
38 | int hostname_to_ip(char * , char *); |
||
39 | int whois_query(char * , char * , char **); |
||
40 | char *str_replace(char *search , char *replace , char *subject ); |
||
41 | char* str_copy(char*); |
||
42 | |||
43 | |||
44 | int main(int argc , char *argv[]) |
||
9558 | turbocat | 45 | { |
46 | networklib_init(); |
||
8687 | turbocat | 47 | char *domain , *data = NULL; |
48 | int f_flag=0; |
||
49 | |||
50 | if(argc==2){ |
||
51 | domain=strdup(argv[1]); |
||
52 | } |
||
53 | |||
54 | else if(!strcmp(argv[2], "-f") && argc==4){ |
||
55 | domain=strdup(argv[1]); |
||
56 | if((out=fopen(argv[3],"w"))==NULL){ |
||
57 | printf("Error writing to file: '%s' !\n", argv[3]); |
||
58 | exit(0); |
||
59 | } |
||
60 | }else{ |
||
61 | show_help(); |
||
62 | exit(0); |
||
63 | } |
||
64 | if(out==stdout){ |
||
8787 | turbocat | 65 | con_init(); |
66 | (*con_set_title)("Whois"); |
||
8687 | turbocat | 67 | } |
68 | get_whois_data(domain , &data); |
||
69 | exit(0); |
||
70 | } |
||
71 | |||
72 | /* |
||
73 | Get the whois data of a domain |
||
74 | */ |
||
75 | |||
76 | int get_whois_data(char *domain , char **data) |
||
77 | { |
||
78 | char ext[1024] , *pch , *response = NULL , *response_2 = NULL , *wch , *dt; |
||
79 | |||
80 | //remove "http://" and "www." |
||
81 | domain = str_replace("http://" , "" , domain); |
||
82 | domain = str_replace("www." , "" , domain); |
||
83 | |||
84 | //get the extension , com , org , edu |
||
85 | dt = strdup(domain); |
||
86 | |||
87 | if(dt == NULL){ |
||
88 | fprintf(out, "strdup failed"); |
||
89 | } |
||
90 | pch = (char*)strtok(dt , "."); |
||
91 | while(pch != NULL){ |
||
92 | strcpy(ext , pch); |
||
93 | pch = strtok(NULL , "."); |
||
94 | } |
||
95 | // This will tell the whois server for the particular TLD like com , org |
||
96 | if( whois_query("whois.iana.org" , ext , &response) == EXIT_FAILURE){ |
||
97 | fprintf(out, "Whois query failed"); |
||
98 | return 1; |
||
99 | } |
||
100 | fprintf(out, "\n\nResponse is:\n\n"); |
||
101 | fprintf(out, "%s", response); |
||
102 | |||
103 | // Now analysze the response |
||
104 | pch = strtok(response , "\n"); |
||
105 | while(pch != NULL){ |
||
106 | // Check if whois line |
||
107 | wch = strstr(pch , "whois."); |
||
108 | if(wch != NULL){ |
||
109 | break; |
||
110 | } |
||
111 | |||
112 | // Next line please |
||
113 | pch = strtok(NULL , "\n"); |
||
114 | } |
||
115 | // Now we have the TLD whois server in wch , query again |
||
116 | //This will provide minimal whois information along with the parent whois server of the specific domain :) |
||
117 | wch = strdup(wch); |
||
118 | free(response); |
||
119 | //This should not be necessary , but segmentation fault without this , why ? |
||
120 | response = NULL; |
||
121 | if(wch != NULL){ |
||
122 | fprintf(out,"\nTLD Whois server is : %s" , wch); |
||
123 | if( whois_query(wch , domain , &response) == EXIT_FAILURE){ |
||
124 | fprintf(out, "Whois query failed\n"); |
||
125 | return EXIT_FAILURE; |
||
126 | } |
||
127 | }else{ |
||
128 | fprintf(out, "\nTLD whois server for %s not found\n" , ext); |
||
129 | return EXIT_SUCCESS; |
||
130 | } |
||
131 | |||
132 | response_2 = strdup(response); |
||
133 | |||
134 | // Again search for a whois server in this response. :) |
||
135 | pch = strtok(response , "\n"); |
||
136 | while(pch != NULL){ |
||
137 | // Check if whois line |
||
138 | wch = strstr(pch , "whois."); |
||
139 | if(wch != NULL){ |
||
140 | break; |
||
141 | } |
||
142 | //Next line please |
||
143 | pch = strtok(NULL , "\n"); |
||
144 | } |
||
145 | |||
146 | /* |
||
147 | If a registrar whois server is found then query it |
||
148 | */ |
||
149 | if(wch){ |
||
150 | // Now we have the registrar whois server , this has the direct full information of the particular domain |
||
151 | // so lets query again |
||
152 | |||
153 | fprintf(out, "\nRegistrar Whois server is : %s" , wch); |
||
154 | |||
155 | if( whois_query(wch , domain , &response) == EXIT_FAILURE ){ |
||
156 | fprintf(out, "Whois query failed"); |
||
157 | }else{ |
||
158 | fprintf(out, "\n%s" , response); |
||
159 | } |
||
160 | } |
||
161 | /* |
||
162 | otherwise echo the output from the previous whois result |
||
163 | */ |
||
164 | else{ |
||
165 | fprintf(out, "%s" , response_2); |
||
166 | } |
||
167 | return 0; |
||
168 | } |
||
169 | |||
170 | /* |
||
171 | Perform a whois query to a server and record the response |
||
172 | */ |
||
173 | int whois_query(char *server , char *query , char **response) |
||
174 | { |
||
175 | char ip[32] , message[100] , buffer[1500]; |
||
176 | int sock , read_size , total_size = 0; |
||
177 | int WHOIS_PORT = 43; |
||
178 | struct sockaddr dest; |
||
179 | |||
180 | sock = socket(AF_INET4 , SOCK_STREAM , IPPROTO_TCP); |
||
181 | |||
182 | //Prepare connection structures :) |
||
183 | memset(&dest , 0 , sizeof(dest) ); |
||
184 | dest.sin_family = AF_INET; |
||
185 | server = str_copy(server); |
||
186 | |||
187 | server[strcspn(server, "\r\n")] = '\0'; |
||
188 | fprintf(out, "\nResolving: %s ...\n" , server); |
||
189 | if(hostname_to_ip(server , ip) == EXIT_FAILURE ){ |
||
190 | fprintf(out, "Failed\n"); |
||
191 | return EXIT_FAILURE; |
||
192 | } |
||
193 | |||
194 | fprintf(out, "Found ip: %s \n" , ip); |
||
195 | dest.sin_addr = inet_addr(ip); |
||
196 | dest.sin_port = PORT(WHOIS_PORT); |
||
197 | |||
198 | ; //Now connect to remote server |
||
199 | if(connect(sock , (const struct sockaddr*) &dest , sizeof(dest)) < 0){ |
||
200 | perror("connect failed"); |
||
201 | perror(strerror(errno)); |
||
202 | return EXIT_FAILURE; |
||
203 | } |
||
204 | |||
205 | //Now send some data or message |
||
206 | fprintf(out, "\nQuerying for: %s ...\n" , query); |
||
207 | sprintf(message , "%s\r\n" , query); |
||
208 | if( send(sock , message , strlen(message) , 0) < 0){ |
||
209 | perror("send failed"); |
||
210 | return EXIT_FAILURE; |
||
211 | } |
||
212 | |||
213 | //Now receive the response |
||
214 | while((read_size = recv(sock, buffer, sizeof(buffer), 0))){ |
||
215 | *response = realloc(*response , read_size + total_size); |
||
216 | if(*response == NULL){ |
||
217 | fprintf(out, "realloc failed"); |
||
218 | return EXIT_FAILURE; |
||
219 | } |
||
220 | memcpy(*response + total_size , buffer , read_size); |
||
221 | total_size += read_size; |
||
222 | } |
||
223 | |||
224 | fprintf(out, "Done\n"); |
||
225 | |||
226 | *response = realloc(*response , total_size + 1); |
||
227 | *(*response + total_size) = '\0'; |
||
228 | close(sock); |
||
229 | return EXIT_SUCCESS; |
||
230 | } |
||
231 | /* |
||
232 | Get the ip address of a given hostname |
||
233 | */ |
||
234 | int hostname_to_ip(char *hostname , char *ip) |
||
235 | { |
||
236 | struct addrinfo *addr_info; |
||
237 | char port_str[16]; sprintf(port_str, "%d", 80); |
||
238 | struct addrinfo hints; |
||
239 | memset(&hints, 0, sizeof(hints)); |
||
240 | hints.ai_family = AF_UNSPEC; // IPv4 or IPv6 doesnt matter |
||
241 | hints.ai_socktype = SOCK_STREAM; // TCP stream sockets |
||
242 | if (getaddrinfo(hostname, port_str, 0, &addr_info) != 0) { |
||
243 | freeaddrinfo(addr_info); |
||
244 | return EXIT_FAILURE; |
||
245 | }else{ |
||
246 | strcpy(ip, inet_ntoa(addr_info->ai_addr->sin_addr)); |
||
247 | return EXIT_SUCCESS; |
||
248 | } |
||
249 | } |
||
250 | /* |
||
251 | Search and replace a string with another string , in a string |
||
252 | */ |
||
253 | char *str_replace(char *search , char *replace , char *subject) |
||
254 | { |
||
255 | char *p = NULL , *old = NULL , *new_subject = NULL ; |
||
256 | int c = 0 , search_size; |
||
257 | |||
258 | search_size = strlen(search); |
||
259 | |||
260 | //Count how many occurences |
||
261 | for(p = strstr(subject , search) ; p != NULL ; p = strstr(p + search_size , search)){ |
||
262 | c++; |
||
263 | } |
||
264 | //Final size |
||
265 | c = ( strlen(replace) - search_size )*c + strlen(subject); |
||
266 | |||
267 | //New subject with new size |
||
268 | new_subject = malloc( c ); |
||
269 | |||
270 | //Set it to blank |
||
271 | strcpy(new_subject , ""); |
||
272 | |||
273 | //The start position |
||
274 | old = subject; |
||
275 | |||
276 | for(p = strstr(subject , search) ; p != NULL ; p = strstr(p + search_size , search)){ |
||
277 | //move ahead and copy some text from original subject , from a certain position |
||
278 | strncpy(new_subject + strlen(new_subject) , old , p - old); |
||
279 | |||
280 | //move ahead and copy the replacement text |
||
281 | strcpy(new_subject + strlen(new_subject) , replace); |
||
282 | |||
283 | //The new start position after this search match |
||
284 | old = p + search_size; |
||
285 | } |
||
286 | |||
287 | //Copy the part after the last search match |
||
288 | strcpy(new_subject + strlen(new_subject) , old); |
||
289 | |||
290 | return new_subject; |
||
291 | } |
||
292 | |||
293 | char* str_copy(char *source) |
||
294 | { |
||
295 | char *copy = malloc(strlen(source) + 1); |
||
296 | |||
297 | if(copy){ |
||
298 | strcpy(copy, source); |
||
299 | } |
||
300 | return copy; |
||
301 | }>> |