1+ #include <stdio.h>
2+ #include <stdlib.h>
3+ #include <string.h>
4+ #include <netinet/in.h>
5+ #include <sys/socket.h>
6+ #include <sys/types.h>
7+ #include <netdb.h>
8+ #include <arpa/inet.h>
9+ #include <unistd.h>
10+ #include <stdbool.h>
11+ #include <ctype.h>
12+
13+ #define BUFF_LEN 4096
14+ #define MAX_SUB_DOMAIN 20
15+ #define SUB_DOMAIN_LEN 50
16+ #define MAX_NAME_SERVERS 20
17+
18+ int parse (char * domain ,char * name_server , char nameservers [][SUB_DOMAIN_LEN ]){
19+ char command [BUFF_LEN ];
20+ strcpy (command ,"nslookup -type=ns " );
21+ strcat (command ,domain );
22+ strcat (command ," " );
23+ strcat (command ,name_server );
24+ printf ("%s\n" ,command );
25+ const char * cmd = command ;
26+ char result [BUFF_LEN ] = "" ;
27+ FILE * out = popen (cmd , "r" );
28+ char buffer [BUFF_LEN ];
29+ while (fgets (buffer , 1000 , out ))
30+ strcat (result ,buffer );
31+ pclose (out );
32+
33+ char * token ;
34+ strtok (result ,"\n" );
35+ strtok (NULL ,"\n" );
36+ strtok (NULL ,"\n" );
37+ strtok (NULL ,"=" );
38+ token = strtok (NULL ,"\n" );
39+ int i = 0 ;
40+ while (token != NULL ){
41+ strncpy (nameservers [i ++ ],token + 1 ,strlen (token )- 2 );
42+ strtok (NULL ,"=" );
43+ token = strtok (NULL ,"\n" );
44+ }
45+ return i ;
46+ }
47+
48+ int main (){
49+ int sockfd = socket (PF_INET ,SOCK_DGRAM ,0 );
50+ if (sockfd == -1 ){
51+ printf ("Failed to create a socket\n" );
52+ return 0 ;
53+ }
54+ else if (sockfd <= 0 ){
55+ printf ("Invalid memory creation for socket. Try again\n" );
56+ return 0 ;
57+ }
58+
59+ struct sockaddr_in serv_addr ;
60+ serv_addr .sin_family = AF_INET ;
61+ serv_addr .sin_port = htons (1234 );
62+ serv_addr .sin_addr .s_addr = INADDR_ANY ;
63+ memset (serv_addr .sin_zero ,0 ,sizeof (serv_addr .sin_zero ));
64+
65+
66+ int flag1 = bind (sockfd ,(struct sockaddr * )& serv_addr ,sizeof (serv_addr ));
67+ if (flag1 == -1 ){
68+ printf ("Failed to bind to an IP and port\n" );
69+ close (sockfd );
70+ return 0 ;
71+ }
72+
73+ struct sockaddr_storage serv_storage ;
74+ int addr = sizeof (serv_storage );
75+ while (1 ){
76+ char buffer [BUFF_LEN ];
77+ bzero (buffer ,BUFF_LEN );
78+ while (1 )
79+ if (recvfrom (sockfd ,buffer ,sizeof (buffer ),0 ,(struct sockaddr * )& serv_storage ,& addr ) > 0 )
80+ break ;
81+ if (!strncmp (buffer ,"quit" ,4 )){
82+ printf ("Requested to close the service\n" );
83+ sendto (sockfd ,buffer ,strlen (buffer ),0 ,(struct sockaddr * )& serv_storage ,addr );
84+ break ;
85+ }
86+ else {
87+ printf ("Request from client is : %s" ,buffer );
88+ buffer [strlen (buffer )] = '\n' ;
89+ if (strncmp (buffer ,"A " ,2 ) && strncmp (buffer ,"AAAA " ,5 ) && strncmp (buffer ,"NS " ,3 ) && strncmp (buffer ,"CNAME " ,5 )){
90+ char buff [] = "Illegal\n" ;
91+ sendto (sockfd ,buff ,strlen (buff )+ 1 ,0 ,(struct sockaddr * )& serv_storage ,addr );
92+ continue ;
93+ }
94+ char * token1 ,* token2 ;
95+ token1 = strtok (buffer ," " );
96+ char req [10 ];
97+ strcpy (req ,token1 );
98+ token2 = strtok (NULL ,"\n" );
99+ strcpy (buffer ,token2 );
100+ char buffer_copy [BUFF_LEN ];
101+ strcpy (buffer_copy ,buffer );
102+
103+ FILE * fp = fopen ("cache.txt" ,"r" );
104+ char check [BUFF_LEN ];
105+ strcpy (check ,buffer );
106+ strcat (check ,"-" );
107+ strcat (check ,req );
108+ printf ("check : %s\n" ,check );
109+ bool flag = 0 ;
110+ char buff [BUFF_LEN ], res [BUFF_LEN ];
111+ bzero (res ,BUFF_LEN );
112+ while (fp != NULL && fgets (buff ,BUFF_LEN ,fp )){
113+ if (strncmp (buff ,check ,strlen (check ))== 0 ){
114+ while (1 ){
115+ bzero (buff ,BUFF_LEN );
116+ fgets (buff ,BUFF_LEN ,fp );
117+ if (strncmp (buff ,"---" ,3 )== 0 ) break ;
118+ strcat (res ,buff );
119+ }
120+ sendto (sockfd ,res ,strlen (res ),0 ,(struct sockaddr * )& serv_storage ,addr );
121+ printf ("Response found in Cache\n" );
122+ flag = 1 ;
123+ break ;
124+ }
125+ }
126+ if (flag )
127+ continue ;
128+
129+ int count = 1 ;
130+ for (int i = 0 ;i < strlen (buffer );i ++ )
131+ if (buffer [i ] == '.' )
132+ count ++ ;
133+ printf ("Total number of subdomains in the given domain name is %d\n" ,count );
134+
135+ char a [count ][SUB_DOMAIN_LEN ];
136+ char * token ;
137+ token = strtok (buffer_copy ,"." );
138+ for (int i = 0 ;i < count ;i ++ ){
139+ strcpy (a [i ],token );
140+ token = strtok (NULL ,"." );
141+ }
142+
143+ char div_sub_domains [count ][SUB_DOMAIN_LEN ];
144+ strcpy (div_sub_domains [0 ],a [count - 1 ]);
145+
146+ for (int i = 1 ;i < count ;i ++ ){
147+ strcpy (div_sub_domains [i ],a [count - 1 - i ]);
148+ strcat (div_sub_domains [i ],"." );
149+ strcat (div_sub_domains [i ],div_sub_domains [i - 1 ]);
150+ }
151+
152+ for (int i = 0 ;i < count ;i ++ )
153+ printf ("%s\n" ,div_sub_domains [i ]);
154+
155+ char nameservers [MAX_NAME_SERVERS ][SUB_DOMAIN_LEN ];
156+ int name_count = parse ("." ,"" ,nameservers );
157+ for (int i = 0 ;i < name_count ;i ++ )
158+ printf ("%s\n" ,nameservers [i ]);
159+ for (int j = 0 ;j < count - 1 ;j ++ ){
160+ char dup_nameservers [MAX_NAME_SERVERS ][SUB_DOMAIN_LEN ];
161+ for (int i = 0 ;i < name_count ;i ++ )
162+ strcpy (dup_nameservers [i ],nameservers [i ]);
163+ for (int i = 0 ;i < name_count ;i ++ )
164+ bzero (nameservers [i ],SUB_DOMAIN_LEN );
165+ for (int i = 0 ;i < name_count ;i ++ ){
166+ int temp = parse (div_sub_domains [j ],dup_nameservers [i ],nameservers );
167+ if (temp != 0 ){
168+ for (int i = 0 ;i < temp ;i ++ )
169+ printf ("%s\n" ,nameservers [i ]);
170+ name_count = temp ;
171+ break ;
172+ }
173+ }
174+ }
175+
176+ char command [BUFF_LEN ];
177+ for (int i = 0 ;i < name_count ;i ++ ){
178+ strcpy (command ,"nslookup -type=" );
179+ strcat (command ,req );
180+ strcat (command ," " );
181+ strcat (command ,buffer );
182+ strcat (command ," " );
183+ strcat (command ,nameservers [i ]);
184+ printf ("%s\n" ,command );
185+ const char * cmd = command ;
186+ char result [BUFF_LEN ] = "" ;
187+ FILE * out = popen (cmd , "r" );
188+ char buff [BUFF_LEN ];
189+ while (fgets (buff , 1000 , out ))
190+ strcat (result ,buff );
191+ pclose (out );
192+ sendto (sockfd ,result ,strlen (result ),0 ,(struct sockaddr * )& serv_storage ,addr );
193+
194+ FILE * fp = fopen ("cache.txt" ,"a" );
195+ fprintf (fp ,"%s-%s\n" ,buffer ,req );
196+ fprintf (fp ,"%s\n" ,result );
197+ fprintf (fp ,"-------\n" );
198+ fclose (fp );
199+ break ;
200+ }
201+ }
202+ }
203+
204+ close (sockfd );
205+
206+ return 0 ;
207+ }
0 commit comments