Advertisement
Guest User

Untitled

a guest
Nov 28th, 2015
61
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 20.91 KB | None | 0 0
  1. /*
  2.  
  3. Sofia Gonçalves 2011158780
  4. Rodrigo Almeida 2013140729
  5.  
  6. */
  7.  
  8. // Includes
  9.  
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include <unistd.h>
  13. #include <signal.h>
  14. #include <string.h>
  15. #include <sys/socket.h>
  16. #include <arpa/inet.h>
  17. #include <netinet/in.h>
  18. #include <unistd.h>
  19. #include <sys/ipc.h>
  20. #include <sys/shm.h>
  21. #include <sys/msg.h>
  22. #include <pthread.h>
  23. #include <semaphore.h>
  24. #include "includes.h"
  25. #include "structures.h"
  26. #include <sys/types.h>
  27. #include <sys/stat.h>
  28.  
  29. #define MAX_LEN 300
  30. #define MAX_DOMAINS 100
  31. #define N_PROCESSES 2
  32. #define LOCAL_DNS_PATH "localdns.txt"
  33.  
  34.  
  35. /*--------------------------------*/
  36. // Global Variables
  37.  
  38. pid_t processes[N_PROCESSES];
  39. ConfigMemory* config_memory;
  40. Host hosts[MAX_HOSTS];
  41. int shmid;
  42. pthread_t main_thread;
  43. List_high high;
  44. List normal;
  45. Threads threads; // Pool Threads
  46. pthread_mutex_t mutex; // Mutex of threads
  47.  
  48. FILE * wr_stream,*rd_stream;
  49. int res;
  50.  
  51. /*--------------------------------*/
  52. // Functions
  53.  
  54. // Given Functions
  55. void convertName2RFC (unsigned char*,unsigned char*);
  56. unsigned char* convertRFC2Name (unsigned char*,unsigned char*,int*);
  57. void sendReply(unsigned short, unsigned char*, int, int, struct sockaddr_in);
  58.  
  59. // Our Functions
  60. void readConfigFile();
  61. void read_localdns();
  62. int write_localdns(char endereco[]);
  63. void configProcess();
  64. void statsProcess();
  65. void requestProcess(int port);
  66. void print_list_high(List_high high);
  67. void print_list_normal(List normal);
  68. void go_through_high_list(List_high high, List_high *ant_high, List_high *useless_high);
  69. void go_through_normal_list(List normal, List *ant_normal, List *useless_normal);
  70. int empty_list_high(List_high high);
  71. int empty_list_normal(List normal);
  72. void remove_first_high(List_high high);
  73. void remove_first_normal(List normal);
  74. void destroy_high(List_high high);
  75. void destroy_normal(List normal);
  76. void init();
  77. void *mainThread(void *param);
  78. void terminate();
  79. void sigint(int sig);
  80. void sig_handler();
  81. void inicia_pipe();
  82. void envia_pipe(int action);
  83. int recebe_pipe();
  84.  
  85. int main(int argc, char const *argv[]) {
  86.  
  87. // Check arguments
  88. if(argc <= 1) {
  89. printf("Usage: dnsserver <port>\n");
  90. exit(1);
  91. }
  92.  
  93. // Get server UDP port number
  94. int port = atoi(argv[1]);
  95.  
  96. if(port <= 0) {
  97. printf("Usage: dnsserver <port>\n");
  98. exit(1);
  99. }
  100.  
  101. //Init
  102. init();
  103.  
  104. // Configuration Management Process
  105. if((processes[0]=fork())==0) {
  106. printf("\nInitializing Configuration Management Process (%d)...\n", getpid());
  107. configProcess();
  108.  
  109. // Signal SIGUSR1
  110. if (signal(SIGUSR1, sig_handler) == SIG_ERR)
  111. printf("\ncan't catch SIGUSR1\n");
  112.  
  113. if(signal(SIGINT,SIG_IGN)==SIG_ERR){
  114. perror("ERROR IGNORING SIGINT");
  115. exit(1);
  116. }
  117.  
  118. // A long long wait so that we can easily issue a signal to this process
  119. while(1)
  120. sleep(1);
  121. return 0;
  122. exit(0);
  123. }
  124.  
  125. // Wait For Configuration Management Process
  126. sleep(1);
  127.  
  128. //Initialize pipe
  129. void inicia_pipe();
  130.  
  131. // Statistics Process
  132. if((processes[1]=fork())==0) {
  133. printf("\nInitializing Statistics Process...\n");
  134. statsProcess();
  135. exit(0);
  136. }
  137.  
  138. // Wait For Statistics Process
  139. sleep(1);
  140.  
  141. // Create Main Thread
  142. if(pthread_create(&main_thread,NULL,mainThread,NULL)!=0){
  143. perror("\nCreating Main Thread...");
  144. terminate();
  145. }
  146.  
  147. // Wait for Main Thread
  148. sleep(2);
  149.  
  150. requestProcess(port);
  151.  
  152. return 0;
  153. }
  154.  
  155. // Configuration Management Process
  156. void configProcess() {
  157. int i;
  158.  
  159. // Read config.txt
  160. readConfigFile();
  161.  
  162. printf(" - Number of Threads: %d\n", config_memory->n_threads);
  163. printf(" - Domains (%d): ", config_memory->n_domains);
  164. for(i=0;i<config_memory->n_domains;i++) {
  165. if(i == config_memory->n_domains-1){
  166. printf("%s", config_memory->domains[i]);
  167. } else{
  168. printf("%s | ", config_memory->domains[i]);
  169. }
  170. }
  171. printf("\n");
  172. printf(" - Local Domain: %s\n", config_memory->local_domain);
  173. printf(" - Named Pipe: %s\n", config_memory->named_pipe);
  174.  
  175. read_localdns();
  176. }
  177.  
  178. void statsProcess(){
  179. int contador_pedidos = 0;
  180. int valor_pipe = 200;
  181.  
  182. while(1){
  183. valor_pipe = recebe_pipe();
  184. if (valor_pipe == 1){
  185. contador_pedidos ++;
  186. printf("O contador de pedidos agora esta a %d\n",contador_pedidos);
  187. }
  188. }
  189. }
  190.  
  191. void requestProcess(int port){
  192. unsigned char buf[65536], *reader;
  193. int sockfd, stop;
  194. struct DNS_HEADER *dns = NULL;
  195.  
  196. struct sockaddr_in servaddr, dest;
  197. socklen_t len;
  198.  
  199. // ****************************************
  200. // Create socket & bind
  201. // ****************************************
  202.  
  203. // Create UDP socket
  204. sockfd = socket(AF_INET , SOCK_DGRAM , IPPROTO_UDP); //UDP packet for DNS queries
  205.  
  206. if (sockfd < 0) {
  207. printf("ERROR opening socket.\n");
  208. exit(1);
  209. }
  210.  
  211. // Prepare UDP to bind port
  212. bzero(&servaddr,sizeof(servaddr));
  213. servaddr.sin_family = AF_INET;
  214. servaddr.sin_addr.s_addr=htonl(INADDR_ANY);
  215. servaddr.sin_port=htons(port);
  216.  
  217. // Bind application to UDP port
  218. int res = bind(sockfd,(struct sockaddr *)&servaddr,sizeof(servaddr));
  219.  
  220. if(res < 0) {
  221. printf("Error binding to port %d.\n", servaddr.sin_port);
  222.  
  223. if(servaddr.sin_port <= 1024) {
  224. printf("To use ports below 1024 you may need additional permitions. Try to use a port higher than 1024.\n");
  225. } else {
  226. printf("Please make sure this UDP port is not being used.\n");
  227. }
  228. exit(1);
  229. }
  230.  
  231. // ****************************************
  232. // Receive questions
  233. // ****************************************
  234.  
  235. while(1) {
  236. List_high high_node;
  237. List_high ant_high;
  238. List_high useless_high;
  239.  
  240. List normal_node;
  241. List ant_normal;
  242. List useless_normal;
  243.  
  244.  
  245. high_node = (List_high)malloc(sizeof(list_node_high));
  246. ant_high = (List_high)malloc(sizeof(list_node_high));
  247. useless_high = (List_high)malloc(sizeof(list_node_high));
  248.  
  249. normal_node = (List)malloc(sizeof(list_node));
  250. ant_normal = (List)malloc(sizeof(list_node));
  251. useless_normal = (List)malloc(sizeof(list_node));
  252.  
  253. // Receive questions
  254. len = sizeof(dest);
  255. printf("\n\n-- Wating for DNS message --\n\n");
  256. if(recvfrom (sockfd,(char*)buf , 65536 , 0 , (struct sockaddr*)&dest , &len) < 0) {
  257. printf("Error while waiting for DNS message. Exiting...\n");
  258. exit(1);
  259. }
  260.  
  261. printf("DNS message received\n");
  262.  
  263. // Process received message
  264. dns = (struct DNS_HEADER*) buf;
  265. //qname =(unsigned char*)&buf[sizeof(struct DNS_HEADER)];
  266. reader = &buf[sizeof(struct DNS_HEADER)];
  267.  
  268. printf("\nThe query %d contains: ", ntohs(dns->id));
  269. printf("\n %d Questions.",ntohs(dns->q_count));
  270. printf("\n %d Answers.",ntohs(dns->ans_count));
  271. printf("\n %d Authoritative Servers.",ntohs(dns->auth_count));
  272. printf("\n %d Additional records.\n\n",ntohs(dns->add_count));
  273.  
  274. // We only need to process the questions
  275. // We only process DNS messages with one question
  276. // Get the query fields according to the RFC specification
  277. struct QUERY query;
  278. if(ntohs(dns->q_count) == 1) {
  279. // Get NAME
  280. query.name = convertRFC2Name(reader,buf,&stop);
  281. reader = reader + stop;
  282.  
  283. // Get QUESTION structure
  284. query.ques = (struct QUESTION*)(reader);
  285. reader = reader + sizeof(struct QUESTION);
  286.  
  287. // Check question type. We only need to process A records.
  288. if(ntohs(query.ques->qtype) == 1) {
  289. printf("A record request.\n\n");
  290. } else {
  291. printf("NOT A record request!! Ignoring DNS message!\n");
  292. continue;
  293. }
  294.  
  295. } else {
  296. printf("\n\nDNS message must contain one question!! Ignoring DNS message!\n\n");
  297. continue;
  298. }
  299.  
  300. // Received DNS message fulfills all requirements.
  301.  
  302.  
  303. // ****************************************
  304. // Print received DNS message QUERY
  305. // ****************************************
  306. printf(">> QUERY: %s\n", query.name);
  307. printf(">> Type (A): %d\n", ntohs(query.ques->qtype));
  308. printf(">> Class (IN): %d\n\n", ntohs(query.ques->qclass));
  309.  
  310.  
  311. int valor_pipe = 1;
  312. // Check Domain
  313. if(strstr((char*)query.name, config_memory->local_domain) != NULL){
  314. printf(">>> Its a local domain!\n");
  315. printf(">>> Goes to High Priority Queue!\n");
  316. if(high_node != NULL){
  317. high_node->info = dns;
  318. high_node->dest = dest;
  319. high_node->sockfd = sockfd;
  320. high_node->name = query.name;
  321. go_through_high_list(high, &ant_high, &useless_high);
  322. high_node->next = ant_high->next;
  323. ant_high->next = high_node;
  324. envia_pipe(valor_pipe); //envia o valor 1 ao pipe para ele saber que ha mais um request
  325. }
  326. } else{
  327. printf(">>> Its an external domain!\n");
  328. printf(">>> Goes to Normal Priority Queue!\n");
  329. if(normal_node != NULL){
  330. normal_node->info = dns;
  331. normal_node->dest = dest;
  332. normal_node->sockfd = sockfd;
  333. normal_node->name = query.name;
  334. go_through_normal_list(normal, &ant_normal, &useless_normal);
  335. normal_node->next = ant_normal->next;
  336. ant_normal->next = normal_node;
  337. envia_pipe(valor_pipe); //envia o valor 1 ao pipe para ele saber que ha mais um request
  338. }
  339. }
  340. }
  341. }
  342.  
  343. int write_localdns(char endereco[]){
  344. FILE *fp;
  345. fp = fopen(LOCAL_DNS_PATH,"a");
  346.  
  347. if( fp == NULL )
  348. {
  349. printf("ERROR:I can't open the file \n");
  350. exit(1);
  351. }
  352.  
  353. fprintf(fp, "%s\n", endereco);
  354.  
  355. fclose(fp); //closing the file
  356. return 1;
  357. }
  358.  
  359. // Worker Thread (Thread in Pool)
  360. void *worker_thread(void * ptr_thread) {
  361. FILE* in;
  362. extern FILE *popen();
  363. char buff[512];
  364. int i;
  365. Thread* thread = (Thread*) ptr_thread;
  366.  
  367. while(1) {
  368. char command[MAX_LEN];
  369. read_localdns();
  370. pthread_mutex_lock(&(thread->mutex));
  371.  
  372. while(thread->flag == 0){
  373. pthread_cond_wait(&(thread->cond),&(thread->mutex));
  374. }
  375.  
  376. thread->flag = 1;
  377.  
  378. pthread_mutex_unlock(&(thread->mutex));
  379.  
  380. // Deals with Request
  381. if(strstr((char*)thread->name, config_memory->local_domain) != NULL){
  382. for(i=0; i<hosts[0].size_array; i++){
  383. if(strcmp(hosts[i].host_name, (char*)thread->name) == 0){
  384. sendReply(thread->request->id, thread->name, inet_addr(hosts[i].ip), thread->sockfd, thread->origin);
  385. break;
  386. }
  387. }
  388. } else{
  389. for(i=0; i<config_memory->n_domains; i++){
  390. if(strstr((char*)thread->name, config_memory->domains[i]) != NULL){
  391. strcpy(command, "dig +short ");
  392. strcat(command, (char*)thread->name);
  393. if(!(in = popen(command, "r"))){
  394. exit(1);
  395. }
  396. while(fgets(buff, sizeof(buff), in)!=NULL){
  397. sendReply(thread->request->id, thread->name, inet_addr(buff), thread->sockfd, thread->origin);
  398. break;
  399. }
  400. if(fgets(buff, sizeof(buff), in) == NULL){
  401. sendReply(thread->request->id, thread->name, inet_addr("0.0.0.0"), thread->sockfd, thread->origin);
  402. }
  403. pclose(in);
  404. break;
  405. } else{
  406. if(i == config_memory->n_domains -1){
  407. printf("That is not a valid external domain!\n");
  408. break;
  409. }
  410. }
  411. }
  412. }
  413.  
  414. sleep(3);
  415.  
  416. //Set thread as available
  417. threads.list[thread->id].flag = 0;
  418.  
  419. printf("Dealt by Thread (%d)\n",thread->id);
  420. }
  421. return NULL;
  422. }
  423.  
  424. void *mainThread(void *param){
  425. int i = 0;
  426.  
  427. printf("\nInitializing Threads...\n");
  428.  
  429. // Create Pool Threads
  430. threads.list = (Thread*) malloc ((config_memory->n_threads)*sizeof(Thread));
  431. for(i=0;i<config_memory->n_threads;i++) {
  432. if(pthread_create(&threads.list[i].thread,NULL,worker_thread,&threads.list[i])!=0){
  433. perror("thread pool\n");
  434. terminate();
  435. }
  436. threads.list[i].id = i;
  437. threads.list[i].flag = 0;
  438. threads.list[i].request = NULL;
  439. threads.list[i].cond = (pthread_cond_t)PTHREAD_COND_INITIALIZER;
  440. threads.list[i].mutex = (pthread_mutex_t)PTHREAD_MUTEX_INITIALIZER;
  441. }
  442.  
  443. sleep(1);
  444. printf(" - Main Thread...\n");
  445. printf(" - Pool Threads...\n");
  446.  
  447. while(1){
  448. //Primeiro temos a prioridade alta e depois vem a prioridade normal
  449. // Check Lists - verifica se as listas estao ou nao vazias
  450. if(empty_list_high(high) != 1){ //The list is not empty if the returned value is != 0 // Verifify if there are request with high Priority
  451. // Choose a thread free to solve the problem
  452. for(i=0;i<config_memory->n_threads;i++){
  453. // Thread Available
  454. if(threads.list[i].flag == 0) {
  455. // Sinalize Request In Thread --> Dar o primeiro no 'a thread e elimina-lo da lista
  456. threads.list[i].request = high->next->info;
  457. threads.list[i].sockfd = high->next->sockfd;
  458. threads.list[i].origin = high->next->dest;
  459. threads.list[i].name = high->next->name;
  460. remove_first_high(high);
  461. // Set Thread as Unavailable
  462. threads.list[i].flag = 1;
  463. // Call Worker Thread
  464. if(pthread_cond_signal(&threads.list[i].cond)!=0){
  465. perror("pthread cond signal");
  466. terminate();
  467. }
  468. break;
  469. }
  470. }
  471. } else if(empty_list_normal(normal) != 1){ // If not, take a request from normal priority
  472. if((config_memory->flag == 0) && (empty_list_normal(normal) != 1)){ // Check config_memory_flag --> Só resolve requests de high priority (SIGUSR1) //The list is not empty if the returned value is != 0 // Verifify if there are request with normal Priority
  473. // Choose a thread free to solve the problem
  474. for(i=0;i<config_memory->n_threads;i++) {
  475. // Thread Available
  476. if(threads.list[i].flag == 0) {
  477. pthread_mutex_unlock(&(threads.list[i].mutex));
  478. // Sinalize Request In Thread --> Dar o primeiro no 'a thread e elimina-lo da lista
  479. threads.list[i].request = normal->next->info;
  480. threads.list[i].sockfd = normal->next->sockfd;
  481. threads.list[i].origin = normal->next->dest;
  482. threads.list[i].name = normal->next->name;
  483. remove_first_normal(normal);
  484.  
  485. threads.list[i].flag = 1; // Set Thread as Unavailable
  486. // Call Worker Thread
  487. if(pthread_cond_signal(&threads.list[i].cond)!=0){
  488. perror("pthread cond signal");
  489. terminate();
  490. }
  491. pthread_mutex_unlock(&(threads.list[i].mutex));
  492. break;
  493. }
  494. }
  495. }
  496. }
  497. }
  498. }
  499.  
  500. void init() {
  501. printf("--- Initializing ---\n\n");
  502. printf("Initializing Resources...\n");
  503.  
  504. // Catch Signals
  505. printf(" - Catch Signals...\n");
  506. if(signal(SIGINT, sigint)==SIG_ERR){
  507. perror("sigint");
  508. exit(0);
  509. }
  510.  
  511. // Initialize Shared Memory
  512. printf(" - Shared Memory...\n");
  513. // - Connect to (and possibly create) the segment
  514. if ((shmid = shmget(IPC_PRIVATE, sizeof(ConfigMemory), IPC_CREAT|0700)) == -1) {
  515. perror("shmget");
  516. terminate();
  517. }
  518. // - Attach to the segment to get a pointer to it
  519. config_memory = (ConfigMemory*) shmat(shmid, NULL, 0);
  520. if (config_memory == (ConfigMemory*)(-1)) {
  521. perror("shmat");
  522. terminate();
  523. }
  524.  
  525. // Initialize High Priority Queue
  526. printf(" - High Priority Queue...\n");
  527. high = (List_high) malloc(sizeof(list_node_high));
  528. high->info = malloc(sizeof(struct DNS_HEADER*));
  529. if(high != NULL){
  530. high->info->id = 0;
  531. high->next = NULL;
  532. }
  533.  
  534. // Initialize Normal Priority Queue
  535. printf(" - Normal Priority Queue...\n");
  536. normal = (List) malloc(sizeof(list_node));
  537. normal->info = malloc(sizeof(struct DNS_HEADER*));
  538. if(normal != NULL){
  539. normal->info->id = 0;
  540. normal->next = NULL;
  541. }
  542. }
  543.  
  544.  
  545. void inicia_pipe(){
  546.  
  547. remove(config_memory->named_pipe);
  548. if (access(config_memory->named_pipe, F_OK) == -1) { //verifica se o FIFO já existe
  549.  
  550. res = mkfifo(config_memory->named_pipe,S_IRWXU);
  551.  
  552. if (res != 0) {
  553. fprintf(stderr, "Não consegui abrir o FIFO %s\n", config_memory->named_pipe);
  554. exit(0);
  555. }
  556. else{
  557. //printf("INICIEI O PIPE\n");
  558. }
  559. }
  560.  
  561. }
  562.  
  563. void envia_pipe(int action){
  564.  
  565. wr_stream = fopen(config_memory->named_pipe,"w");
  566.  
  567. fwrite(&action,sizeof(int),1,wr_stream);
  568.  
  569. fclose(wr_stream);
  570. }
  571.  
  572. int recebe_pipe(){
  573.  
  574. int action = -1;
  575.  
  576. rd_stream = fopen(config_memory->named_pipe,"r"); /* open fifo in read-only mode */
  577.  
  578. fread(&action,sizeof(int),1,rd_stream);
  579.  
  580. printf("ACTION : %d \n", action);
  581.  
  582. fclose(rd_stream); /* close the fifo */
  583.  
  584. return action;
  585. }
  586.  
  587.  
  588. // Terminate Server
  589. void terminate() {
  590. int i;
  591. printf("\n--- Terminating ---\n\n");
  592.  
  593. // Kill Child Processes
  594. printf("Killing Child Processes...\n");
  595. for(i=0;i<N_PROCESSES;i++) {
  596. kill(processes[i], SIGTERM);
  597. printf(" - Child Process %i Killed!\n", i);
  598. }
  599. printf("\n");
  600.  
  601. // Destroy Threads
  602. pthread_cancel(main_thread);
  603. printf("Destroying Threads...\n");
  604. for(i=0;i<config_memory->n_threads;i++){
  605. pthread_mutex_destroy(&(threads.list[i].mutex));
  606. pthread_cancel(threads.list[i].thread);
  607.  
  608. }
  609. printf(" - DONE!\n");
  610.  
  611.  
  612. // Destroy Shared Memory
  613. printf("Destroying Shared Memory...\n");
  614. shmdt(config_memory);
  615. shmctl(shmid, IPC_RMID, NULL);
  616. printf(" - DONE!\n");
  617.  
  618. // Destroy Lists
  619. printf("Destroying Priority Lists...\n");
  620. destroy_normal(normal);
  621. destroy_high(high);
  622. printf(" - DONE!\n");
  623.  
  624. exit(0);
  625. }
  626.  
  627. // Functions from dnsserver.c
  628. /**
  629. sendReply: this method sends a DNS query reply to the client
  630. * id: DNS message id (required in the reply)
  631. * query: the requested query name (required in the reply)
  632. * ip_addr: the DNS lookup reply (the actual value to reply to the request)
  633. * sockfd: the socket to use for the reply
  634. * dest: the UDP package structure with the information of the DNS query requestor (includes it's IP and port to send the reply)
  635. **/
  636.  
  637. void sendReply(unsigned short id, unsigned char* query, int ip_addr, int sockfd, struct sockaddr_in dest) {
  638. unsigned char bufReply[65536], *rname;
  639. char *rip;
  640. struct R_DATA *rinfo = NULL;
  641.  
  642. //Set the DNS structure to reply (according to the RFC)
  643. struct DNS_HEADER *rdns = NULL;
  644. rdns = (struct DNS_HEADER *)&bufReply;
  645. rdns->id = id;
  646. rdns->qr = 1;
  647. rdns->opcode = 0;
  648. rdns->aa = 1;
  649. rdns->tc = 0;
  650. rdns->rd = 0;
  651. rdns->ra = 0;
  652. rdns->z = 0;
  653. rdns->ad = 0;
  654. rdns->cd = 0;
  655. rdns->rcode = 0;
  656. rdns->q_count = 0;
  657. rdns->ans_count = htons(1);
  658. rdns->auth_count = 0;
  659. rdns->add_count = 0;
  660.  
  661. // Add the QUERY name (the same as the query received)
  662. rname = (unsigned char*)&bufReply[sizeof(struct DNS_HEADER)];
  663. convertName2RFC(rname , query);
  664.  
  665. // Add the reply structure (according to the RFC)
  666. rinfo = (struct R_DATA*)&bufReply[sizeof(struct DNS_HEADER) + (strlen((const char*)rname)+1)];
  667. rinfo->type = htons(1);
  668. rinfo->_class = htons(1);
  669. rinfo->ttl = htonl(3600);
  670. rinfo->data_len = htons(sizeof(ip_addr)); // Size of the reply IP address
  671.  
  672. // Add the reply IP address for the query name
  673. rip = (char *)&bufReply[sizeof(struct DNS_HEADER) + (strlen((const char*)rname)+1) + sizeof(struct R_DATA)];
  674. memcpy(rip, (struct in_addr *) &ip_addr, sizeof(ip_addr));
  675.  
  676. // Send DNS reply
  677. printf("\nSending Answer... ");
  678. if( sendto(sockfd, (char*)bufReply, sizeof(struct DNS_HEADER) + (strlen((const char*)rname) + 1) + sizeof(struct R_DATA) + sizeof(ip_addr),0,(struct sockaddr*)&dest,sizeof(dest)) < 0) {
  679. printf("FAILED!!\n");
  680. } else {
  681. printf("SENT!!!\n");
  682. }
  683. }
  684.  
  685. /**
  686. convertRFC2Name: converts DNS RFC name to name
  687. **/
  688. u_char* convertRFC2Name(unsigned char* reader,unsigned char* buffer,int* count) {
  689. unsigned char *name;
  690. unsigned int p=0,jumped=0,offset;
  691. int i , j;
  692.  
  693. *count = 1;
  694. name = (unsigned char*)malloc(256);
  695.  
  696. name[0]='\0';
  697.  
  698. while(*reader!=0) {
  699. if(*reader>=192) {
  700. offset = (*reader)*256 + *(reader+1) - 49152;
  701. reader = buffer + offset - 1;
  702. jumped = 1;
  703. } else {
  704. name[p++]=*reader;
  705. }
  706.  
  707. reader = reader+1;
  708.  
  709. if(jumped==0) {
  710. *count = *count + 1;
  711. }
  712. }
  713.  
  714. name[p]='\0';
  715. if(jumped==1) {
  716. *count = *count + 1;
  717. }
  718.  
  719. for(i=0;i<(int)strlen((const char*)name);i++) {
  720. p=name[i];
  721. for(j=0;j<(int)p;j++) {
  722. name[i]=name[i+1];
  723. i=i+1;
  724. }
  725. name[i]='.';
  726. }
  727. name[i-1]='\0';
  728. return name;
  729. }
  730.  
  731. /**
  732. convertName2RFC: converts name to DNS RFC name
  733. **/
  734. void convertName2RFC(unsigned char* dns,unsigned char* host) {
  735. int lock = 0 , i;
  736. strcat((char*)host,".");
  737.  
  738. for(i = 0 ; i < strlen((char*)host) ; i++) {
  739. if(host[i]=='.') {
  740. *dns++ = i-lock;
  741. for(;lock<i;lock++) {
  742. *dns++=host[lock];
  743. }
  744. lock++;
  745. }
  746. }
  747. *dns++='\0';
  748. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement