Advertisement
Guest User

Anton tukang berak

a guest
Nov 2nd, 2013
737
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 46.71 KB | None | 0 0
  1. /*
  2.  * rldns - Ringlayer DNS Based Load Balancer Server 1.0.0
  3.  *  
  4.  * Developed by Antonius  (Sw0rdm4n)
  5.  *
  6.  * Official Website : www.ringlayer.net
  7.  *
  8.  * www.ringlayer.com - www.cr0security.com - www.jasaplus.com - www.komputekno.org - c0debreaker.com
  9.  * thanks www.indonesianbacktrack.or.id
  10.  *
  11.  * This program is free software; you can redistribute it and/or modify
  12.  * it under the terms of the GNU General Public License as published by
  13.  * the Free Software Foundation; either version 2 of the License, or
  14.  * (at your option) any later version.
  15.  *
  16.  * This program is distributed in the hope that it will be useful,
  17.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19.  * GNU General Public License for more details.
  20.  *
  21.  * You should have received a copy of the GNU General Public License
  22.  * along with this program; if not, write to the Free Software
  23.  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  24.  *
  25.  */
  26.  
  27. #include <sys/stat.h>
  28. #include <stdio.h>
  29. #include <stdlib.h>
  30. #include <string.h>
  31. #include <unistd.h>
  32. #include <errno.h>
  33. #include <pwd.h>
  34. #include <pthread.h>
  35. #include <time.h>
  36. #include <ctype.h>
  37. #include <fcntl.h>
  38. #include <time.h>
  39. #include <sys/mman.h>
  40. #include <sys/wait.h>
  41. #include <sys/stat.h>
  42. #include <sys/types.h>
  43. #include <sys/epoll.h>
  44. #include <sys/syslog.h>
  45. #include <sys/socket.h>
  46. #include <sys/prctl.h>
  47. #include <netinet/in.h>
  48. #include <netdb.h>
  49. #include <arpa/inet.h>
  50. #include <dirent.h>
  51. #include <limits.h>
  52. #define CONFIG "rldns.conf"
  53. #define PACKET_SIZE 512
  54. #define MAX_ZONE_FILE_LINE_LENGTH 256
  55. #define MAX_A_LENGTH_ALLOWED 62
  56. #define MAX_ANSWER_LENGTH_ALLOWED ((16 + 12) * 18)
  57. #define header_length 13
  58. /**
  59. rfc  reference
  60. - http://tools.ietf.org/html/rfc1035
  61.  
  62. for a resolver
  63. this dns software has 2 types method to resolve a name request
  64. - a_resolver_type 1, if more than 1 ip to resolve, this will do a dns based load balancing without randomizing ip addresses
  65. - a_resolver_type 2, if more than 1 ip to resolve, this will randomize multiple ip sequences for dns based load balancing (this will works if A ip to resolve is more than 3)
  66. **/
  67.  
  68. /** uncomment this for a resolver type 1
  69. static const int a_resolver_type = 1;
  70. **/
  71.  
  72. static const int a_resolver_type = 2;
  73.  
  74. typedef int boolean;
  75. static const boolean true = 1;
  76. static const boolean false = 0;
  77.  
  78. /** static variables start **/
  79. //static const char *user = "rldns";
  80. static const int max_buf =  255;
  81. static int epoll_fd;
  82. static const uint8_t BACKLOG = 4;
  83. static const int max_domain_name_length = 253;
  84. static int already_prctl = 0;
  85.  
  86. /** rldns default settings **/
  87. int tsc = 1;
  88. int rldns_port;
  89. int worker;
  90. int thread;
  91. char *version;
  92. char *zones_path;
  93. /** eof static variables **/
  94.  
  95. /** dns packet **/
  96. int zone_count = 0;
  97. /** eof dns packet **/
  98.  
  99. /** vars **/
  100. char *fail_nonblock = "\n | rldns : Fatal Warning ! failed to create a non blocking socket for handling multiple connection ! |\n";
  101. char *no_config = "\n | rldns : Fatal Error ! rldns.conf not found ! exit ! |\n";
  102. char *sock_fail = "\n  | rldns : Fatal Error ! failed to create socket ! exit ! |\n";
  103. char *no_user = "\n  | rldns : Fatal Error ! no rldns user ! please adduser rldns first ! exit ! |\n";
  104. char *fail_reuseaddr = "\n | rldns : Warning ! failed to setsockopt for reuseaddr ! |\n";
  105. char *fail_bind = "\n | rldns : Fatal Error ! failed to bind socket ! |\n";
  106. char *no_zones = "\n | rldns : Fatal Error !  no zone files found, please add domain zone file(s) ! |\n";
  107. char *no_zonepath = "\n | rldns : Fatal Error !  incorrect zone path , please check your zone setting at cbdns.conf ! |\n";
  108. char *failed_prctl = "\n | rldns : Warning ! prctl failed to control cr4 ! |\n";
  109. /** eof vars **/
  110.  
  111. /**
  112. tmp data(s)
  113. **/
  114. char *tmp_ip;
  115. int tmp_domain_uid;
  116. /** eof tmp datas **/
  117.  
  118. /** structs **/
  119. struct passwd *p;
  120. struct epoll_event _epoll_event;
  121. struct epoll_event *_epoll_events;
  122. struct sockaddr_in server_addr;  
  123. struct sockaddr_in client_addr;
  124.  
  125. typedef struct {
  126.     int _cur_receive;
  127.     char *_cur_dns_response;
  128.     char  *_cur_tot_res_ip;
  129.     int _cur_ans_count;
  130. } _st_struct_current_dns_resp;
  131.  
  132. typedef struct {
  133.     int port;
  134.     int worker;
  135.     int thread;
  136.     char *version;
  137.     char *zones;
  138. }_st_configurations;
  139.  
  140. typedef struct {
  141.     int uid;
  142.     char *a_ip1;
  143.     char *a_ip2;
  144.     char *a_ip3;
  145.     char *a_ip4;
  146.     char *a_ip5;
  147.     char *a_ip6;
  148.     char *a_ip7;
  149.     char *a_ip8;
  150.     char *a_ip9;
  151.     char *a_ip10;
  152.     char *a_ip11;
  153.     char *a_ip12;
  154.     char *a_ip13;
  155.     char *a_ip14;
  156.     char *a_ip15;
  157.     char *a_ip16;
  158.     char *a_ip17;
  159.     char *a_ip18;
  160. }_st_a_res;
  161.  
  162. typedef struct {
  163.     int uid;
  164.     char *cname1;
  165.     char *cname2;
  166.     char *cname3;
  167.     char *cname4;
  168.     char *cname5;
  169. } _st_cname;
  170.  
  171. typedef struct {
  172.     int uid;
  173.     char *mx_host;
  174. } _st_mx;
  175.  
  176. typedef struct {
  177.     int uid;
  178.     char *ns1;
  179.     char *ns1_ip;
  180.     char *ns2;
  181.     char *ns2_ip;
  182.     char *ns3;
  183.     char *ns3_ip;
  184.     char *ns4;
  185.     char *ns4_ip;
  186. } _st_ns;
  187.  
  188. typedef struct {
  189.     int uid;
  190.     char *zone_aname;
  191. } _st_zone;
  192.  
  193. typedef struct {
  194.     int uid;   
  195.     char *domain_zone;
  196.     int domain_zone_a_ip_count;
  197.     int domain_zone_cname_count;
  198.     int domain_zone_mx_count;
  199.     int domain_zone_ns_count;
  200. } _st_mainstruct_domain_zone;
  201.  
  202. _st_configurations *_cfg;
  203. _st_mainstruct_domain_zone *_ret_st_mainstruct_domain_zone;
  204. _st_zone *_ret_struct_dns_zone;
  205. _st_a_res *_ret_struct_a_res;
  206. _st_cname *_ret_struct_cname;
  207. _st_mx *_ret_struct_mx;
  208. _st_ns *_ret_struct_ns;
  209. _st_struct_current_dns_resp *_ret_st_struct_current_dns_resp;
  210.  
  211. static inline char *do_craft_dns_ns_response(char *qid, char *a_name, char *dns_response, int receive, int zone_uid);
  212. static inline char *do_craft_dns_mx_response(char *qid, char *a_name, char *dns_response, int receive, int zone_uid);
  213. static inline boolean validate_ipv4_octet(char *ipaddr);
  214. static inline char *_set_randomize_a_ip(int zone_uid);
  215. static inline char *_last_replace(char *original_str, char *str_to_replace, char *replacer_str);
  216. static inline char *get_current_dns_qid(char *msg);
  217. static inline char *n_malloc(ssize_t size);
  218. static inline char *craft_dns_aname_response(char *qid, char *dns_response, int receive);
  219. static inline char *craft_dns_mx_response(char *qid, char *dns_response, int receive);
  220. static inline char *craft_dns_ns_response(char *qid, char *dns_response, int receive);
  221. static inline char *determine_dns_request_type(char *request);
  222. static inline char *rtrim(char *str);
  223. static inline char *ltrim(char *str);
  224. static inline char *trim(char *str);
  225. static inline char *parse_dns_query_and_fetch_a_req(char *msg, char *mode);
  226. static  inline char *do_craft_dns_aname_response(char *total_res_ip, char *qid, char *a_name, char *dns_response, int receive, int zone_uid);
  227. static inline int _count_answer_length(char *total_res_ip, char *mode);
  228. static inline int _do_rdtsc();
  229.  
  230. static inline boolean validate_ipv4_octet(char *ipaddr)
  231. {
  232.     int j, octet_found = 0;
  233.     boolean valid = false;
  234.    
  235.     for (j = 0; j < (strlen(ipaddr)); j++) {
  236.         if (tmp_ip[j] == 0x2e)
  237.             octet_found++;
  238.     }
  239.     if (octet_found > 2)
  240.         valid = true;
  241.    
  242.     return valid;
  243. }
  244.  
  245. inline long get_file_length_or_line_count(char *filename, char *mode)
  246. {
  247.     FILE *fd;
  248.     int filename_len, len, retval, tot;
  249.     char str[256] = "\0";
  250.     char *pcs = "\0";  
  251.    
  252.     filename_len = strlen(filename);
  253.     tot = filename_len + 7;
  254.     char cmd[tot];  
  255.     if (strstr(mode, "lengt"))
  256.         snprintf(cmd,tot,"wc -c %s",filename);
  257.     else
  258.         snprintf(cmd,tot,"wc -l %s",filename);
  259.     fd = popen(cmd,"r");
  260.     while(fgets(str, max_buf, fd)!=NULL) {
  261.         len = strlen(str);
  262.         if ((len > 1)) {
  263.             pcs = strtok(str, " ");
  264.             retval = atoi(pcs);
  265.         }
  266.     }
  267.     pclose(fd);
  268.    
  269.     return (retval);
  270. }
  271.  
  272. static inline char *get_current_dns_qid(char *msg)
  273. {
  274.     char *qid;
  275.    
  276.     qid = n_malloc(2);
  277.     qid[0] = msg[0];
  278.     qid[1] = msg[1];
  279.  
  280.     return qid;
  281. }
  282.  
  283. static inline int find_element(int seekat[], int num)
  284. {
  285.     int i, found = 0;
  286.    
  287.     for (i = 0; i < 20; i++) {
  288.         if (seekat[i] == num) {
  289.             found = 1;
  290.             break;
  291.         }
  292.     }
  293.    
  294.     return found;
  295. }
  296.  
  297. static inline char *_last_replace(char *original_str, char *str_to_replace, char *replacer_str)
  298. {
  299.     char *clean_str;
  300.     int i, z, half_done, len_original_str, len_str_to_replace, len_replacer_str, len_clean_str;
  301.    
  302.     len_original_str = strlen(original_str);
  303.     len_str_to_replace = strlen(str_to_replace);
  304.     i = 0;
  305.     if (replacer_str == NULL) {
  306.         len_clean_str = len_original_str - len_str_to_replace;
  307.         clean_str = n_malloc(len_clean_str);
  308.         for (i = 0; i < len_clean_str; i++)
  309.             clean_str[i] = original_str[i];
  310.     }
  311.     else {
  312.         len_replacer_str = strlen(replacer_str);
  313.         half_done = len_original_str - len_str_to_replace;
  314.         len_clean_str = (len_original_str - len_str_to_replace) + len_replacer_str;
  315.         clean_str = n_malloc(len_clean_str);
  316.         for (i = 0; i < half_done; i++)
  317.             clean_str[i] = original_str[i];
  318.         z = 0;
  319.         for (i = half_done; i < len_clean_str;i++) {
  320.             clean_str[i] = replacer_str[z];
  321.             z++;
  322.         }  
  323.     }
  324.     return clean_str;
  325.     if (clean_str)
  326.         free(clean_str);
  327. }
  328.  
  329. static int cont_or_no()
  330. {
  331.     char y_or_n;
  332.    
  333.     fprintf(stdout, "\n Warning ! Failed to set non blocking socket ! No concurreny, server may not handle multiple client ! Do you want to continue running server ? (y/n)"); 
  334.     y_or_n = getchar();
  335.    
  336.     return y_or_n;
  337. }
  338.  
  339. int daemonize()
  340. {
  341.     pid_t worker_pid;
  342.    
  343.     worker_pid = fork();
  344.     if (worker_pid != 0)
  345.         exit(0);
  346.    
  347.     return 0;
  348. }
  349.  
  350. static inline char *n_malloc(ssize_t size)
  351. {
  352.     char *retme;
  353.    
  354.     retme = malloc((size + 1) * sizeof(char));
  355.     memset(retme, '\0', size + 1);
  356.    
  357.     return (retme);
  358. }
  359.  
  360. static inline void _msg_err(char *msg)
  361. {
  362.     fprintf(stdout, "%s", msg);
  363.     syslog(LOG_DAEMON, "%s", msg); 
  364.     /** ignore warning rldns will keep continue **/
  365. }
  366.  
  367. static inline  void _msg_terminated_err(char *msg)
  368. {
  369.     fprintf(stdout, "%s", msg);
  370.     syslog(LOG_DAEMON, "%s", msg);
  371.     exit(0);
  372. }
  373.  
  374. static inline void stop_crash()
  375. {
  376.     pid_t pid;
  377.     int status;
  378.    
  379.     while ((pid = waitpid(-1, &status, WNOHANG)) > 0)
  380.         return;
  381. }
  382.  
  383. /**
  384. int static _init_set_cred()
  385. {
  386.     int rldns_uid, rldns_gid;
  387.    
  388.     if ((p = getpwnam(user)) == NULL)
  389.         _msg_terminated_err(no_user);      
  390.     rldns_uid = (int) (p->pw_uid);
  391.     rldns_gid =  (int) (p->pw_gid);
  392.     setuid(rldns_uid);
  393.     setgid(rldns_gid);
  394.     seteuid(rldns_uid);
  395.    
  396.     return 0;  
  397. }
  398. **/
  399.  
  400. static _st_configurations *_init_read_parse_config()
  401. {
  402.     _st_configurations *rldns_config;
  403.     char *result = NULL;
  404.     FILE *config;
  405.     int total_line, len, cur_line = 0;
  406.     char str[256] = "\0";
  407.     int struct_offset, offset_port, offset_worker, offset_thread, offset_version, offset_zones = 0;
  408.     int total_config_length = 0;
  409.    
  410.     struct_offset = 0;
  411.     rldns_config = malloc(1 * sizeof(_st_configurations));
  412.     fprintf(stdout, "\t[+] reading rldns configuration file\n");
  413.     offset_port = 0;
  414.     offset_worker = 0;
  415.     offset_thread = 0;
  416.     offset_version = 0;
  417.     result = n_malloc(256);
  418.     config = fopen(CONFIG, "r");
  419.     if (!config)
  420.         _msg_terminated_err(no_config);
  421.     total_line = get_file_length_or_line_count(CONFIG, "line");
  422.     total_config_length = get_file_length_or_line_count(CONFIG, "length");
  423.     while((fgets(str, max_buf, config) != NULL) && (cur_line <= total_line)) {
  424.         len = strlen(str);
  425.         if (len > 1)
  426.             if (!strstr(str, ";")) {
  427.                 result = strtok(str, " ");
  428.                 while(result != NULL) {
  429.                     result = trim(result);
  430.                     /** fillin the configuration struct **/
  431.                     if (offset_version == 1) {
  432.                         (rldns_config + struct_offset)->version =  n_malloc(strlen(result));
  433.                         (rldns_config + struct_offset)->version = trim(result);
  434.                         version =  n_malloc(strlen((rldns_config + struct_offset)->version));
  435.                         strcpy(version, (rldns_config + struct_offset)->version);
  436.                         fprintf(stdout, "\t[+] rldns version : %s\n", (rldns_config + struct_offset)->version);
  437.                     }
  438.                     if (offset_zones == 1) {
  439.                         (rldns_config + struct_offset)->zones =  n_malloc(strlen(result));
  440.                         (rldns_config + struct_offset)->zones = trim(result);
  441.                         zones_path =  n_malloc(strlen((rldns_config + struct_offset)->zones));
  442.                         strcpy(zones_path, (rldns_config + struct_offset)->zones);
  443.                         fprintf(stdout, "\t[+] rldns zone(s) : %s\n",(rldns_config + struct_offset)->zones);
  444.                     }
  445.                     if (offset_port == 1) {
  446.                         (rldns_config + struct_offset)->port = atoi(result);
  447.                         rldns_port = (rldns_config + struct_offset)->port;
  448.                         fprintf(stdout, "\t[+] rldns port : %d\n", (rldns_config + struct_offset)->port);
  449.                     }
  450.                     if (offset_worker == 1) {
  451.                         (rldns_config + struct_offset)->worker = atoi(result);
  452.                         worker = (rldns_config + struct_offset)->worker;
  453.                         fprintf(stdout, "\t[+] rldns worker(s) : %d\n", (rldns_config + struct_offset)->worker);
  454.                     }
  455.                     if (offset_thread == 1) {
  456.                         (rldns_config + struct_offset)->thread = atoi(result);
  457.                         thread = (rldns_config + struct_offset)->thread;
  458.                         fprintf(stdout, "\t[+] rldns thread(s) : %d\n", (rldns_config + struct_offset)->thread);
  459.                     }
  460.                     if (strcmp(result, "port") == 0)
  461.                         offset_port = 1;
  462.                     else
  463.                         offset_port = 0;
  464.                     if (strcmp(result, "worker") == 0)
  465.                         offset_worker = 1;
  466.                     else
  467.                         offset_worker = 0;
  468.                     if (strcmp(result, "thread") == 0)
  469.                         offset_thread = 1;
  470.                     else
  471.                         offset_thread = 0;
  472.                     if (strcmp(result, "version") == 0)
  473.                         offset_version = 1;
  474.                     else
  475.                         offset_version = 0;
  476.                     if (strcmp(result, "zones") == 0)
  477.                         offset_zones = 1;
  478.                     else
  479.                         offset_zones = 0;
  480.                     result = strtok(NULL, " ");
  481.                 }  
  482.             }      
  483.         cur_line++;
  484.     }  
  485.     fclose(config);
  486.    
  487.     return rldns_config;
  488. }
  489.  
  490. static void _check_config()
  491. {
  492.     struct stat buf;
  493.    
  494.     if (stat("rldns.conf", &buf) == 0)
  495.         printf("\t[+] found configuration file : rldns.conf \n");  
  496.     else
  497.         _msg_terminated_err(no_config);
  498. }
  499.  
  500. /** string trimming functions taken from http://en.wikipedia.org/wiki/Trimming_%28computer_programming%29#C.2FC.2B.2B **/
  501. static inline char *rtrim(char *str)
  502. {
  503.     int n = 0;
  504.    
  505.     n = strlen(str);
  506.     while (n > 0 && isspace((unsigned char)str[n - 1]))
  507.         n--;
  508.     str[n] = '\0';
  509.    
  510.     return (str);
  511. }
  512.  
  513. static inline char *ltrim(char *str)
  514. {
  515.     int n = 0;
  516.    
  517.     while (str[n] != '\0' && isspace((unsigned char)str[n]))
  518.         n++;
  519.     memmove(str, str + n, strlen(str) - n + 1);
  520.     return (str);
  521. }
  522.  
  523. static inline char *trim(char *str)
  524. {
  525.     str = rtrim(str);
  526.     str = ltrim(str);
  527.    
  528.     return (str);
  529. }
  530.  
  531. /**
  532. prctl and rdtsc reference taken from :
  533. http://man7.org/linux/man-pages/man2/prctl.2.html
  534. http://www.mcs.anl.gov/~kazutomo/rdtsc.html
  535.  
  536. Trying to get timestamp for seeding srand later, cr4 register control must be enabled
  537. **/
  538.  
  539. static inline int _do_rdtsc()
  540. {
  541.     if (already_prctl == 0) {
  542.         if ((prctl(PR_SET_TSC, PR_TSC_ENABLE)) == -1) {
  543.             _msg_err(failed_prctl);
  544.         }
  545.         already_prctl = 1;
  546.     }
  547.     __asm__ __volatile__ ("rdtsc");
  548. }
  549.  
  550. static int fcntl_nonblock(int sock_fd)
  551. {
  552.     if (fcntl(sock_fd, F_SETFL, fcntl(sock_fd, F_GETFD, 0) | O_NONBLOCK) == -1) {
  553.         _msg_err(fail_nonblock);
  554.         return -1;
  555.     }
  556.    
  557.     return 0;
  558. }
  559.  
  560. /**
  561. epoll usage reference from : https://banu.com/blog/2/how-to-use-epoll-a-complete-example-in-c
  562. **/
  563.  
  564. static _st_mainstruct_domain_zone *_read_zone_file()
  565. {
  566.     DIR  *dir_fd;
  567.     char *zone_file_name, *full_path, *fgets_res = NULL;
  568.     struct dirent *zone_list;
  569.     FILE *zone_fd;
  570.     int a_count, cname_count, mx_count, ns_count, current_zone_count;
  571.     char *tmp_pcs, *tmp_ns, *tmp_ns_ip;
  572.    
  573.     _ret_st_mainstruct_domain_zone = malloc(200 * sizeof(_ret_st_mainstruct_domain_zone));
  574.     _ret_struct_dns_zone = malloc(200 * sizeof(_st_zone));
  575.     _ret_struct_a_res = malloc(200 * sizeof(_st_a_res));
  576.     _ret_struct_cname = malloc(200 * sizeof(_st_cname));
  577.     _ret_struct_mx = malloc(200 * sizeof(_st_mx));
  578.     _ret_struct_ns = malloc(200 * sizeof(_st_ns));
  579.     strtok(zones_path, "/");
  580.     dir_fd = opendir(zones_path);  
  581.     if (dir_fd == NULL)
  582.         _msg_terminated_err(no_zonepath);
  583.     current_zone_count = 0;
  584.     while ((zone_list =  readdir(dir_fd))) {
  585.         if (strstr(zone_list->d_name, ".zone")) {
  586.             full_path = n_malloc((strlen(zone_list->d_name)) + strlen(zones_path) + 1);
  587.             strncat(full_path, trim(zones_path), strlen(zones_path));
  588.             strncat(full_path, "/", 1);
  589.             strncat(full_path, trim(zone_list->d_name), strlen(zone_list->d_name));
  590.             zone_file_name = n_malloc(strlen(zone_list->d_name));
  591.             zone_file_name = zone_list->d_name;
  592.             zone_fd = fopen(full_path, "r");
  593.             if (zone_fd != NULL) {
  594.                 fgets_res = n_malloc(MAX_ZONE_FILE_LINE_LENGTH);
  595.                 while ((fgets(fgets_res, MAX_ZONE_FILE_LINE_LENGTH, zone_fd)) != NULL) {
  596.                     trim(fgets_res);
  597.                     /** a records **/
  598.                     if (strstr(fgets_res, "masterzone ")) {
  599.                         a_count = 0;
  600.                         cname_count = 0;
  601.                         mx_count = 0;
  602.                         ns_count = 0;
  603.                         current_zone_count = zone_count;
  604.                         tmp_pcs = strtok(fgets_res, " ");
  605.                         tmp_pcs = strtok(NULL, " ");   
  606.                         ((_ret_st_mainstruct_domain_zone) + current_zone_count)->domain_zone = strdup(tmp_pcs);
  607.                         ((_ret_st_mainstruct_domain_zone) + current_zone_count)->uid = zone_count; 
  608.                         ((_ret_struct_dns_zone) + current_zone_count)->zone_aname = strdup(tmp_pcs);   
  609.                         ((_ret_struct_dns_zone) + current_zone_count)->uid = zone_count;   
  610.                         ((_ret_struct_a_res) + current_zone_count)->uid = zone_count;
  611.                         tmp_domain_uid = current_zone_count;
  612.                         ((_ret_struct_cname) + zone_count)->uid = zone_count;
  613.                         ((_ret_struct_mx) + zone_count)->uid = zone_count;
  614.                         ((_ret_struct_ns) + zone_count)->uid = zone_count;
  615.                         printf("=========================================================\n");
  616.                         printf("\tmainstruct dom [%s]\n",((_ret_st_mainstruct_domain_zone) + zone_count)->domain_zone);
  617.                         zone_count++;
  618.                     }
  619.                     if (strstr(fgets_res, "Arecord ")) {
  620.                         tmp_pcs = strtok(fgets_res, " ");
  621.                         tmp_pcs = strtok(NULL, " ");
  622.                         _ret_st_mainstruct_domain_zone[current_zone_count].domain_zone_a_ip_count++;
  623.                         a_count++;
  624.                         switch(a_count) {
  625.                             case 1:
  626.                             if (strlen(tmp_pcs) > 0)       
  627.                                 ((_ret_struct_a_res) + current_zone_count)->a_ip1 = strdup(tmp_pcs);       
  628.                             break;
  629.                             case 2:
  630.                             if (strlen(tmp_pcs) > 0)       
  631.                                 ((_ret_struct_a_res) + current_zone_count)->a_ip2 = strdup(tmp_pcs);       
  632.                             break;
  633.                             case 3:
  634.                             if (strlen(tmp_pcs) > 0)       
  635.                                 ((_ret_struct_a_res) + current_zone_count)->a_ip3 = strdup(tmp_pcs);       
  636.                             break;
  637.                             case 4:
  638.                             if (strlen(tmp_pcs) > 0)       
  639.                                 ((_ret_struct_a_res) + current_zone_count)->a_ip4 = strdup(tmp_pcs);       
  640.                             break;
  641.                             case 5:
  642.                             if (strlen(tmp_pcs) > 0)       
  643.                                 ((_ret_struct_a_res) + current_zone_count)->a_ip5 = strdup(tmp_pcs);       
  644.                             break;
  645.                             case 6:
  646.                             if (strlen(tmp_pcs) > 0)       
  647.                                 ((_ret_struct_a_res) + current_zone_count)->a_ip6 = strdup(tmp_pcs);       
  648.                             break;
  649.                             case 7:
  650.                             if (strlen(tmp_pcs) > 0)       
  651.                                 ((_ret_struct_a_res) + current_zone_count)->a_ip7 = strdup(tmp_pcs);       
  652.                             break;
  653.                             case 8:
  654.                             if (strlen(tmp_pcs) > 0)       
  655.                                 ((_ret_struct_a_res) + current_zone_count)->a_ip8 = strdup(tmp_pcs);       
  656.                             break;
  657.                             case 9:
  658.                             if (strlen(tmp_pcs) > 0)       
  659.                                 ((_ret_struct_a_res) + current_zone_count)->a_ip9 = strdup(tmp_pcs);       
  660.                             break;
  661.                             case 10:
  662.                             if (strlen(tmp_pcs) > 0)       
  663.                                 ((_ret_struct_a_res) + current_zone_count)->a_ip10 = strdup(tmp_pcs);      
  664.                             break;
  665.                             case 11:
  666.                             if (strlen(tmp_pcs) > 0)       
  667.                                 ((_ret_struct_a_res) + current_zone_count)->a_ip11 = strdup(tmp_pcs);      
  668.                             break;
  669.                             case 12:
  670.                             if (strlen(tmp_pcs) > 0)       
  671.                                 ((_ret_struct_a_res) + current_zone_count)->a_ip12 = strdup(tmp_pcs);      
  672.                             break;
  673.                             case 13:
  674.                             if (strlen(tmp_pcs) > 0)       
  675.                                 ((_ret_struct_a_res) + current_zone_count)->a_ip13 = strdup(tmp_pcs);      
  676.                             break;
  677.                             case 14:
  678.                             if (strlen(tmp_pcs) > 0)       
  679.                                 ((_ret_struct_a_res) + current_zone_count)->a_ip14 = strdup(tmp_pcs);      
  680.                             break;
  681.                             case 15:
  682.                             if (strlen(tmp_pcs) > 0)       
  683.                                 ((_ret_struct_a_res) + current_zone_count)->a_ip15 = strdup(tmp_pcs);      
  684.                             break;
  685.                             case 16:
  686.                             if (strlen(tmp_pcs) > 0)       
  687.                                 ((_ret_struct_a_res) + current_zone_count)->a_ip16 = strdup(tmp_pcs);      
  688.                             break;
  689.                             case 17:
  690.                             if (strlen(tmp_pcs) > 0)       
  691.                                 ((_ret_struct_a_res) + current_zone_count)->a_ip17 = strdup(tmp_pcs);      
  692.                             break;
  693.                             case 18:
  694.                             if (strlen(tmp_pcs) > 0)       
  695.                                 ((_ret_struct_a_res) + current_zone_count)->a_ip18 = strdup(tmp_pcs);      
  696.                             break;
  697.                         }
  698.                         printf("\tMainstruct for domain [%s], uid : [%d]\n",_ret_st_mainstruct_domain_zone[current_zone_count].domain_zone,((_ret_st_mainstruct_domain_zone) + current_zone_count)->uid);
  699.                         if (_ret_st_mainstruct_domain_zone[current_zone_count].domain_zone_a_ip_count > 20)
  700.                             _ret_st_mainstruct_domain_zone[current_zone_count].domain_zone_a_ip_count = 1;
  701.                         printf("\tA mainstruct zone a ip count [%d]\n",_ret_st_mainstruct_domain_zone[current_zone_count].domain_zone_a_ip_count);
  702.                     }
  703.                     if (strstr(fgets_res, "CNAMErecord ")) {
  704.                         tmp_pcs = strtok(fgets_res, " ");
  705.                         tmp_pcs = strtok(NULL, " ");
  706.                         cname_count++;
  707.                         _ret_st_mainstruct_domain_zone[current_zone_count].domain_zone_cname_count = cname_count;  
  708.                         switch(cname_count) {
  709.                             case 1:
  710.                             if (strlen(tmp_pcs) > 0)       
  711.                                 ((_ret_struct_cname) + current_zone_count)->cname1 = strdup(tmp_pcs);          
  712.                             break;
  713.                             case 2:
  714.                             if (strlen(tmp_pcs) > 0)       
  715.                                 ((_ret_struct_cname) + current_zone_count)->cname2 = strdup(tmp_pcs);          
  716.                             break;
  717.                             case 3:
  718.                             if (strlen(tmp_pcs) > 0)       
  719.                                 ((_ret_struct_cname) + current_zone_count)->cname3 = strdup(tmp_pcs);          
  720.                             break;
  721.                             case 4:
  722.                             if (strlen(tmp_pcs) > 0)       
  723.                                 ((_ret_struct_cname) + current_zone_count)->cname4 = strdup(tmp_pcs);          
  724.                             break;
  725.                             case 5:
  726.                             if (strlen(tmp_pcs) > 0)       
  727.                                 ((_ret_struct_cname) + current_zone_count)->cname5 = strdup(tmp_pcs);          
  728.                             break;
  729.                         }
  730.                         printf("\t [%d] cname count : [%d]\n",current_zone_count, _ret_st_mainstruct_domain_zone[current_zone_count].domain_zone_cname_count);
  731.                     }
  732.                     if (strstr(fgets_res, "MXrecord ")) {
  733.                         tmp_pcs = strtok(fgets_res, " ");
  734.                         tmp_pcs = strtok(NULL, " ");
  735.                         ((_ret_struct_mx) + current_zone_count)->mx_host = strdup(tmp_pcs);
  736.                         tmp_pcs = strtok(NULL, " ");
  737.                         _ret_st_mainstruct_domain_zone[current_zone_count].domain_zone_mx_count++;     
  738.                         mx_count++;
  739.                         printf("\t [%d] mx count : [%d]\n",current_zone_count, _ret_st_mainstruct_domain_zone[current_zone_count].domain_zone_mx_count);
  740.                     }
  741.                     if (strstr(fgets_res, "NSrecord ")) {
  742.                         tmp_pcs = strtok(fgets_res, " ");
  743.                         tmp_pcs = strtok(NULL, " ");
  744.                         tmp_ns = n_malloc(strlen(tmp_pcs));
  745.                         tmp_ns = tmp_pcs;
  746.                         tmp_pcs = strtok(NULL, " ");
  747.                         tmp_ns_ip = n_malloc(strlen(tmp_pcs));
  748.                         tmp_ns_ip = tmp_pcs;
  749.                         _ret_st_mainstruct_domain_zone[current_zone_count].domain_zone_ns_count++; 
  750.                         ns_count++;
  751.                         switch(ns_count) {
  752.                             case 1:
  753.                             ((_ret_struct_ns) + current_zone_count)->ns1 = strdup(tmp_ns);
  754.                             ((_ret_struct_ns) + current_zone_count)->ns1_ip = strdup(tmp_ns_ip);
  755.                             break;
  756.                             case 2:
  757.                             ((_ret_struct_ns) + current_zone_count)->ns2 = strdup(tmp_ns);
  758.                             ((_ret_struct_ns) + current_zone_count)->ns2_ip = strdup(tmp_ns_ip);
  759.                             break;
  760.                             case 3:
  761.                             ((_ret_struct_ns) + current_zone_count)->ns3 = strdup(tmp_ns);
  762.                             ((_ret_struct_ns) + current_zone_count)->ns3_ip = strdup(tmp_ns_ip);
  763.                             break;
  764.                             case 4:
  765.                             ((_ret_struct_ns) + current_zone_count)->ns4 = strdup(tmp_ns);
  766.                             ((_ret_struct_ns) + current_zone_count)->ns4_ip = strdup(tmp_ns_ip);
  767.                             break;
  768.                         }
  769.                         printf("\t [%d] ns count : [%d]\n",current_zone_count, _ret_st_mainstruct_domain_zone[current_zone_count].domain_zone_ns_count);
  770.                     }
  771.                 }
  772.             }
  773.         }
  774.     }
  775.    
  776.     return _ret_st_mainstruct_domain_zone;
  777. }
  778.  
  779. static int create_sock()
  780. {
  781.     int rldns_sock, true = 1;  
  782.    
  783.     if ((rldns_sock = socket(PF_INET, SOCK_DGRAM, 0)) == -1)
  784.         _msg_terminated_err(sock_fail);
  785.     if (setsockopt(rldns_sock, SOL_SOCKET, SO_REUSEADDR, &true, sizeof(int)) == -1)
  786.         _msg_err(fail_reuseaddr);
  787.    
  788.     return rldns_sock;
  789. }
  790.  
  791. static int nb_bind(int rldns_sock)
  792. {
  793.     int res;
  794.     char y_or_n;   
  795.    
  796.     if ((res = fcntl_nonblock(rldns_sock)) < 0) {
  797.         y_or_n = cont_or_no();
  798.         if ((y_or_n == 0x6e) || (y_or_n == 0x4e))
  799.             exit(0);
  800.     }
  801.     server_addr.sin_family = AF_INET;        
  802.         server_addr.sin_port = htons(rldns_port);    
  803.         server_addr.sin_addr.s_addr = INADDR_ANY;
  804.         bzero(&(server_addr.sin_zero), 8);
  805.     if (bind(rldns_sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) < 0)
  806.         _msg_terminated_err(fail_bind);
  807.    
  808.     return rldns_sock;
  809. }
  810.  
  811. static inline char *_switch_rand(int _rand, int zone_uid)
  812. {
  813.     tmp_ip = n_malloc(16);
  814.     switch(_rand) {
  815.         case 1:
  816.         tmp_ip = ((_ret_struct_a_res) + zone_uid)->a_ip1;  
  817.         break;
  818.         case 2:
  819.         tmp_ip = ((_ret_struct_a_res) + zone_uid)->a_ip2;  
  820.         break;
  821.         case 3:
  822.         tmp_ip = ((_ret_struct_a_res) + zone_uid)->a_ip3;  
  823.         break;
  824.         case 4:
  825.         tmp_ip = ((_ret_struct_a_res) + zone_uid)->a_ip4;  
  826.         break;
  827.         case 5:
  828.         tmp_ip = ((_ret_struct_a_res) + zone_uid)->a_ip5;  
  829.         break;
  830.         case 6:
  831.         tmp_ip = ((_ret_struct_a_res) + zone_uid)->a_ip6;  
  832.         break;
  833.         case 7:
  834.         tmp_ip = ((_ret_struct_a_res) + zone_uid)->a_ip7;  
  835.         break;
  836.         case 8:
  837.         tmp_ip = ((_ret_struct_a_res) + zone_uid)->a_ip8;  
  838.         break;
  839.         case 9:
  840.         tmp_ip = ((_ret_struct_a_res) + zone_uid)->a_ip9;  
  841.         break;
  842.         case 10:
  843.         tmp_ip = ((_ret_struct_a_res) + zone_uid)->a_ip10; 
  844.         break;
  845.         case 11:
  846.         tmp_ip = ((_ret_struct_a_res) + zone_uid)->a_ip11; 
  847.         break;
  848.         case 12:
  849.         tmp_ip = ((_ret_struct_a_res) + zone_uid)->a_ip12; 
  850.         break;
  851.         case 13:
  852.         tmp_ip = ((_ret_struct_a_res) + zone_uid)->a_ip13; 
  853.         break;
  854.         case 14:
  855.         tmp_ip = ((_ret_struct_a_res) + zone_uid)->a_ip14; 
  856.         break;
  857.         case 15:
  858.         tmp_ip = ((_ret_struct_a_res) + zone_uid)->a_ip15; 
  859.         break;
  860.         case 16:
  861.         tmp_ip = ((_ret_struct_a_res) + zone_uid)->a_ip16; 
  862.         break;
  863.         case 17:
  864.         tmp_ip = ((_ret_struct_a_res) + zone_uid)->a_ip17; 
  865.         break;
  866.         case 18:
  867.         tmp_ip = ((_ret_struct_a_res) + zone_uid)->a_ip18; 
  868.         break;
  869.     }  
  870.  
  871.     return tmp_ip;
  872. }
  873.  
  874. static inline char *_set_randomize_a_ip(int zone_uid)
  875. {
  876.     /**
  877.     _st_tmp_ip_fetcher *_struct_tmp_ip_fetcher;
  878.     **/
  879.     boolean valid;
  880.     int aray_rand[(_ret_st_mainstruct_domain_zone + zone_uid)->domain_zone_a_ip_count];
  881.     char *total_ip_sequence;
  882.     char *add_this;
  883.     char *domain;
  884.     int how_many = (_ret_st_mainstruct_domain_zone + zone_uid)->domain_zone_a_ip_count;
  885.     int found, _rand, i, try, range, amount = 0;
  886.  
  887.     try = 0;
  888.     /**_ret_st_mainstruct_domain_zone[i].domain_zone_a_ip_count **/
  889.     printf("\t[+] zone_uid [%d]\n", zone_uid);
  890.     domain = (_ret_st_mainstruct_domain_zone + zone_uid)->domain_zone;
  891.     printf("\t[+] domain to set random now : [%s]\n", domain);
  892.     range = _ret_st_mainstruct_domain_zone[zone_uid].domain_zone_a_ip_count + 1;
  893.     total_ip_sequence = n_malloc((16 * _ret_st_mainstruct_domain_zone[zone_uid].domain_zone_a_ip_count) + _ret_st_mainstruct_domain_zone[zone_uid].domain_zone_a_ip_count);
  894.     printf("\t[+] a name count [%d]\n", how_many);
  895.     for (i = 0; i <= how_many; i++) {
  896.         try++;
  897.         if (try > 140000)
  898.             break;
  899.         found = 1;
  900.         srand(_do_rdtsc());
  901.         _rand = rand() % range;
  902.         found = find_element(aray_rand, _rand);
  903.         if (found == 0) {
  904.             amount++;
  905.             aray_rand[i] = _rand;
  906.             add_this = _switch_rand(_rand, zone_uid);
  907.             /** validate ip octet **/
  908.             valid = validate_ipv4_octet(add_this);
  909.             if (valid == true) {
  910.                 strcat(total_ip_sequence, add_this);
  911.                 strcat(total_ip_sequence, "|");
  912.             }
  913.             if ((amount > how_many) || (amount == how_many))
  914.                 goto out;
  915.         }
  916.         else
  917.             i--;
  918.     }  
  919.     out:
  920.  
  921.     return total_ip_sequence;
  922. }  
  923.  
  924. static inline char *determine_dns_request_type(char *request)
  925. {
  926.     char *return_request_type;
  927.     int i, marker = 0;
  928.  
  929.     for (i = header_length; i <= MAX_A_LENGTH_ALLOWED; i++) {
  930.         if ((int)request[i] == 0) {
  931.             marker = 1;
  932.             break;
  933.         }          
  934.     }
  935.     return_request_type = n_malloc(2);
  936.     i+= 2;
  937.     if ((unsigned)(unsigned char)request[i] == 0xf)
  938.         return_request_type = "mx";
  939.     else if ((unsigned)(unsigned char)request[i] == 0x2)
  940.         return_request_type = "ns";
  941.     else if ((unsigned)(unsigned char)request[i] == 0x1)
  942.         return_request_type = "A";
  943.     else
  944.         return_request_type = "A";
  945.    
  946.     return return_request_type;
  947. }
  948.  
  949. static inline char *do_craft_dns_aname_response(char *total_res_ip, char *qid, char *a_name,  char *dns_response, int receive, int zone_uid)
  950. {
  951.     char *tot_res, *tmp_data;
  952.     int i, j, qid_ar, number_of_answer = 0;
  953.     char *piece = NULL;
  954.     char *octet = NULL;
  955.     typedef struct {
  956.         char *ip;  
  957.     }_tmp_data;
  958.     _tmp_data *__tmp_data;
  959.    
  960.     __tmp_data = malloc(18 *sizeof(__tmp_data));
  961.     if (a_resolver_type == 3) {
  962.         tot_res = n_malloc(16);
  963.         for (i = 0; i < 16; i++)
  964.             tot_res[i] = total_res_ip[i];
  965.     }      
  966.     else {
  967.         tot_res = n_malloc(strlen(total_res_ip));
  968.         for (i = 0; i < strlen(total_res_ip); i++)
  969.             tot_res[i] = total_res_ip[i];
  970.     }
  971.     number_of_answer = _count_answer_length(tot_res, "answer_count");
  972.     /** craft dns header **/
  973.     dns_response[0] = qid[0];  
  974.     dns_response[1] = qid[1];          
  975.     dns_response[2] = 0x81;
  976.     dns_response[3] = 0x80;
  977.     dns_response[4] = 0x0;
  978.     dns_response[5] = 0x1;
  979.     dns_response[6]= 0x0;
  980.     dns_response[7] = number_of_answer;
  981.     dns_response[8] = 0x0;
  982.     dns_response[9] = 0x0; /** NSCount : Authority Record Count **/
  983.     dns_response[10] = 0x0;
  984.     dns_response[11] = 0x0; /**ARCount : Additional Record Count: Specifies the number of resource records in the Additional section of the message.**/
  985.     i = 0;
  986.     qid_ar = (int)(qid[0]) +  (int)(qid[1]);
  987.     /**
  988.     typedef struct {
  989.     int _cur_receive;
  990.     char *_cur_dns_response;
  991.     char  *_cur_tot_res_ip;
  992.     int _cur_ans_count;
  993.     } _st_struct_current_dns_resp;
  994.     _ret_st_struct_current_dns_resp = malloc(255 *sizeof(_ret_st_struct_current_dns_resp));
  995.     since a name response is similar we will equip the same code just like a anwer
  996.     nah it's global struct
  997.     **/
  998.     (_ret_st_struct_current_dns_resp + qid_ar)->_cur_receive = receive;
  999.     (_ret_st_struct_current_dns_resp + qid_ar)->_cur_dns_response = dns_response;
  1000.     (_ret_st_struct_current_dns_resp + qid_ar)->_cur_tot_res_ip = total_res_ip;
  1001.     (_ret_st_struct_current_dns_resp + qid_ar)->_cur_ans_count = number_of_answer; 
  1002.     if (strstr(total_res_ip, "|")) {
  1003.         piece = strtok(total_res_ip, "|");
  1004.         while (piece != NULL) {
  1005.             (__tmp_data + i)->ip = piece;  
  1006.             piece = strtok(NULL, "|");
  1007.             i++;
  1008.         }
  1009.         for (j = 0;j < i; j++) {
  1010.             tmp_data = n_malloc(strlen((__tmp_data + j)->ip));
  1011.             tmp_data = (__tmp_data + j)->ip;
  1012.             /** craft answer section **/
  1013.             dns_response[receive++] = 0xc0;
  1014.             dns_response[receive++] = 0xc;   /** offset **/
  1015.             dns_response[receive++] = 0x0;
  1016.             dns_response[receive++] = 0x1;
  1017.             dns_response[receive++] = 0x0;
  1018.             dns_response[receive++] = 0x1;
  1019.             dns_response[receive++] = 0x0;
  1020.             dns_response[receive++] = 0x0;
  1021.             dns_response[receive++] = 0x0;
  1022.             dns_response[receive++] = 0x3c;
  1023.             dns_response[receive++] = 0x0;
  1024.             dns_response[receive++] = 0x4;
  1025.             octet = strtok(tmp_data, ".");
  1026.             while (octet != NULL) {
  1027.                 dns_response[receive++] = atoi(octet);
  1028.                 octet = strtok(NULL, ".");
  1029.             }
  1030.         }
  1031.     }
  1032.     else {
  1033.     /** processing single ip address **/
  1034.         dns_response[receive++] = 0xc0;
  1035.         dns_response[receive++] = 0xc;   /** offset **/
  1036.         dns_response[receive++] = 0x0;
  1037.         dns_response[receive++] = 0x1;
  1038.         dns_response[receive++] = 0x0;
  1039.         dns_response[receive++] = 0x1;
  1040.         dns_response[receive++] = 0x0;
  1041.         dns_response[receive++] = 0x0;
  1042.         dns_response[receive++] = 0x0;
  1043.         dns_response[receive++] = 0x3c;
  1044.         dns_response[receive++] = 0x0;
  1045.         dns_response[receive++] = 0x4;
  1046.         tmp_data = n_malloc(16);
  1047.         tmp_data = (_ret_struct_a_res + zone_uid)->a_ip1;
  1048.         octet = strtok(tmp_data, ".");
  1049.         while (octet != NULL) {
  1050.             dns_response[receive++] = atoi(octet);
  1051.             octet = strtok(NULL, "."); 
  1052.         }
  1053.     }
  1054.     (_ret_st_struct_current_dns_resp + qid_ar)->_cur_receive = receive;
  1055.    
  1056.     return  dns_response;  
  1057. }
  1058.  
  1059. static inline char *parse_dns_query_and_fetch_a_req(char *msg, char *mode)
  1060. {
  1061.     /**
  1062.     this function is made based on my own experiment
  1063.     sorry for any mistakes here
  1064.     **/
  1065.     int z, i, x, start_offset = header_length;
  1066.     int max_search_a = start_offset + max_domain_name_length;
  1067.     char aname[max_domain_name_length + 1];
  1068.     char *ret_a_name, *piece = NULL;
  1069.    
  1070.     if ((msg[start_offset] == 0x77) && (msg[start_offset + 1] == 0x77) && (msg[start_offset + 2] == 0x77))
  1071.         start_offset = 17;
  1072.     aname[max_domain_name_length + 1] = '\0';
  1073.     x = 0;
  1074.     for (i = start_offset; i <= max_search_a; i++) {
  1075.         if ((msg[i] == 0x00) || msg[i] == 0)
  1076.             break; 
  1077.         else if ((msg[i] == 0x1) || (msg[i] == 0x2) || (msg[i] == 0x3) ||  (msg[i] == 0x4) ||
  1078.         (msg[i] == 0x5) || (msg[i] == 0x6) || (msg[i] == 0x7) || (msg[i] == 0x8) ||
  1079.         (msg[i] == 0x9) || (msg[i] == 0xc)) {
  1080.             aname[x] = '.';
  1081.             x++;
  1082.         }
  1083.         else {
  1084.             aname[x] = (char)msg[i];
  1085.             x++;
  1086.         }  
  1087.     }
  1088.     ret_a_name = n_malloc(x);
  1089.     for (z = 0; z < x; z++) {
  1090.         if (sizeof(aname[z]) > 0)
  1091.             ret_a_name[z] = aname[z];
  1092.     }
  1093.     if (strcmp(mode, "a_name_without_tld") == 0) {
  1094.         piece = strtok(ret_a_name, ".");
  1095.         ret_a_name = n_malloc(strlen(piece));
  1096.         strcpy(ret_a_name, piece);
  1097.     }
  1098.    
  1099.     return (char *)ret_a_name;
  1100. }
  1101.  
  1102. static inline int _count_answer_length(char *total_res_ip, char *mode)
  1103. {
  1104.     /** count answer length **/
  1105.     char *piece = NULL;
  1106.     int leng_tot_ip = 0;
  1107.     int num_of_ans = 0;
  1108.     int ret = 0;
  1109.    
  1110.     piece = strtok(total_res_ip, "|");
  1111.     while (piece != NULL) {
  1112.         if (strcmp(mode, "length") == 0) {
  1113.             leng_tot_ip += strlen(piece);
  1114.             leng_tot_ip += 10;
  1115.             ret = leng_tot_ip;
  1116.         }
  1117.         else if (strcmp(mode, "answer_count") == 0)
  1118.             num_of_ans++;  
  1119.         piece = strtok(NULL, "|");
  1120.     }
  1121.     if (strcmp(mode, "length") == 0)
  1122.         ret = leng_tot_ip;
  1123.     else if (strcmp(mode, "answer_count") == 0)
  1124.         ret = num_of_ans;  
  1125.    
  1126.     return ret;
  1127. }
  1128.  
  1129. static inline char *_set_non_randomize_a_ip(int zone_uid)
  1130. {
  1131.     char *total_ip_sequence;
  1132.     char *domain;
  1133.     int i, how_many = (_ret_st_mainstruct_domain_zone + zone_uid)->domain_zone_a_ip_count;
  1134.     boolean valid;
  1135.    
  1136.     printf("\t[+] zone_uid [%d]\n", zone_uid);
  1137.     printf("\t[+] a ip count : [%d]\n",_ret_st_mainstruct_domain_zone[zone_uid].domain_zone_a_ip_count);
  1138.     total_ip_sequence = n_malloc((16 * _ret_st_mainstruct_domain_zone[zone_uid].domain_zone_a_ip_count) + _ret_st_mainstruct_domain_zone[zone_uid].domain_zone_a_ip_count);
  1139.     domain = (_ret_st_mainstruct_domain_zone + zone_uid)->domain_zone;
  1140.     printf("\t[+] domain to resolve now : [%s]\n", domain);
  1141.     printf("\t[+] how_many equ : [%d]\n", how_many);
  1142.     for (i = 0; i < how_many; i++) {
  1143.         tmp_ip = n_malloc(16);
  1144.         switch(i) {
  1145.             case 0:
  1146.             tmp_ip = (_ret_struct_a_res + zone_uid)->a_ip1;
  1147.             break;
  1148.             case 1:
  1149.             tmp_ip = (_ret_struct_a_res + zone_uid)->a_ip2;
  1150.             break;
  1151.             case 2:
  1152.             tmp_ip = (_ret_struct_a_res + zone_uid)->a_ip3;
  1153.             break;
  1154.             case 3:
  1155.             tmp_ip = (_ret_struct_a_res + zone_uid)->a_ip4;
  1156.             break;
  1157.             case 4:
  1158.             tmp_ip = (_ret_struct_a_res + zone_uid)->a_ip5;
  1159.             break;
  1160.             case 5:
  1161.             tmp_ip = (_ret_struct_a_res + zone_uid)->a_ip6;
  1162.             break;
  1163.             case 6:
  1164.             tmp_ip = (_ret_struct_a_res + zone_uid)->a_ip7;
  1165.             break;
  1166.             case 7:
  1167.             tmp_ip = (_ret_struct_a_res + zone_uid)->a_ip8;
  1168.             break;
  1169.             case 8:
  1170.             tmp_ip = (_ret_struct_a_res + zone_uid)->a_ip9;
  1171.             break;
  1172.             case 9:
  1173.             tmp_ip = (_ret_struct_a_res + zone_uid)->a_ip10;
  1174.             break;
  1175.             case 10:
  1176.             tmp_ip = (_ret_struct_a_res + zone_uid)->a_ip11;
  1177.             break;
  1178.             case 11:
  1179.             tmp_ip = (_ret_struct_a_res + zone_uid)->a_ip12;
  1180.             break;
  1181.             case 12:
  1182.             tmp_ip = (_ret_struct_a_res + zone_uid)->a_ip13;
  1183.             break;
  1184.             case 13:
  1185.             tmp_ip = (_ret_struct_a_res + zone_uid)->a_ip14;
  1186.             break;
  1187.             case 14:
  1188.             tmp_ip = (_ret_struct_a_res + zone_uid)->a_ip15;
  1189.             break;
  1190.             case 15:
  1191.             tmp_ip = (_ret_struct_a_res + zone_uid)->a_ip16;
  1192.             break;
  1193.             case 16:
  1194.             tmp_ip = (_ret_struct_a_res + zone_uid)->a_ip17;
  1195.             break;
  1196.             case 17:
  1197.             tmp_ip = (_ret_struct_a_res + zone_uid)->a_ip18;
  1198.             break;
  1199.         }
  1200.         if ((strstr(tmp_ip, ".")) && (strlen(tmp_ip) > 2)) {
  1201.             /** validate ip octet **/
  1202.             valid = validate_ipv4_octet(tmp_ip);
  1203.             if (valid == true) {
  1204.                 strcat(total_ip_sequence, tmp_ip);
  1205.                 strcat(total_ip_sequence, "|");
  1206.             }
  1207.         }
  1208.     }  
  1209.    
  1210.     return total_ip_sequence;
  1211. }
  1212.  
  1213. static inline char *craft_dns_aname_response(char *qid, char *dns_response, int receive)
  1214. {
  1215.     int i, a_counter = 0;
  1216.     char *total_res_ip, *a_name;
  1217.    
  1218.     a_name = n_malloc(max_domain_name_length);
  1219.     a_name = parse_dns_query_and_fetch_a_req(dns_response, "a_name");
  1220.     /** debugging purpose **/
  1221.     printf("\n\t[+] Client requesting a name req : [%s]\n", a_name);
  1222.     /** looping to search from appropriate structures for this a name req **/
  1223.     for (i = 1; i < zone_count; i++) {
  1224.         printf("\ncmp (_ret_st_mainstruct_domain_zone + i)->domain_zone : [%s] with a_name [%s]\n", (_ret_st_mainstruct_domain_zone + i)->domain_zone, a_name);
  1225.         if ((strcmp((_ret_st_mainstruct_domain_zone + i )->domain_zone, a_name)) == 0) {
  1226.             printf("\t[+] found match zone a name : [%s]\n",(_ret_st_mainstruct_domain_zone + i)->domain_zone);
  1227.             total_res_ip = n_malloc(((_ret_st_mainstruct_domain_zone[i].domain_zone_a_ip_count) * 16) + 1 + ((_ret_st_mainstruct_domain_zone[i].domain_zone_a_ip_count)));
  1228.             a_counter = (_ret_st_mainstruct_domain_zone[i].domain_zone_a_ip_count);
  1229.             if (a_resolver_type == 1)
  1230.                 total_res_ip = _set_non_randomize_a_ip((_ret_st_mainstruct_domain_zone + i)->uid);
  1231.             else if (a_resolver_type == 2) {
  1232.                 if (a_counter < 4)
  1233.                     total_res_ip = _set_non_randomize_a_ip((_ret_st_mainstruct_domain_zone + i)->uid);
  1234.                 else   
  1235.                     total_res_ip = _set_randomize_a_ip((_ret_st_mainstruct_domain_zone + i)->uid);
  1236.             }
  1237.             break;
  1238.         }  
  1239.     }
  1240.     dns_response = do_craft_dns_aname_response(total_res_ip, qid, a_name, dns_response, receive, (_ret_st_mainstruct_domain_zone + i)->uid);
  1241.    
  1242.     return dns_response;
  1243. }
  1244.  
  1245. static inline char *craft_dns_mx_response(char *qid, char *dns_response, int receive)
  1246. {
  1247.     char *a_name;
  1248.     int i;
  1249.    
  1250.     a_name = n_malloc(max_domain_name_length);
  1251.     a_name = parse_dns_query_and_fetch_a_req(dns_response, "a_name");
  1252.     printf("\n\trequested mx for a_name : [%s]\n", a_name);
  1253.     for (i = 1; i < zone_count; i++) {
  1254.         if ((strcmp((_ret_st_mainstruct_domain_zone + i)->domain_zone, a_name)) == 0) {
  1255.             printf("\t[+] found match zone a name : [%s]\n",(_ret_st_mainstruct_domain_zone + i)->domain_zone);
  1256.             dns_response = do_craft_dns_mx_response(qid, a_name, dns_response, receive, i);
  1257.         }
  1258.     }  
  1259.    
  1260.     return dns_response;
  1261. }
  1262.  
  1263. static inline char *craft_dns_ns_response(char *qid, char *dns_response, int receive)
  1264. {
  1265.     char *a_name;
  1266.     int i;
  1267.    
  1268.     a_name = n_malloc(max_domain_name_length);
  1269.     a_name = parse_dns_query_and_fetch_a_req(dns_response, "a_name");
  1270.     printf("\n\trequested mx for a_name : [%s]\n", a_name);
  1271.     for (i = 1; i < zone_count; i++) {
  1272.         if ((strcmp((_ret_st_mainstruct_domain_zone + i)->domain_zone, a_name)) == 0) {
  1273.             printf("\t[+] found match zone a name : [%s]\n",(_ret_st_mainstruct_domain_zone + i)->domain_zone);
  1274.             dns_response = do_craft_dns_ns_response(qid, a_name, dns_response, receive, i);
  1275.         }
  1276.     }
  1277.    
  1278.     return  dns_response;  
  1279. }
  1280.  
  1281. static inline char *do_craft_dns_mx_response(char *qid, char *a_name, char *dns_response, int receive, int zone_uid)
  1282. {
  1283.     int qid_ar;
  1284.    
  1285.     /** flags **/
  1286.     dns_response[0] = qid[0];  
  1287.     dns_response[1] = qid[1];   /** dns qid**/     
  1288.     /**forget to casting here **/
  1289.     qid_ar = (int)(qid[0]) + (int)(qid[1]);
  1290.     dns_response[2] = 0x85;
  1291.     dns_response[3] = 0x00;
  1292.     dns_response[4] = 0x0;
  1293.     dns_response[5] = 0x1; /** defined question num **/
  1294.     dns_response[6]= 0x0;
  1295.     dns_response[7] = 0x2; /** answer num **/
  1296.     dns_response[8] = 0x0;
  1297.     dns_response[9] = 0x00; /** NSCount : Authority Record Count **/
  1298.     dns_response[10] = 0x0;
  1299.     /***for additional record we will use only 1 **/
  1300.     dns_response[11] = 0x0; /**ARCount : Additional Record Count: Specifies the number of resource records in the Additional section of the message.**/
  1301.    
  1302.    
  1303.     /** craft answer section **/
  1304.     dns_response[receive++] = 0xc0;
  1305.     dns_response[receive++] = 0x0c; /** defined offset here **/
  1306.     dns_response[receive++] = 0x0;
  1307.     dns_response[receive++] = 0x0f; /** mx answer type**/
  1308.     dns_response[receive++] = 0x0;
  1309.     dns_response[receive++] = 0x01; /** class **/
  1310.     dns_response[receive++] = 0x0;
  1311.     dns_response[receive++] = 0x0;
  1312.     dns_response[receive++] = 0x01;
  1313.     dns_response[receive++] = 0x2c;  /** ttl  defined as 5 minutes **/
  1314.     dns_response[receive++] = 0x0;
  1315.     dns_response[receive++] = 0x09; /**data length : 9 (ringlayer)**/
  1316.     dns_response[receive++] = 0x0;
  1317.     dns_response[receive++] = 0x0a; /**preference = 10 **/
  1318.     /** mail **/
  1319.     dns_response[receive++] = 0x04;
  1320.     dns_response[receive++] = 0x6d;
  1321.     dns_response[receive++] = 0x61;
  1322.     dns_response[receive++] = 0x69;
  1323.     dns_response[receive++] = 0x6c;
  1324.     dns_response[receive++] = 0xc0;
  1325.     dns_response[receive++] = 0xc;
  1326.    
  1327.     /** craft second answer **/
  1328.     dns_response[receive++] = 0xc0;
  1329.     dns_response[receive++] = 0x0c; /** defined offset  **/
  1330.     dns_response[receive++] = 0x0;
  1331.     dns_response[receive++] = 0x0f; /** mx answer type**/
  1332.     dns_response[receive++] = 0x0;
  1333.     dns_response[receive++] = 0x01; /** class **/
  1334.     dns_response[receive++] = 0x0;
  1335.     dns_response[receive++] = 0x0;
  1336.     dns_response[receive++] = 0x01;
  1337.     dns_response[receive++] = 0x2c;  /** ttl  defined as 5 minutes **/
  1338.     dns_response[receive++] = 0x0;
  1339.     dns_response[receive++] = 0x9; /**data length : 9 (ringlayer)**/
  1340.     dns_response[receive++] = 0x0;
  1341.     dns_response[receive++] = 0xA; /**preference = 10 **/
  1342.     /** smtp
  1343.     73:6d:74:70
  1344.     **/
  1345.    
  1346.     dns_response[receive++] = 0x04;
  1347.     dns_response[receive++] = 0x73;
  1348.     dns_response[receive++] = 0x6d;
  1349.     dns_response[receive++] = 0x74;
  1350.     dns_response[receive++] = 0x70;
  1351.     dns_response[receive++] = 0xc0;
  1352.     dns_response[receive++] = 0xc;
  1353.    
  1354.     /***just like mx response before , similar code will be applied for ns response**/
  1355.     (_ret_st_struct_current_dns_resp + qid_ar)->_cur_receive = receive;
  1356.     (_ret_st_struct_current_dns_resp + qid_ar)->_cur_ans_count = 1;
  1357.  
  1358.     return  dns_response;  
  1359. }
  1360.  
  1361.  
  1362. static inline char *do_craft_dns_ns_response(char *qid, char *a_name, char *dns_response, int receive, int zone_uid)
  1363. {
  1364.     int qid_ar;
  1365.     /**qid_ar should be integer**/
  1366.    
  1367.     qid_ar = (int)(qid[0]) + (int)(qid[1]);
  1368.     /** flag **/
  1369.     dns_response[0] = qid[0];
  1370.     dns_response[1] = qid[1];
  1371.     dns_response[2] = 0x85;
  1372.     dns_response[3] = 0x00;
  1373.     dns_response[4] = 0x0;
  1374.     dns_response[5] = 0x01; /** question number **/
  1375.     dns_response[6] = 0x00;
  1376.     dns_response[7] = 0x02; /** number of answer = 2, test with 2 answer **/
  1377.     dns_response[8] = 0x0;
  1378.     dns_response[9] = 0x0; /** authority rrs **/
  1379.     dns_response[10] = 0x0;
  1380.     dns_response[11] = 0x0; /** additional records **/
  1381.    
  1382.     /** craft 1st answer
  1383.     receive is integer will contains next array number after question
  1384.     **/
  1385.    
  1386.     dns_response[receive++] = 0xc0;
  1387.     dns_response[receive++] = 0xc; /** offset **/
  1388.     dns_response[receive++] = 0x00;
  1389.     dns_response[receive++] = 0x02; /** answer type : ns **/
  1390.     dns_response[receive++] = 0x00;
  1391.     dns_response[receive++] = 0x01; /** class **/
  1392.     dns_response[receive++] = 0x00;
  1393.     dns_response[receive++] = 0x01;
  1394.     dns_response[receive++] = 0x51;
  1395.     dns_response[receive++] = 0x80; /** ttl = 1d **/
  1396.     dns_response[receive++] = 0x00;
  1397.     dns_response[receive++] = 0x06;
  1398.    
  1399.     dns_response[receive++] = 0x03;
  1400.     dns_response[receive++] = 0x6e; //n
  1401.     dns_response[receive++] = 0x73; //s
  1402.     dns_response[receive++]  = 0x31; //1
  1403.     dns_response[receive++] = 0xc0;
  1404.     dns_response[receive++] = 0xc;
  1405.  
  1406.     /** craft 2nd answer
  1407.     receive is integer will contains next array number after question
  1408.     **/
  1409.     dns_response[receive++] = 0xc0;
  1410.     dns_response[receive++] = 0xc;  /** offset **/
  1411.     dns_response[receive++] = 0x00;
  1412.     dns_response[receive++] = 0x02; /** answer type : ns **/
  1413.     dns_response[receive++] = 0x00;
  1414.     dns_response[receive++] = 0x01; /** class **/
  1415.     dns_response[receive++] = 0x00;
  1416.     dns_response[receive++] = 0x01;
  1417.     dns_response[receive++] = 0x51;
  1418.     dns_response[receive++] = 0x80; /** ttl = 1d **/
  1419.     dns_response[receive++] = 0x00;
  1420.     dns_response[receive++] = 0x06;
  1421.    
  1422.     dns_response[receive++] = 0x03;
  1423.     dns_response[receive++] = 0x6e; //n
  1424.     dns_response[receive++] = 0x73; //s
  1425.     dns_response[receive++]  = 0x32; //2
  1426.     dns_response[receive++] = 0xc0;
  1427.     dns_response[receive++] = 0xc;
  1428.  
  1429.     (_ret_st_struct_current_dns_resp + qid_ar)->_cur_receive = receive; /**fillin the struct to record last array number***/
  1430.     //(_ret_st_struct_current_dns_resp + qid_ar)->_cur_ans_count = 1;
  1431.    
  1432.     return dns_response;
  1433. }
  1434.  
  1435. static int rldns_main()
  1436. {
  1437.     int qid_ar, len, rldns_sock;
  1438.     char *dns_packet, *client_ip, *a_name, *a_name_without_tld, *dns_response_type, *qid;
  1439.     char buf_dns_packet[PACKET_SIZE];
  1440.     int rcv_flag = 0;
  1441.     int receive;
  1442.    
  1443.     _ret_st_struct_current_dns_resp = malloc(77 *sizeof(_ret_st_struct_current_dns_resp));
  1444.     buf_dns_packet[PACKET_SIZE + 1] = '\0';
  1445.     dns_packet = n_malloc(PACKET_SIZE);
  1446.     epoll_fd = epoll_create(10);
  1447.     rldns_sock = create_sock();
  1448.     rldns_sock = nb_bind(rldns_sock);
  1449.     len = sizeof(client_addr);
  1450.     while (1) {
  1451.         receive = recvfrom(rldns_sock, dns_packet, PACKET_SIZE, rcv_flag, (struct sockaddr *) &client_addr, (socklen_t * __restrict__)&len);
  1452.         if (receive < 0) {continue;}
  1453.             client_ip = n_malloc(16);
  1454.             client_ip = inet_ntoa(client_addr.sin_addr);
  1455.             printf("\n=========================dns operation================================\n\n");
  1456.             printf("\t[+] got new client from [%s]\n", client_ip);
  1457.             a_name = n_malloc(max_domain_name_length);
  1458.             a_name = parse_dns_query_and_fetch_a_req(dns_packet, "a_name");
  1459.             a_name = n_malloc(max_domain_name_length);
  1460.             a_name_without_tld = parse_dns_query_and_fetch_a_req(dns_packet, "a_name_without_tld");
  1461.             qid = n_malloc(2);
  1462.             qid = get_current_dns_qid(dns_packet);
  1463.             printf("\t[+] got current qid : 0x%x 0x%x\n", (unsigned)(unsigned char)qid[0],(unsigned)(unsigned char)qid[1]);
  1464.             dns_response_type = determine_dns_request_type(dns_packet);
  1465.             printf("\t[+] got ret dns req type : [%s]\n", dns_response_type);
  1466.             qid_ar = (int)(qid[0]) + (int)(qid[1]);
  1467.             if (strcmp(dns_response_type, "A") == 0)  {
  1468.                 dns_packet = craft_dns_aname_response(qid, dns_packet, receive);
  1469.                 receive = (_ret_st_struct_current_dns_resp + qid_ar)->_cur_receive;
  1470.             }              
  1471.             else if (strcmp(dns_response_type, "mx") == 0) {
  1472.                 dns_packet = craft_dns_mx_response(qid, dns_packet, receive);
  1473.                 receive = (_ret_st_struct_current_dns_resp + qid_ar)->_cur_receive;
  1474.             }
  1475.             else if (strcmp(dns_response_type, "ns") == 0)  {
  1476.                 dns_packet = craft_dns_ns_response(qid, dns_packet, receive);
  1477.                 receive = (_ret_st_struct_current_dns_resp + qid_ar)->_cur_receive;
  1478.             }
  1479.             else {
  1480.                 dns_packet = craft_dns_aname_response(qid, dns_packet, receive);   
  1481.                 receive = (_ret_st_struct_current_dns_resp + qid_ar)->_cur_receive;
  1482.             }
  1483.             /**
  1484.             for (i = 0; i < 513; i++) {
  1485.                 printf("hex packet : [%d] : [0x%x] \n", i, (unsigned)(unsigned char)dns_response[i]);
  1486.             }
  1487.             **/
  1488.             sendto(rldns_sock, dns_packet, receive, rcv_flag,(struct sockaddr *)&client_addr, len);
  1489.     }
  1490.  
  1491.     return 0;
  1492. }
  1493.  
  1494. int main()
  1495. {
  1496.     _check_config();
  1497.     _cfg = _init_read_parse_config();
  1498.     _read_zone_file(); 
  1499.     rldns_port = _cfg[0].port;
  1500.     rldns_main();
  1501.     return 0;
  1502. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement