代码改变世界

Whois client code in C with Linux sockets

2012-07-14 00:08  Rollen Holt  阅读(660)  评论(0编辑  收藏  举报

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.

Code

1 /*
2  * @brief
3  * Whois client program
4  *
5  * @details
6  * This program shall perform whois for a domain and get you the whois data of that domain
7  *
8  * @author Silver Moon ( m00n.silv3r@gmail.com )
9  * */
10  
11 #include<stdio.h> //scanf , printf
12 #include<string.h>    //strtok
13 #include<stdlib.h>    //realloc
14 #include<sys/socket.h>    //socket
15 #include<netinet/in.h> //sockaddr_in
16 #include<arpa/inet.h> //getsockname
17 #include<netdb.h> //hostent
18 #include<unistd.h>    //close
19  
20 int get_whois_data(char * , char **);
21 int hostname_to_ip(char * , char *);
22 int whois_query(char * , char * , char **);
23 char *str_replace(char *search , char *replace , char *subject );
24  
25 int main(int argc , char *argv[])
26 {
27     char domain[100] , *data = NULL;
28      
29     printf("Enter domain name to whois : ");
30     scanf("%s" , domain);
31      
32     get_whois_data(domain , &data);
33      
34     //puts(data);
35     return 0;
36 }
37  
38 /*
39  * Get the whois data of a domain
40  * */
41 int get_whois_data(char *domain , char **data)
42 {
43     char ext[1024] , *pch , *response = NULL , *response_2 = NULL , *wch , *dt;
44  
45     //remove "http://" and "www."
46     domain = str_replace("http://" "" , domain);
47     domain = str_replace("www." "" , domain);
48  
49     //get the extension , com , org , edu
50     dt = strdup(domain);
51     if(dt == NULL)
52     {
53         printf("strdup failed");
54     }
55     pch = (char*)strtok(dt , ".");
56     while(pch != NULL)
57     {
58         strcpy(ext , pch);
59         pch = strtok(NULL , ".");
60     }
61      
62     //This will tell the whois server for the particular TLD like com , org
63     if(whois_query("whois.iana.org" , ext , &response))
64     {
65         printf("Whois query failed");
66     }
67      
68     //Now analysze the response :)
69     pch = strtok(response , "\n");
70     while(pch != NULL)
71     {
72         //Check if whois line
73         wch = strstr(pch , "whois.");
74         if(wch != NULL)
75         {
76             break;
77         }
78  
79         //Next line please
80         pch = strtok(NULL , "\n");
81     }
82  
83      
84      
85     //Now we have the TLD whois server in wch , query again
86     //This will provide minimal whois information along with the parent whois server of the specific domain :)
87     free(response);
88     //This should not be necessary , but segmentation fault without this , why ?
89     response = NULL;
90     if(wch != NULL)
91     {
92         printf("\nTLD Whois server is : %s" , wch);
93         if(whois_query(wch , domain , &response))
94         {
95             printf("Whois query failed");
96         }
97     }
98     else
99     {
100         printf("\nTLD whois server for %s not found" , ext);
101         return 1;
102     }
103      
104     response_2 = strdup(response);
105  
106     //Again search for a whois server in this response. :)
107     pch = strtok(response , "\n");
108     while(pch != NULL)
109     {
110         //Check if whois line
111         wch = strstr(pch , "whois.");
112         if(wch != NULL)
113         {
114             break;
115         }
116  
117         //Next line please
118         pch = strtok(NULL , "\n");
119     }
120  
121  
122     /*
123      * If a registrar whois server is found then query it
124      * */
125     if(wch)
126     {
127         //Now we have the registrar whois server , this has the direct full information of the particular domain
128         //so lets query again
129          
130         printf("\nRegistrar Whois server is : %s" , wch);
131          
132         if(whois_query(wch , domain , &response))
133         {
134             printf("Whois query failed");
135         }
136          
137         printf("\n%s" , response);
138     }
139      
140     /*
141      * otherwise echo the output from the previous whois result
142      * */
143     else
144     {
145         printf("%s" , response_2);
146     }
147     return 0;
148 }
149  
150 /*
151  * Perform a whois query to a server and record the response
152  * */
153 int whois_query(char *server , char *query , char **response)
154 {
155     char ip[32] , message[100] , buffer[1500];
156     int sock , read_size , total_size = 0;
157     struct sockaddr_in dest;
158       
159     sock = socket(AF_INET , SOCK_STREAM , IPPROTO_TCP);
160       
161     //Prepare connection structures :)
162     memset( &dest , 0 , sizeof(dest) );
163     dest.sin_family = AF_INET;
164       
165     printf("\nResolving %s..." , server);
166     if(hostname_to_ip(server , ip))
167     {
168         printf("Failed");
169         return 1;
170     }
171     printf("%s" , ip);   
172     dest.sin_addr.s_addr = inet_addr( ip );
173     dest.sin_port = htons( 43 );
174  
175     //Now connect to remote server
176     if(connect( sock , (const struct sockaddr*) &dest , sizeof(dest) ) < 0)
177     {
178         perror("connect failed");
179     }
180      
181     //Now send some data or message
182     printf("\nQuerying for ... %s ..." , query);
183     sprintf(message , "%s\r\n" , query);
184     if( send(sock , message , strlen(message) , 0) < 0)
185     {
186         perror("send failed");
187     }
188      
189     //Now receive the response
190     while( (read_size = recv(sock , buffer , sizeof(buffer) , 0) ) )
191     {
192         *response = realloc(*response , read_size + total_size);
193         if(*response == NULL)
194         {
195             printf("realloc failed");
196         }
197         memcpy(*response + total_size , buffer , read_size);
198         total_size += read_size;
199     }
200     printf("Done");
201     fflush(stdout);
202      
203     *response = realloc(*response , total_size + 1);
204     *(*response + total_size) = '\0';
205      
206     close(sock);
207     return 0;
208 }
209  
210 /*
211  * @brief
212  * Get the ip address of a given hostname
213  *
214  * */
215 int hostname_to_ip(char * hostname , char* ip)
216 {
217     struct hostent *he;
218     struct in_addr **addr_list;
219     int i;
220          
221     if ( (he = gethostbyname( hostname ) ) == NULL)
222     {
223         // get the host info
224         herror("gethostbyname");
225         return 1;
226     }
227  
228     addr_list = (struct in_addr **) he->h_addr_list;
229      
230     for(i = 0; addr_list[i] != NULL; i++)
231     {
232         //Return the first one;
233         strcpy(ip , inet_ntoa(*addr_list[i]) );
234         return 0;
235     }
236      
237     return 0;
238 }
239  
240 /*
241  * Search and replace a string with another string , in a string
242  * */
243 char *str_replace(char *search , char *replace , char *subject)
244 {
245     char  *p = NULL , *old = NULL , *new_subject = NULL ;
246     int c = 0 , search_size;
247      
248     search_size = strlen(search);
249      
250     //Count how many occurences
251     for(p = strstr(subject , search) ; p != NULL ; p = strstr(p + search_size , search))
252     {
253         c++;
254     }
255      
256     //Final size
257     c = ( strlen(replace) - search_size )*c + strlen(subject);
258      
259     //New subject with new size
260     new_subject = malloc( c );
261      
262     //Set it to blank
263     strcpy(new_subject , "");
264      
265     //The start position
266     old = subject;
267      
268     for(p = strstr(subject , search) ; p != NULL ; p = strstr(p + search_size , search))
269     {
270         //move ahead and copy some text from original subject , from a certain position
271         strncpy(new_subject + strlen(new_subject) , old , p - old);
272          
273         //move ahead and copy the replacement text
274         strcpy(new_subject + strlen(new_subject) , replace);
275          
276         //The new start position after this search match
277         old = p + search_size;
278     }
279      
280     //Copy the part after the last search match
281     strcpy(new_subject + strlen(new_subject) , old);
282      
283     return new_subject;
284 }

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.

Output

1 Enter domain name to whois : www.wikipedia.org
2  
3 Resolving whois.iana.org...192.0.47.59
4 Querying for ... org ...Done
5 TLD Whois server is : whois.pir.org
6 Resolving whois.pir.org...149.17.192.7
7 Querying for ... wikipedia.org ...DoneAccess to .ORG WHOIS information is provided to assist persons in
8 determining the contents of a domain name registration record in the
9 Public Interest Registry registry database. The data in this record is provided by
10 Public Interest Registry for informational purposes only, and Public Interest Registry does not
11 guarantee its accuracy.  This service is intended only for query-based
12 access. You agree that you will use this data only for lawful purposes
13 and that, under no circumstances will you use this data to: (a) allow,
14 enable, or otherwise support the transmission by e-mail, telephone, or
15 facsimile of mass unsolicited, commercial advertising or solicitations
16 to entities other than the data recipient's own existing customers; or
17 (b) enable high volume, automated, electronic processes that send
18 queries or data to the systems of Registry Operator, a Registrar, or
19 Afilias except as reasonably necessary to register domain names or
20 modify existing registrations. All rights reserved. Public Interest Registry reserves
21 the right to modify these terms at any time. By submitting this query,
22 you agree to abide by this policy.
23  
24 Domain ID:D51687756-LROR
25 Domain Name:WIKIPEDIA.ORG
26 Created On:13-Jan-2001 00:12:14 UTC
27 Last Updated On:02-Dec-2009 20:57:17 UTC
28 Expiration Date:13-Jan-2015 00:12:14 UTC
29 Sponsoring Registrar:GoDaddy.com, Inc. (R91-LROR)
30 Status:CLIENT DELETE PROHIBITED
31 Status:CLIENT RENEW PROHIBITED
32 Status:CLIENT TRANSFER PROHIBITED
33 Status:CLIENT UPDATE PROHIBITED
34 Registrant ID:CR31094073
35 Registrant Name:DNS Admin
36 Registrant Organization:Wikimedia Foundation, Inc.
37 Registrant Street1:149 New Montgomery Street
38 Registrant Street2:Third Floor
39 Registrant Street3:
40 Registrant City:San Francisco
41 Registrant State/Province:California
42 Registrant Postal Code:94105
43 Registrant Country:US
44 Registrant Phone:+1.4158396885
45 Registrant Phone Ext.:
46 Registrant FAX:+1.4158820495
47 Registrant FAX Ext.:
48 Registrant Email:dns-admin@wikimedia.org
49 Admin ID:CR31094075
50 Admin Name:DNS Admin
51 Admin Organization:Wikimedia Foundation, Inc.
52 Admin Street1:149 New Montgomery Street
53 Admin Street2:Third Floor
54 Admin Street3:
55 Admin City:San Francisco
56 Admin State/Province:California
57 Admin Postal Code:94105
58 Admin Country:US
59 Admin Phone:+1.4158396885
60 Admin Phone Ext.:
61 Admin FAX:+1.4158820495
62 Admin FAX Ext.:
63 Admin Email:dns-admin@wikimedia.org
64 Tech ID:CR31094074
65 Tech Name:DNS Admin
66 Tech Organization:Wikimedia Foundation, Inc.
67 Tech Street1:149 New Montgomery Street
68 Tech Street2:Third Floor
69 Tech Street3:
70 Tech City:San Francisco
71 Tech State/Province:California
72 Tech Postal Code:94105
73 Tech Country:US
74 Tech Phone:+1.4158396885
75 Tech Phone Ext.:
76 Tech FAX:+1.4158820495
77 Tech FAX Ext.:
78 Tech Email:dns-admin@wikimedia.org
79 Name Server:NS0.WIKIMEDIA.ORG
80 Name Server:NS1.WIKIMEDIA.ORG
81 Name Server:NS2.WIKIMEDIA.ORG
82 Name Server:
83 Name Server:
84 Name Server:
85 Name Server:
86 Name Server:
87 Name Server:
88 Name Server:
89 Name Server:
90 Name Server:
91 Name Server:
92 DNSSEC:Unsigned

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.

Code

1 /*
2  * @brief
3  * Whois client program
4  *
5  * @details
6  * This program shall perform whois for a domain and get you the whois data of that domain
7  *
8  * @author Silver Moon ( m00n.silv3r@gmail.com )
9  * */
10  
11 #include<stdio.h> //scanf , printf
12 #include<string.h>    //strtok
13 #include<stdlib.h>    //realloc
14 #include<sys/socket.h>    //socket
15 #include<netinet/in.h> //sockaddr_in
16 #include<arpa/inet.h> //getsockname
17 #include<netdb.h> //hostent
18 #include<unistd.h>    //close
19  
20 int get_whois_data(char * , char **);
21 int hostname_to_ip(char * , char *);
22 int whois_query(char * , char * , char **);
23 char *str_replace(char *search , char *replace , char *subject );
24  
25 int main(int argc , char *argv[])
26 {
27     char domain[100] , *data = NULL;
28      
29     printf("Enter domain name to whois : ");
30     scanf("%s" , domain);
31      
32     get_whois_data(domain , &data);
33      
34     //puts(data);
35     return 0;
36 }
37  
38 /*
39  * Get the whois data of a domain
40  * */
41 int get_whois_data(char *domain , char **data)
42 {
43     char ext[1024] , *pch , *response = NULL , *response_2 = NULL , *wch , *dt;
44  
45     //remove "http://" and "www."
46     domain = str_replace("http://" "" , domain);
47     domain = str_replace("www." "" , domain);
48  
49     //get the extension , com , org , edu
50     dt = strdup(domain);
51     if(dt == NULL)
52     {
53         printf("strdup failed");
54     }
55     pch = (char*)strtok(dt , ".");
56     while(pch != NULL)
57     {
58         strcpy(ext , pch);
59         pch = strtok(NULL , ".");
60     }
61      
62     //This will tell the whois server for the particular TLD like com , org
63     if(whois_query("whois.iana.org" , ext , &response))
64     {
65         printf("Whois query failed");
66     }
67      
68     //Now analysze the response :)
69     pch = strtok(response , "\n");
70     while(pch != NULL)
71     {
72         //Check if whois line
73         wch = strstr(pch , "whois.");
74         if(wch != NULL)
75         {
76             break;
77         }
78  
79         //Next line please
80         pch = strtok(NULL , "\n");
81     }
82  
83      
84      
85     //Now we have the TLD whois server in wch , query again
86     //This will provide minimal whois information along with the parent whois server of the specific domain :)
87     free(response);
88     //This should not be necessary , but segmentation fault without this , why ?
89     response = NULL;
90     if(wch != NULL)
91     {
92         printf("\nTLD Whois server is : %s" , wch);
93         if(whois_query(wch , domain , &response))
94         {
95             printf("Whois query failed");
96         }
97     }
98     else
99     {
100         printf("\nTLD whois server for %s not found" , ext);
101         return 1;
102     }
103      
104     response_2 = strdup(response);
105  
106     //Again search for a whois server in this response. :)
107     pch = strtok(response , "\n");
108     while(pch != NULL)
109     {
110         //Check if whois line
111         wch = strstr(pch , "whois.");
112         if(wch != NULL)
113         {
114             break;
115         }
116  
117         //Next line please
118         pch = strtok(NULL , "\n");
119     }
120  
121  
122     /*
123      * If a registrar whois server is found then query it
124      * */
125     if(wch)
126     {
127         //Now we have the registrar whois server , this has the direct full information of the particular domain
128         //so lets query again
129          
130         printf("\nRegistrar Whois server is : %s" , wch);
131          
132         if(whois_query(wch , domain , &response))
133         {
134             printf("Whois query failed");
135         }
136          
137         printf("\n%s" , response);
138     }
139      
140     /*
141      * otherwise echo the output from the previous whois result
142      * */
143     else
144     {
145         printf("%s" , response_2);
146     }
147     return 0;
148 }
149  
150 /*
151  * Perform a whois query to a server and record the response
152  * */
153 int whois_query(char *server , char *query , char **response)
154 {
155     char ip[32] , message[100] , buffer[1500];
156     int sock , read_size , total_size = 0;
157     struct sockaddr_in dest;
158       
159     sock = socket(AF_INET , SOCK_STREAM , IPPROTO_TCP);
160       
161     //Prepare connection structures :)
162     memset( &dest , 0 , sizeof(dest) );
163     dest.sin_family = AF_INET;
164       
165     printf("\nResolving %s..." , server);
166     if(hostname_to_ip(server , ip))
167     {
168         printf("Failed");
169         return 1;
170     }
171     printf("%s" , ip);   
172     dest.sin_addr.s_addr = inet_addr( ip );
173     dest.sin_port = htons( 43 );
174  
175     //Now connect to remote server
176     if(connect( sock , (const struct sockaddr*) &dest , sizeof(dest) ) < 0)
177     {
178         perror("connect failed");
179     }
180      
181     //Now send some data or message
182     printf("\nQuerying for ... %s ..." , query);
183     sprintf(message , "%s\r\n" , query);
184     if( send(sock , message , strlen(message) , 0) < 0)
185     {
186         perror("send failed");
187     }
188      
189     //Now receive the response
190     while( (read_size = recv(sock , buffer , sizeof(buffer) , 0) ) )
191     {
192         *response = realloc(*response , read_size + total_size);
193         if(*response == NULL)
194         {
195             printf("realloc failed");
196         }
197         memcpy(*response + total_size , buffer , read_size);
198         total_size += read_size;
199     }
200     printf("Done");
201     fflush(stdout);
202      
203     *response = realloc(*response , total_size + 1);
204     *(*response + total_size) = '\0';
205      
206     close(sock);
207     return 0;
208 }
209  
210 /*
211  * @brief
212  * Get the ip address of a given hostname
213  *
214  * */
215 int hostname_to_ip(char * hostname , char* ip)
216 {
217     struct hostent *he;
218     struct in_addr **addr_list;
219     int i;
220          
221     if ( (he = gethostbyname( hostname ) ) == NULL)
222     {
223         // get the host info
224         herror("gethostbyname");
225         return 1;
226     }
227  
228     addr_list = (struct in_addr **) he->h_addr_list;
229      
230     for(i = 0; addr_list[i] != NULL; i++)
231     {
232         //Return the first one;
233         strcpy(ip , inet_ntoa(*addr_list[i]) );
234         return 0;
235     }
236      
237     return 0;
238 }
239  
240 /*
241  * Search and replace a string with another string , in a string
242  * */
243 char *str_replace(char *search , char *replace , char *subject)
244 {
245     char  *p = NULL , *old = NULL , *new_subject = NULL ;
246     int c = 0 , search_size;
247      
248     search_size = strlen(search);
249      
250     //Count how many occurences
251     for(p = strstr(subject , search) ; p != NULL ; p = strstr(p + search_size , search))
252     {
253         c++;
254     }
255      
256     //Final size
257     c = ( strlen(replace) - search_size )*c + strlen(subject);
258      
259     //New subject with new size
260     new_subject = malloc( c );
261      
262     //Set it to blank
263     strcpy(new_subject , "");
264      
265     //The start position
266     old = subject;
267      
268     for(p = strstr(subject , search) ; p != NULL ; p = strstr(p + search_size , search))
269     {
270         //move ahead and copy some text from original subject , from a certain position
271         strncpy(new_subject + strlen(new_subject) , old , p - old);
272          
273         //move ahead and copy the replacement text
274         strcpy(new_subject + strlen(new_subject) , replace);
275          
276         //The new start position after this search match
277         old = p + search_size;
278     }
279      
280     //Copy the part after the last search match
281     strcpy(new_subject + strlen(new_subject) , old);
282      
283     return new_subject;
284 }

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.

Output

1 Enter domain name to whois : www.wikipedia.org
2  
3 Resolving whois.iana.org...192.0.47.59
4 Querying for ... org ...Done
5 TLD Whois server is : whois.pir.org
6 Resolving whois.pir.org...149.17.192.7
7 Querying for ... wikipedia.org ...DoneAccess to .ORG WHOIS information is provided to assist persons in
8 determining the contents of a domain name registration record in the
9 Public Interest Registry registry database. The data in this record is provided by
10 Public Interest Registry for informational purposes only, and Public Interest Registry does not
11 guarantee its accuracy.  This service is intended only for query-based
12 access. You agree that you will use this data only for lawful purposes
13 and that, under no circumstances will you use this data to: (a) allow,
14 enable, or otherwise support the transmission by e-mail, telephone, or
15 facsimile of mass unsolicited, commercial advertising or solicitations
16 to entities other than the data recipient's own existing customers; or
17 (b) enable high volume, automated, electronic processes that send
18 queries or data to the systems of Registry Operator, a Registrar, or
19 Afilias except as reasonably necessary to register domain names or
20 modify existing registrations. All rights reserved. Public Interest Registry reserves
21 the right to modify these terms at any time. By submitting this query,
22 you agree to abide by this policy.
23  
24 Domain ID:D51687756-LROR
25 Domain Name:WIKIPEDIA.ORG
26 Created On:13-Jan-2001 00:12:14 UTC
27 Last Updated On:02-Dec-2009 20:57:17 UTC
28 Expiration Date:13-Jan-2015 00:12:14 UTC
29 Sponsoring Registrar:GoDaddy.com, Inc. (R91-LROR)
30 Status:CLIENT DELETE PROHIBITED
31 Status:CLIENT RENEW PROHIBITED
32 Status:CLIENT TRANSFER PROHIBITED
33 Status:CLIENT UPDATE PROHIBITED
34 Registrant ID:CR31094073
35 Registrant Name:DNS Admin
36 Registrant Organization:Wikimedia Foundation, Inc.
37 Registrant Street1:149 New Montgomery Street
38 Registrant Street2:Third Floor
39 Registrant Street3:
40 Registrant City:San Francisco
41 Registrant State/Province:California
42 Registrant Postal Code:94105
43 Registrant Country:US
44 Registrant Phone:+1.4158396885
45 Registrant Phone Ext.:
46 Registrant FAX:+1.4158820495
47 Registrant FAX Ext.:
48 Registrant Email:dns-admin@wikimedia.org
49 Admin ID:CR31094075
50 Admin Name:DNS Admin
51 Admin Organization:Wikimedia Foundation, Inc.
52 Admin Street1:149 New Montgomery Street
53 Admin Street2:Third Floor
54 Admin Street3:
55 Admin City:San Francisco
56 Admin State/Province:California
57 Admin Postal Code:94105
58 Admin Country:US
59 Admin Phone:+1.4158396885
60 Admin Phone Ext.:
61 Admin FAX:+1.4158820495
62 Admin FAX Ext.:
63 Admin Email:dns-admin@wikimedia.org
64 Tech ID:CR31094074
65 Tech Name:DNS Admin
66 Tech Organization:Wikimedia Foundation, Inc.
67 Tech Street1:149 New Montgomery Street
68 Tech Street2:Third Floor
69 Tech Street3:
70 Tech City:San Francisco
71 Tech State/Province:California
72 Tech Postal Code:94105
73 Tech Country:US
74 Tech Phone:+1.4158396885
75 Tech Phone Ext.:
76 Tech FAX:+1.4158820495
77 Tech FAX Ext.:
78 Tech Email:dns-admin@wikimedia.org
79 Name Server:NS0.WIKIMEDIA.ORG
80 Name Server:NS1.WIKIMEDIA.ORG
81 Name Server:NS2.WIKIMEDIA.ORG
82 Name Server:
83 Name Server:
84 Name Server:
85 Name Server:
86 Name Server:
87 Name Server:
88 Name Server:
89 Name Server:
90 Name Server:
91 Name Server:
92 DNSSEC:Unsigned