Whois client code in C with Linux sockets

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 
20int get_whois_data(char * , char **);
21int hostname_to_ip(char * , char *);
22int whois_query(char * , char * , char **);
23char *str_replace(char *search , char *replace , char *subject );
24 
25int 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 * */
41int 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 * */
153int 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 * */
215int 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 * */
243char *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

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

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

转载于:https://www.cnblogs.com/rollenholt/articles/2591005.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值