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