Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * rldns - Ringlayer DNS Based Load Balancer Server 1.0.0
- *
- * Developed by Antonius (Sw0rdm4n)
- *
- * Official Website : www.ringlayer.net
- *
- * www.ringlayer.com - www.cr0security.com - www.jasaplus.com - www.komputekno.org - c0debreaker.com
- * thanks www.indonesianbacktrack.or.id
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- */
- #include <sys/stat.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <unistd.h>
- #include <errno.h>
- #include <pwd.h>
- #include <pthread.h>
- #include <time.h>
- #include <ctype.h>
- #include <fcntl.h>
- #include <time.h>
- #include <sys/mman.h>
- #include <sys/wait.h>
- #include <sys/stat.h>
- #include <sys/types.h>
- #include <sys/epoll.h>
- #include <sys/syslog.h>
- #include <sys/socket.h>
- #include <sys/prctl.h>
- #include <netinet/in.h>
- #include <netdb.h>
- #include <arpa/inet.h>
- #include <dirent.h>
- #include <limits.h>
- #define CONFIG "rldns.conf"
- #define PACKET_SIZE 512
- #define MAX_ZONE_FILE_LINE_LENGTH 256
- #define MAX_A_LENGTH_ALLOWED 62
- #define MAX_ANSWER_LENGTH_ALLOWED ((16 + 12) * 18)
- #define header_length 13
- /**
- rfc reference
- - http://tools.ietf.org/html/rfc1035
- for a resolver
- this dns software has 2 types method to resolve a name request
- - a_resolver_type 1, if more than 1 ip to resolve, this will do a dns based load balancing without randomizing ip addresses
- - 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)
- **/
- /** uncomment this for a resolver type 1
- static const int a_resolver_type = 1;
- **/
- static const int a_resolver_type = 2;
- typedef int boolean;
- static const boolean true = 1;
- static const boolean false = 0;
- /** static variables start **/
- //static const char *user = "rldns";
- static const int max_buf = 255;
- static int epoll_fd;
- static const uint8_t BACKLOG = 4;
- static const int max_domain_name_length = 253;
- static int already_prctl = 0;
- /** rldns default settings **/
- int tsc = 1;
- int rldns_port;
- int worker;
- int thread;
- char *version;
- char *zones_path;
- /** eof static variables **/
- /** dns packet **/
- int zone_count = 0;
- /** eof dns packet **/
- /** vars **/
- char *fail_nonblock = "\n | rldns : Fatal Warning ! failed to create a non blocking socket for handling multiple connection ! |\n";
- char *no_config = "\n | rldns : Fatal Error ! rldns.conf not found ! exit ! |\n";
- char *sock_fail = "\n | rldns : Fatal Error ! failed to create socket ! exit ! |\n";
- char *no_user = "\n | rldns : Fatal Error ! no rldns user ! please adduser rldns first ! exit ! |\n";
- char *fail_reuseaddr = "\n | rldns : Warning ! failed to setsockopt for reuseaddr ! |\n";
- char *fail_bind = "\n | rldns : Fatal Error ! failed to bind socket ! |\n";
- char *no_zones = "\n | rldns : Fatal Error ! no zone files found, please add domain zone file(s) ! |\n";
- char *no_zonepath = "\n | rldns : Fatal Error ! incorrect zone path , please check your zone setting at cbdns.conf ! |\n";
- char *failed_prctl = "\n | rldns : Warning ! prctl failed to control cr4 ! |\n";
- /** eof vars **/
- /**
- tmp data(s)
- **/
- char *tmp_ip;
- int tmp_domain_uid;
- /** eof tmp datas **/
- /** structs **/
- struct passwd *p;
- struct epoll_event _epoll_event;
- struct epoll_event *_epoll_events;
- struct sockaddr_in server_addr;
- struct sockaddr_in client_addr;
- typedef struct {
- int _cur_receive;
- char *_cur_dns_response;
- char *_cur_tot_res_ip;
- int _cur_ans_count;
- } _st_struct_current_dns_resp;
- typedef struct {
- int port;
- int worker;
- int thread;
- char *version;
- char *zones;
- }_st_configurations;
- typedef struct {
- int uid;
- char *a_ip1;
- char *a_ip2;
- char *a_ip3;
- char *a_ip4;
- char *a_ip5;
- char *a_ip6;
- char *a_ip7;
- char *a_ip8;
- char *a_ip9;
- char *a_ip10;
- char *a_ip11;
- char *a_ip12;
- char *a_ip13;
- char *a_ip14;
- char *a_ip15;
- char *a_ip16;
- char *a_ip17;
- char *a_ip18;
- }_st_a_res;
- typedef struct {
- int uid;
- char *cname1;
- char *cname2;
- char *cname3;
- char *cname4;
- char *cname5;
- } _st_cname;
- typedef struct {
- int uid;
- char *mx_host;
- } _st_mx;
- typedef struct {
- int uid;
- char *ns1;
- char *ns1_ip;
- char *ns2;
- char *ns2_ip;
- char *ns3;
- char *ns3_ip;
- char *ns4;
- char *ns4_ip;
- } _st_ns;
- typedef struct {
- int uid;
- char *zone_aname;
- } _st_zone;
- typedef struct {
- int uid;
- char *domain_zone;
- int domain_zone_a_ip_count;
- int domain_zone_cname_count;
- int domain_zone_mx_count;
- int domain_zone_ns_count;
- } _st_mainstruct_domain_zone;
- _st_configurations *_cfg;
- _st_mainstruct_domain_zone *_ret_st_mainstruct_domain_zone;
- _st_zone *_ret_struct_dns_zone;
- _st_a_res *_ret_struct_a_res;
- _st_cname *_ret_struct_cname;
- _st_mx *_ret_struct_mx;
- _st_ns *_ret_struct_ns;
- _st_struct_current_dns_resp *_ret_st_struct_current_dns_resp;
- static inline char *do_craft_dns_ns_response(char *qid, char *a_name, char *dns_response, int receive, int zone_uid);
- static inline char *do_craft_dns_mx_response(char *qid, char *a_name, char *dns_response, int receive, int zone_uid);
- static inline boolean validate_ipv4_octet(char *ipaddr);
- static inline char *_set_randomize_a_ip(int zone_uid);
- static inline char *_last_replace(char *original_str, char *str_to_replace, char *replacer_str);
- static inline char *get_current_dns_qid(char *msg);
- static inline char *n_malloc(ssize_t size);
- static inline char *craft_dns_aname_response(char *qid, char *dns_response, int receive);
- static inline char *craft_dns_mx_response(char *qid, char *dns_response, int receive);
- static inline char *craft_dns_ns_response(char *qid, char *dns_response, int receive);
- static inline char *determine_dns_request_type(char *request);
- static inline char *rtrim(char *str);
- static inline char *ltrim(char *str);
- static inline char *trim(char *str);
- static inline char *parse_dns_query_and_fetch_a_req(char *msg, char *mode);
- 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);
- static inline int _count_answer_length(char *total_res_ip, char *mode);
- static inline int _do_rdtsc();
- static inline boolean validate_ipv4_octet(char *ipaddr)
- {
- int j, octet_found = 0;
- boolean valid = false;
- for (j = 0; j < (strlen(ipaddr)); j++) {
- if (tmp_ip[j] == 0x2e)
- octet_found++;
- }
- if (octet_found > 2)
- valid = true;
- return valid;
- }
- inline long get_file_length_or_line_count(char *filename, char *mode)
- {
- FILE *fd;
- int filename_len, len, retval, tot;
- char str[256] = "\0";
- char *pcs = "\0";
- filename_len = strlen(filename);
- tot = filename_len + 7;
- char cmd[tot];
- if (strstr(mode, "lengt"))
- snprintf(cmd,tot,"wc -c %s",filename);
- else
- snprintf(cmd,tot,"wc -l %s",filename);
- fd = popen(cmd,"r");
- while(fgets(str, max_buf, fd)!=NULL) {
- len = strlen(str);
- if ((len > 1)) {
- pcs = strtok(str, " ");
- retval = atoi(pcs);
- }
- }
- pclose(fd);
- return (retval);
- }
- static inline char *get_current_dns_qid(char *msg)
- {
- char *qid;
- qid = n_malloc(2);
- qid[0] = msg[0];
- qid[1] = msg[1];
- return qid;
- }
- static inline int find_element(int seekat[], int num)
- {
- int i, found = 0;
- for (i = 0; i < 20; i++) {
- if (seekat[i] == num) {
- found = 1;
- break;
- }
- }
- return found;
- }
- static inline char *_last_replace(char *original_str, char *str_to_replace, char *replacer_str)
- {
- char *clean_str;
- int i, z, half_done, len_original_str, len_str_to_replace, len_replacer_str, len_clean_str;
- len_original_str = strlen(original_str);
- len_str_to_replace = strlen(str_to_replace);
- i = 0;
- if (replacer_str == NULL) {
- len_clean_str = len_original_str - len_str_to_replace;
- clean_str = n_malloc(len_clean_str);
- for (i = 0; i < len_clean_str; i++)
- clean_str[i] = original_str[i];
- }
- else {
- len_replacer_str = strlen(replacer_str);
- half_done = len_original_str - len_str_to_replace;
- len_clean_str = (len_original_str - len_str_to_replace) + len_replacer_str;
- clean_str = n_malloc(len_clean_str);
- for (i = 0; i < half_done; i++)
- clean_str[i] = original_str[i];
- z = 0;
- for (i = half_done; i < len_clean_str;i++) {
- clean_str[i] = replacer_str[z];
- z++;
- }
- }
- return clean_str;
- if (clean_str)
- free(clean_str);
- }
- static int cont_or_no()
- {
- char y_or_n;
- 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)");
- y_or_n = getchar();
- return y_or_n;
- }
- int daemonize()
- {
- pid_t worker_pid;
- worker_pid = fork();
- if (worker_pid != 0)
- exit(0);
- return 0;
- }
- static inline char *n_malloc(ssize_t size)
- {
- char *retme;
- retme = malloc((size + 1) * sizeof(char));
- memset(retme, '\0', size + 1);
- return (retme);
- }
- static inline void _msg_err(char *msg)
- {
- fprintf(stdout, "%s", msg);
- syslog(LOG_DAEMON, "%s", msg);
- /** ignore warning rldns will keep continue **/
- }
- static inline void _msg_terminated_err(char *msg)
- {
- fprintf(stdout, "%s", msg);
- syslog(LOG_DAEMON, "%s", msg);
- exit(0);
- }
- static inline void stop_crash()
- {
- pid_t pid;
- int status;
- while ((pid = waitpid(-1, &status, WNOHANG)) > 0)
- return;
- }
- /**
- int static _init_set_cred()
- {
- int rldns_uid, rldns_gid;
- if ((p = getpwnam(user)) == NULL)
- _msg_terminated_err(no_user);
- rldns_uid = (int) (p->pw_uid);
- rldns_gid = (int) (p->pw_gid);
- setuid(rldns_uid);
- setgid(rldns_gid);
- seteuid(rldns_uid);
- return 0;
- }
- **/
- static _st_configurations *_init_read_parse_config()
- {
- _st_configurations *rldns_config;
- char *result = NULL;
- FILE *config;
- int total_line, len, cur_line = 0;
- char str[256] = "\0";
- int struct_offset, offset_port, offset_worker, offset_thread, offset_version, offset_zones = 0;
- int total_config_length = 0;
- struct_offset = 0;
- rldns_config = malloc(1 * sizeof(_st_configurations));
- fprintf(stdout, "\t[+] reading rldns configuration file\n");
- offset_port = 0;
- offset_worker = 0;
- offset_thread = 0;
- offset_version = 0;
- result = n_malloc(256);
- config = fopen(CONFIG, "r");
- if (!config)
- _msg_terminated_err(no_config);
- total_line = get_file_length_or_line_count(CONFIG, "line");
- total_config_length = get_file_length_or_line_count(CONFIG, "length");
- while((fgets(str, max_buf, config) != NULL) && (cur_line <= total_line)) {
- len = strlen(str);
- if (len > 1)
- if (!strstr(str, ";")) {
- result = strtok(str, " ");
- while(result != NULL) {
- result = trim(result);
- /** fillin the configuration struct **/
- if (offset_version == 1) {
- (rldns_config + struct_offset)->version = n_malloc(strlen(result));
- (rldns_config + struct_offset)->version = trim(result);
- version = n_malloc(strlen((rldns_config + struct_offset)->version));
- strcpy(version, (rldns_config + struct_offset)->version);
- fprintf(stdout, "\t[+] rldns version : %s\n", (rldns_config + struct_offset)->version);
- }
- if (offset_zones == 1) {
- (rldns_config + struct_offset)->zones = n_malloc(strlen(result));
- (rldns_config + struct_offset)->zones = trim(result);
- zones_path = n_malloc(strlen((rldns_config + struct_offset)->zones));
- strcpy(zones_path, (rldns_config + struct_offset)->zones);
- fprintf(stdout, "\t[+] rldns zone(s) : %s\n",(rldns_config + struct_offset)->zones);
- }
- if (offset_port == 1) {
- (rldns_config + struct_offset)->port = atoi(result);
- rldns_port = (rldns_config + struct_offset)->port;
- fprintf(stdout, "\t[+] rldns port : %d\n", (rldns_config + struct_offset)->port);
- }
- if (offset_worker == 1) {
- (rldns_config + struct_offset)->worker = atoi(result);
- worker = (rldns_config + struct_offset)->worker;
- fprintf(stdout, "\t[+] rldns worker(s) : %d\n", (rldns_config + struct_offset)->worker);
- }
- if (offset_thread == 1) {
- (rldns_config + struct_offset)->thread = atoi(result);
- thread = (rldns_config + struct_offset)->thread;
- fprintf(stdout, "\t[+] rldns thread(s) : %d\n", (rldns_config + struct_offset)->thread);
- }
- if (strcmp(result, "port") == 0)
- offset_port = 1;
- else
- offset_port = 0;
- if (strcmp(result, "worker") == 0)
- offset_worker = 1;
- else
- offset_worker = 0;
- if (strcmp(result, "thread") == 0)
- offset_thread = 1;
- else
- offset_thread = 0;
- if (strcmp(result, "version") == 0)
- offset_version = 1;
- else
- offset_version = 0;
- if (strcmp(result, "zones") == 0)
- offset_zones = 1;
- else
- offset_zones = 0;
- result = strtok(NULL, " ");
- }
- }
- cur_line++;
- }
- fclose(config);
- return rldns_config;
- }
- static void _check_config()
- {
- struct stat buf;
- if (stat("rldns.conf", &buf) == 0)
- printf("\t[+] found configuration file : rldns.conf \n");
- else
- _msg_terminated_err(no_config);
- }
- /** string trimming functions taken from http://en.wikipedia.org/wiki/Trimming_%28computer_programming%29#C.2FC.2B.2B **/
- static inline char *rtrim(char *str)
- {
- int n = 0;
- n = strlen(str);
- while (n > 0 && isspace((unsigned char)str[n - 1]))
- n--;
- str[n] = '\0';
- return (str);
- }
- static inline char *ltrim(char *str)
- {
- int n = 0;
- while (str[n] != '\0' && isspace((unsigned char)str[n]))
- n++;
- memmove(str, str + n, strlen(str) - n + 1);
- return (str);
- }
- static inline char *trim(char *str)
- {
- str = rtrim(str);
- str = ltrim(str);
- return (str);
- }
- /**
- prctl and rdtsc reference taken from :
- http://man7.org/linux/man-pages/man2/prctl.2.html
- http://www.mcs.anl.gov/~kazutomo/rdtsc.html
- Trying to get timestamp for seeding srand later, cr4 register control must be enabled
- **/
- static inline int _do_rdtsc()
- {
- if (already_prctl == 0) {
- if ((prctl(PR_SET_TSC, PR_TSC_ENABLE)) == -1) {
- _msg_err(failed_prctl);
- }
- already_prctl = 1;
- }
- __asm__ __volatile__ ("rdtsc");
- }
- static int fcntl_nonblock(int sock_fd)
- {
- if (fcntl(sock_fd, F_SETFL, fcntl(sock_fd, F_GETFD, 0) | O_NONBLOCK) == -1) {
- _msg_err(fail_nonblock);
- return -1;
- }
- return 0;
- }
- /**
- epoll usage reference from : https://banu.com/blog/2/how-to-use-epoll-a-complete-example-in-c
- **/
- static _st_mainstruct_domain_zone *_read_zone_file()
- {
- DIR *dir_fd;
- char *zone_file_name, *full_path, *fgets_res = NULL;
- struct dirent *zone_list;
- FILE *zone_fd;
- int a_count, cname_count, mx_count, ns_count, current_zone_count;
- char *tmp_pcs, *tmp_ns, *tmp_ns_ip;
- _ret_st_mainstruct_domain_zone = malloc(200 * sizeof(_ret_st_mainstruct_domain_zone));
- _ret_struct_dns_zone = malloc(200 * sizeof(_st_zone));
- _ret_struct_a_res = malloc(200 * sizeof(_st_a_res));
- _ret_struct_cname = malloc(200 * sizeof(_st_cname));
- _ret_struct_mx = malloc(200 * sizeof(_st_mx));
- _ret_struct_ns = malloc(200 * sizeof(_st_ns));
- strtok(zones_path, "/");
- dir_fd = opendir(zones_path);
- if (dir_fd == NULL)
- _msg_terminated_err(no_zonepath);
- current_zone_count = 0;
- while ((zone_list = readdir(dir_fd))) {
- if (strstr(zone_list->d_name, ".zone")) {
- full_path = n_malloc((strlen(zone_list->d_name)) + strlen(zones_path) + 1);
- strncat(full_path, trim(zones_path), strlen(zones_path));
- strncat(full_path, "/", 1);
- strncat(full_path, trim(zone_list->d_name), strlen(zone_list->d_name));
- zone_file_name = n_malloc(strlen(zone_list->d_name));
- zone_file_name = zone_list->d_name;
- zone_fd = fopen(full_path, "r");
- if (zone_fd != NULL) {
- fgets_res = n_malloc(MAX_ZONE_FILE_LINE_LENGTH);
- while ((fgets(fgets_res, MAX_ZONE_FILE_LINE_LENGTH, zone_fd)) != NULL) {
- trim(fgets_res);
- /** a records **/
- if (strstr(fgets_res, "masterzone ")) {
- a_count = 0;
- cname_count = 0;
- mx_count = 0;
- ns_count = 0;
- current_zone_count = zone_count;
- tmp_pcs = strtok(fgets_res, " ");
- tmp_pcs = strtok(NULL, " ");
- ((_ret_st_mainstruct_domain_zone) + current_zone_count)->domain_zone = strdup(tmp_pcs);
- ((_ret_st_mainstruct_domain_zone) + current_zone_count)->uid = zone_count;
- ((_ret_struct_dns_zone) + current_zone_count)->zone_aname = strdup(tmp_pcs);
- ((_ret_struct_dns_zone) + current_zone_count)->uid = zone_count;
- ((_ret_struct_a_res) + current_zone_count)->uid = zone_count;
- tmp_domain_uid = current_zone_count;
- ((_ret_struct_cname) + zone_count)->uid = zone_count;
- ((_ret_struct_mx) + zone_count)->uid = zone_count;
- ((_ret_struct_ns) + zone_count)->uid = zone_count;
- printf("=========================================================\n");
- printf("\tmainstruct dom [%s]\n",((_ret_st_mainstruct_domain_zone) + zone_count)->domain_zone);
- zone_count++;
- }
- if (strstr(fgets_res, "Arecord ")) {
- tmp_pcs = strtok(fgets_res, " ");
- tmp_pcs = strtok(NULL, " ");
- _ret_st_mainstruct_domain_zone[current_zone_count].domain_zone_a_ip_count++;
- a_count++;
- switch(a_count) {
- case 1:
- if (strlen(tmp_pcs) > 0)
- ((_ret_struct_a_res) + current_zone_count)->a_ip1 = strdup(tmp_pcs);
- break;
- case 2:
- if (strlen(tmp_pcs) > 0)
- ((_ret_struct_a_res) + current_zone_count)->a_ip2 = strdup(tmp_pcs);
- break;
- case 3:
- if (strlen(tmp_pcs) > 0)
- ((_ret_struct_a_res) + current_zone_count)->a_ip3 = strdup(tmp_pcs);
- break;
- case 4:
- if (strlen(tmp_pcs) > 0)
- ((_ret_struct_a_res) + current_zone_count)->a_ip4 = strdup(tmp_pcs);
- break;
- case 5:
- if (strlen(tmp_pcs) > 0)
- ((_ret_struct_a_res) + current_zone_count)->a_ip5 = strdup(tmp_pcs);
- break;
- case 6:
- if (strlen(tmp_pcs) > 0)
- ((_ret_struct_a_res) + current_zone_count)->a_ip6 = strdup(tmp_pcs);
- break;
- case 7:
- if (strlen(tmp_pcs) > 0)
- ((_ret_struct_a_res) + current_zone_count)->a_ip7 = strdup(tmp_pcs);
- break;
- case 8:
- if (strlen(tmp_pcs) > 0)
- ((_ret_struct_a_res) + current_zone_count)->a_ip8 = strdup(tmp_pcs);
- break;
- case 9:
- if (strlen(tmp_pcs) > 0)
- ((_ret_struct_a_res) + current_zone_count)->a_ip9 = strdup(tmp_pcs);
- break;
- case 10:
- if (strlen(tmp_pcs) > 0)
- ((_ret_struct_a_res) + current_zone_count)->a_ip10 = strdup(tmp_pcs);
- break;
- case 11:
- if (strlen(tmp_pcs) > 0)
- ((_ret_struct_a_res) + current_zone_count)->a_ip11 = strdup(tmp_pcs);
- break;
- case 12:
- if (strlen(tmp_pcs) > 0)
- ((_ret_struct_a_res) + current_zone_count)->a_ip12 = strdup(tmp_pcs);
- break;
- case 13:
- if (strlen(tmp_pcs) > 0)
- ((_ret_struct_a_res) + current_zone_count)->a_ip13 = strdup(tmp_pcs);
- break;
- case 14:
- if (strlen(tmp_pcs) > 0)
- ((_ret_struct_a_res) + current_zone_count)->a_ip14 = strdup(tmp_pcs);
- break;
- case 15:
- if (strlen(tmp_pcs) > 0)
- ((_ret_struct_a_res) + current_zone_count)->a_ip15 = strdup(tmp_pcs);
- break;
- case 16:
- if (strlen(tmp_pcs) > 0)
- ((_ret_struct_a_res) + current_zone_count)->a_ip16 = strdup(tmp_pcs);
- break;
- case 17:
- if (strlen(tmp_pcs) > 0)
- ((_ret_struct_a_res) + current_zone_count)->a_ip17 = strdup(tmp_pcs);
- break;
- case 18:
- if (strlen(tmp_pcs) > 0)
- ((_ret_struct_a_res) + current_zone_count)->a_ip18 = strdup(tmp_pcs);
- break;
- }
- 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);
- if (_ret_st_mainstruct_domain_zone[current_zone_count].domain_zone_a_ip_count > 20)
- _ret_st_mainstruct_domain_zone[current_zone_count].domain_zone_a_ip_count = 1;
- printf("\tA mainstruct zone a ip count [%d]\n",_ret_st_mainstruct_domain_zone[current_zone_count].domain_zone_a_ip_count);
- }
- if (strstr(fgets_res, "CNAMErecord ")) {
- tmp_pcs = strtok(fgets_res, " ");
- tmp_pcs = strtok(NULL, " ");
- cname_count++;
- _ret_st_mainstruct_domain_zone[current_zone_count].domain_zone_cname_count = cname_count;
- switch(cname_count) {
- case 1:
- if (strlen(tmp_pcs) > 0)
- ((_ret_struct_cname) + current_zone_count)->cname1 = strdup(tmp_pcs);
- break;
- case 2:
- if (strlen(tmp_pcs) > 0)
- ((_ret_struct_cname) + current_zone_count)->cname2 = strdup(tmp_pcs);
- break;
- case 3:
- if (strlen(tmp_pcs) > 0)
- ((_ret_struct_cname) + current_zone_count)->cname3 = strdup(tmp_pcs);
- break;
- case 4:
- if (strlen(tmp_pcs) > 0)
- ((_ret_struct_cname) + current_zone_count)->cname4 = strdup(tmp_pcs);
- break;
- case 5:
- if (strlen(tmp_pcs) > 0)
- ((_ret_struct_cname) + current_zone_count)->cname5 = strdup(tmp_pcs);
- break;
- }
- printf("\t [%d] cname count : [%d]\n",current_zone_count, _ret_st_mainstruct_domain_zone[current_zone_count].domain_zone_cname_count);
- }
- if (strstr(fgets_res, "MXrecord ")) {
- tmp_pcs = strtok(fgets_res, " ");
- tmp_pcs = strtok(NULL, " ");
- ((_ret_struct_mx) + current_zone_count)->mx_host = strdup(tmp_pcs);
- tmp_pcs = strtok(NULL, " ");
- _ret_st_mainstruct_domain_zone[current_zone_count].domain_zone_mx_count++;
- mx_count++;
- printf("\t [%d] mx count : [%d]\n",current_zone_count, _ret_st_mainstruct_domain_zone[current_zone_count].domain_zone_mx_count);
- }
- if (strstr(fgets_res, "NSrecord ")) {
- tmp_pcs = strtok(fgets_res, " ");
- tmp_pcs = strtok(NULL, " ");
- tmp_ns = n_malloc(strlen(tmp_pcs));
- tmp_ns = tmp_pcs;
- tmp_pcs = strtok(NULL, " ");
- tmp_ns_ip = n_malloc(strlen(tmp_pcs));
- tmp_ns_ip = tmp_pcs;
- _ret_st_mainstruct_domain_zone[current_zone_count].domain_zone_ns_count++;
- ns_count++;
- switch(ns_count) {
- case 1:
- ((_ret_struct_ns) + current_zone_count)->ns1 = strdup(tmp_ns);
- ((_ret_struct_ns) + current_zone_count)->ns1_ip = strdup(tmp_ns_ip);
- break;
- case 2:
- ((_ret_struct_ns) + current_zone_count)->ns2 = strdup(tmp_ns);
- ((_ret_struct_ns) + current_zone_count)->ns2_ip = strdup(tmp_ns_ip);
- break;
- case 3:
- ((_ret_struct_ns) + current_zone_count)->ns3 = strdup(tmp_ns);
- ((_ret_struct_ns) + current_zone_count)->ns3_ip = strdup(tmp_ns_ip);
- break;
- case 4:
- ((_ret_struct_ns) + current_zone_count)->ns4 = strdup(tmp_ns);
- ((_ret_struct_ns) + current_zone_count)->ns4_ip = strdup(tmp_ns_ip);
- break;
- }
- printf("\t [%d] ns count : [%d]\n",current_zone_count, _ret_st_mainstruct_domain_zone[current_zone_count].domain_zone_ns_count);
- }
- }
- }
- }
- }
- return _ret_st_mainstruct_domain_zone;
- }
- static int create_sock()
- {
- int rldns_sock, true = 1;
- if ((rldns_sock = socket(PF_INET, SOCK_DGRAM, 0)) == -1)
- _msg_terminated_err(sock_fail);
- if (setsockopt(rldns_sock, SOL_SOCKET, SO_REUSEADDR, &true, sizeof(int)) == -1)
- _msg_err(fail_reuseaddr);
- return rldns_sock;
- }
- static int nb_bind(int rldns_sock)
- {
- int res;
- char y_or_n;
- if ((res = fcntl_nonblock(rldns_sock)) < 0) {
- y_or_n = cont_or_no();
- if ((y_or_n == 0x6e) || (y_or_n == 0x4e))
- exit(0);
- }
- server_addr.sin_family = AF_INET;
- server_addr.sin_port = htons(rldns_port);
- server_addr.sin_addr.s_addr = INADDR_ANY;
- bzero(&(server_addr.sin_zero), 8);
- if (bind(rldns_sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) < 0)
- _msg_terminated_err(fail_bind);
- return rldns_sock;
- }
- static inline char *_switch_rand(int _rand, int zone_uid)
- {
- tmp_ip = n_malloc(16);
- switch(_rand) {
- case 1:
- tmp_ip = ((_ret_struct_a_res) + zone_uid)->a_ip1;
- break;
- case 2:
- tmp_ip = ((_ret_struct_a_res) + zone_uid)->a_ip2;
- break;
- case 3:
- tmp_ip = ((_ret_struct_a_res) + zone_uid)->a_ip3;
- break;
- case 4:
- tmp_ip = ((_ret_struct_a_res) + zone_uid)->a_ip4;
- break;
- case 5:
- tmp_ip = ((_ret_struct_a_res) + zone_uid)->a_ip5;
- break;
- case 6:
- tmp_ip = ((_ret_struct_a_res) + zone_uid)->a_ip6;
- break;
- case 7:
- tmp_ip = ((_ret_struct_a_res) + zone_uid)->a_ip7;
- break;
- case 8:
- tmp_ip = ((_ret_struct_a_res) + zone_uid)->a_ip8;
- break;
- case 9:
- tmp_ip = ((_ret_struct_a_res) + zone_uid)->a_ip9;
- break;
- case 10:
- tmp_ip = ((_ret_struct_a_res) + zone_uid)->a_ip10;
- break;
- case 11:
- tmp_ip = ((_ret_struct_a_res) + zone_uid)->a_ip11;
- break;
- case 12:
- tmp_ip = ((_ret_struct_a_res) + zone_uid)->a_ip12;
- break;
- case 13:
- tmp_ip = ((_ret_struct_a_res) + zone_uid)->a_ip13;
- break;
- case 14:
- tmp_ip = ((_ret_struct_a_res) + zone_uid)->a_ip14;
- break;
- case 15:
- tmp_ip = ((_ret_struct_a_res) + zone_uid)->a_ip15;
- break;
- case 16:
- tmp_ip = ((_ret_struct_a_res) + zone_uid)->a_ip16;
- break;
- case 17:
- tmp_ip = ((_ret_struct_a_res) + zone_uid)->a_ip17;
- break;
- case 18:
- tmp_ip = ((_ret_struct_a_res) + zone_uid)->a_ip18;
- break;
- }
- return tmp_ip;
- }
- static inline char *_set_randomize_a_ip(int zone_uid)
- {
- /**
- _st_tmp_ip_fetcher *_struct_tmp_ip_fetcher;
- **/
- boolean valid;
- int aray_rand[(_ret_st_mainstruct_domain_zone + zone_uid)->domain_zone_a_ip_count];
- char *total_ip_sequence;
- char *add_this;
- char *domain;
- int how_many = (_ret_st_mainstruct_domain_zone + zone_uid)->domain_zone_a_ip_count;
- int found, _rand, i, try, range, amount = 0;
- try = 0;
- /**_ret_st_mainstruct_domain_zone[i].domain_zone_a_ip_count **/
- printf("\t[+] zone_uid [%d]\n", zone_uid);
- domain = (_ret_st_mainstruct_domain_zone + zone_uid)->domain_zone;
- printf("\t[+] domain to set random now : [%s]\n", domain);
- range = _ret_st_mainstruct_domain_zone[zone_uid].domain_zone_a_ip_count + 1;
- 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);
- printf("\t[+] a name count [%d]\n", how_many);
- for (i = 0; i <= how_many; i++) {
- try++;
- if (try > 140000)
- break;
- found = 1;
- srand(_do_rdtsc());
- _rand = rand() % range;
- found = find_element(aray_rand, _rand);
- if (found == 0) {
- amount++;
- aray_rand[i] = _rand;
- add_this = _switch_rand(_rand, zone_uid);
- /** validate ip octet **/
- valid = validate_ipv4_octet(add_this);
- if (valid == true) {
- strcat(total_ip_sequence, add_this);
- strcat(total_ip_sequence, "|");
- }
- if ((amount > how_many) || (amount == how_many))
- goto out;
- }
- else
- i--;
- }
- out:
- return total_ip_sequence;
- }
- static inline char *determine_dns_request_type(char *request)
- {
- char *return_request_type;
- int i, marker = 0;
- for (i = header_length; i <= MAX_A_LENGTH_ALLOWED; i++) {
- if ((int)request[i] == 0) {
- marker = 1;
- break;
- }
- }
- return_request_type = n_malloc(2);
- i+= 2;
- if ((unsigned)(unsigned char)request[i] == 0xf)
- return_request_type = "mx";
- else if ((unsigned)(unsigned char)request[i] == 0x2)
- return_request_type = "ns";
- else if ((unsigned)(unsigned char)request[i] == 0x1)
- return_request_type = "A";
- else
- return_request_type = "A";
- return return_request_type;
- }
- 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)
- {
- char *tot_res, *tmp_data;
- int i, j, qid_ar, number_of_answer = 0;
- char *piece = NULL;
- char *octet = NULL;
- typedef struct {
- char *ip;
- }_tmp_data;
- _tmp_data *__tmp_data;
- __tmp_data = malloc(18 *sizeof(__tmp_data));
- if (a_resolver_type == 3) {
- tot_res = n_malloc(16);
- for (i = 0; i < 16; i++)
- tot_res[i] = total_res_ip[i];
- }
- else {
- tot_res = n_malloc(strlen(total_res_ip));
- for (i = 0; i < strlen(total_res_ip); i++)
- tot_res[i] = total_res_ip[i];
- }
- number_of_answer = _count_answer_length(tot_res, "answer_count");
- /** craft dns header **/
- dns_response[0] = qid[0];
- dns_response[1] = qid[1];
- dns_response[2] = 0x81;
- dns_response[3] = 0x80;
- dns_response[4] = 0x0;
- dns_response[5] = 0x1;
- dns_response[6]= 0x0;
- dns_response[7] = number_of_answer;
- dns_response[8] = 0x0;
- dns_response[9] = 0x0; /** NSCount : Authority Record Count **/
- dns_response[10] = 0x0;
- dns_response[11] = 0x0; /**ARCount : Additional Record Count: Specifies the number of resource records in the Additional section of the message.**/
- i = 0;
- qid_ar = (int)(qid[0]) + (int)(qid[1]);
- /**
- typedef struct {
- int _cur_receive;
- char *_cur_dns_response;
- char *_cur_tot_res_ip;
- int _cur_ans_count;
- } _st_struct_current_dns_resp;
- _ret_st_struct_current_dns_resp = malloc(255 *sizeof(_ret_st_struct_current_dns_resp));
- since a name response is similar we will equip the same code just like a anwer
- nah it's global struct
- **/
- (_ret_st_struct_current_dns_resp + qid_ar)->_cur_receive = receive;
- (_ret_st_struct_current_dns_resp + qid_ar)->_cur_dns_response = dns_response;
- (_ret_st_struct_current_dns_resp + qid_ar)->_cur_tot_res_ip = total_res_ip;
- (_ret_st_struct_current_dns_resp + qid_ar)->_cur_ans_count = number_of_answer;
- if (strstr(total_res_ip, "|")) {
- piece = strtok(total_res_ip, "|");
- while (piece != NULL) {
- (__tmp_data + i)->ip = piece;
- piece = strtok(NULL, "|");
- i++;
- }
- for (j = 0;j < i; j++) {
- tmp_data = n_malloc(strlen((__tmp_data + j)->ip));
- tmp_data = (__tmp_data + j)->ip;
- /** craft answer section **/
- dns_response[receive++] = 0xc0;
- dns_response[receive++] = 0xc; /** offset **/
- dns_response[receive++] = 0x0;
- dns_response[receive++] = 0x1;
- dns_response[receive++] = 0x0;
- dns_response[receive++] = 0x1;
- dns_response[receive++] = 0x0;
- dns_response[receive++] = 0x0;
- dns_response[receive++] = 0x0;
- dns_response[receive++] = 0x3c;
- dns_response[receive++] = 0x0;
- dns_response[receive++] = 0x4;
- octet = strtok(tmp_data, ".");
- while (octet != NULL) {
- dns_response[receive++] = atoi(octet);
- octet = strtok(NULL, ".");
- }
- }
- }
- else {
- /** processing single ip address **/
- dns_response[receive++] = 0xc0;
- dns_response[receive++] = 0xc; /** offset **/
- dns_response[receive++] = 0x0;
- dns_response[receive++] = 0x1;
- dns_response[receive++] = 0x0;
- dns_response[receive++] = 0x1;
- dns_response[receive++] = 0x0;
- dns_response[receive++] = 0x0;
- dns_response[receive++] = 0x0;
- dns_response[receive++] = 0x3c;
- dns_response[receive++] = 0x0;
- dns_response[receive++] = 0x4;
- tmp_data = n_malloc(16);
- tmp_data = (_ret_struct_a_res + zone_uid)->a_ip1;
- octet = strtok(tmp_data, ".");
- while (octet != NULL) {
- dns_response[receive++] = atoi(octet);
- octet = strtok(NULL, ".");
- }
- }
- (_ret_st_struct_current_dns_resp + qid_ar)->_cur_receive = receive;
- return dns_response;
- }
- static inline char *parse_dns_query_and_fetch_a_req(char *msg, char *mode)
- {
- /**
- this function is made based on my own experiment
- sorry for any mistakes here
- **/
- int z, i, x, start_offset = header_length;
- int max_search_a = start_offset + max_domain_name_length;
- char aname[max_domain_name_length + 1];
- char *ret_a_name, *piece = NULL;
- if ((msg[start_offset] == 0x77) && (msg[start_offset + 1] == 0x77) && (msg[start_offset + 2] == 0x77))
- start_offset = 17;
- aname[max_domain_name_length + 1] = '\0';
- x = 0;
- for (i = start_offset; i <= max_search_a; i++) {
- if ((msg[i] == 0x00) || msg[i] == 0)
- break;
- else if ((msg[i] == 0x1) || (msg[i] == 0x2) || (msg[i] == 0x3) || (msg[i] == 0x4) ||
- (msg[i] == 0x5) || (msg[i] == 0x6) || (msg[i] == 0x7) || (msg[i] == 0x8) ||
- (msg[i] == 0x9) || (msg[i] == 0xc)) {
- aname[x] = '.';
- x++;
- }
- else {
- aname[x] = (char)msg[i];
- x++;
- }
- }
- ret_a_name = n_malloc(x);
- for (z = 0; z < x; z++) {
- if (sizeof(aname[z]) > 0)
- ret_a_name[z] = aname[z];
- }
- if (strcmp(mode, "a_name_without_tld") == 0) {
- piece = strtok(ret_a_name, ".");
- ret_a_name = n_malloc(strlen(piece));
- strcpy(ret_a_name, piece);
- }
- return (char *)ret_a_name;
- }
- static inline int _count_answer_length(char *total_res_ip, char *mode)
- {
- /** count answer length **/
- char *piece = NULL;
- int leng_tot_ip = 0;
- int num_of_ans = 0;
- int ret = 0;
- piece = strtok(total_res_ip, "|");
- while (piece != NULL) {
- if (strcmp(mode, "length") == 0) {
- leng_tot_ip += strlen(piece);
- leng_tot_ip += 10;
- ret = leng_tot_ip;
- }
- else if (strcmp(mode, "answer_count") == 0)
- num_of_ans++;
- piece = strtok(NULL, "|");
- }
- if (strcmp(mode, "length") == 0)
- ret = leng_tot_ip;
- else if (strcmp(mode, "answer_count") == 0)
- ret = num_of_ans;
- return ret;
- }
- static inline char *_set_non_randomize_a_ip(int zone_uid)
- {
- char *total_ip_sequence;
- char *domain;
- int i, how_many = (_ret_st_mainstruct_domain_zone + zone_uid)->domain_zone_a_ip_count;
- boolean valid;
- printf("\t[+] zone_uid [%d]\n", zone_uid);
- printf("\t[+] a ip count : [%d]\n",_ret_st_mainstruct_domain_zone[zone_uid].domain_zone_a_ip_count);
- 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);
- domain = (_ret_st_mainstruct_domain_zone + zone_uid)->domain_zone;
- printf("\t[+] domain to resolve now : [%s]\n", domain);
- printf("\t[+] how_many equ : [%d]\n", how_many);
- for (i = 0; i < how_many; i++) {
- tmp_ip = n_malloc(16);
- switch(i) {
- case 0:
- tmp_ip = (_ret_struct_a_res + zone_uid)->a_ip1;
- break;
- case 1:
- tmp_ip = (_ret_struct_a_res + zone_uid)->a_ip2;
- break;
- case 2:
- tmp_ip = (_ret_struct_a_res + zone_uid)->a_ip3;
- break;
- case 3:
- tmp_ip = (_ret_struct_a_res + zone_uid)->a_ip4;
- break;
- case 4:
- tmp_ip = (_ret_struct_a_res + zone_uid)->a_ip5;
- break;
- case 5:
- tmp_ip = (_ret_struct_a_res + zone_uid)->a_ip6;
- break;
- case 6:
- tmp_ip = (_ret_struct_a_res + zone_uid)->a_ip7;
- break;
- case 7:
- tmp_ip = (_ret_struct_a_res + zone_uid)->a_ip8;
- break;
- case 8:
- tmp_ip = (_ret_struct_a_res + zone_uid)->a_ip9;
- break;
- case 9:
- tmp_ip = (_ret_struct_a_res + zone_uid)->a_ip10;
- break;
- case 10:
- tmp_ip = (_ret_struct_a_res + zone_uid)->a_ip11;
- break;
- case 11:
- tmp_ip = (_ret_struct_a_res + zone_uid)->a_ip12;
- break;
- case 12:
- tmp_ip = (_ret_struct_a_res + zone_uid)->a_ip13;
- break;
- case 13:
- tmp_ip = (_ret_struct_a_res + zone_uid)->a_ip14;
- break;
- case 14:
- tmp_ip = (_ret_struct_a_res + zone_uid)->a_ip15;
- break;
- case 15:
- tmp_ip = (_ret_struct_a_res + zone_uid)->a_ip16;
- break;
- case 16:
- tmp_ip = (_ret_struct_a_res + zone_uid)->a_ip17;
- break;
- case 17:
- tmp_ip = (_ret_struct_a_res + zone_uid)->a_ip18;
- break;
- }
- if ((strstr(tmp_ip, ".")) && (strlen(tmp_ip) > 2)) {
- /** validate ip octet **/
- valid = validate_ipv4_octet(tmp_ip);
- if (valid == true) {
- strcat(total_ip_sequence, tmp_ip);
- strcat(total_ip_sequence, "|");
- }
- }
- }
- return total_ip_sequence;
- }
- static inline char *craft_dns_aname_response(char *qid, char *dns_response, int receive)
- {
- int i, a_counter = 0;
- char *total_res_ip, *a_name;
- a_name = n_malloc(max_domain_name_length);
- a_name = parse_dns_query_and_fetch_a_req(dns_response, "a_name");
- /** debugging purpose **/
- printf("\n\t[+] Client requesting a name req : [%s]\n", a_name);
- /** looping to search from appropriate structures for this a name req **/
- for (i = 1; i < zone_count; i++) {
- 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);
- if ((strcmp((_ret_st_mainstruct_domain_zone + i )->domain_zone, a_name)) == 0) {
- printf("\t[+] found match zone a name : [%s]\n",(_ret_st_mainstruct_domain_zone + i)->domain_zone);
- 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)));
- a_counter = (_ret_st_mainstruct_domain_zone[i].domain_zone_a_ip_count);
- if (a_resolver_type == 1)
- total_res_ip = _set_non_randomize_a_ip((_ret_st_mainstruct_domain_zone + i)->uid);
- else if (a_resolver_type == 2) {
- if (a_counter < 4)
- total_res_ip = _set_non_randomize_a_ip((_ret_st_mainstruct_domain_zone + i)->uid);
- else
- total_res_ip = _set_randomize_a_ip((_ret_st_mainstruct_domain_zone + i)->uid);
- }
- break;
- }
- }
- dns_response = do_craft_dns_aname_response(total_res_ip, qid, a_name, dns_response, receive, (_ret_st_mainstruct_domain_zone + i)->uid);
- return dns_response;
- }
- static inline char *craft_dns_mx_response(char *qid, char *dns_response, int receive)
- {
- char *a_name;
- int i;
- a_name = n_malloc(max_domain_name_length);
- a_name = parse_dns_query_and_fetch_a_req(dns_response, "a_name");
- printf("\n\trequested mx for a_name : [%s]\n", a_name);
- for (i = 1; i < zone_count; i++) {
- if ((strcmp((_ret_st_mainstruct_domain_zone + i)->domain_zone, a_name)) == 0) {
- printf("\t[+] found match zone a name : [%s]\n",(_ret_st_mainstruct_domain_zone + i)->domain_zone);
- dns_response = do_craft_dns_mx_response(qid, a_name, dns_response, receive, i);
- }
- }
- return dns_response;
- }
- static inline char *craft_dns_ns_response(char *qid, char *dns_response, int receive)
- {
- char *a_name;
- int i;
- a_name = n_malloc(max_domain_name_length);
- a_name = parse_dns_query_and_fetch_a_req(dns_response, "a_name");
- printf("\n\trequested mx for a_name : [%s]\n", a_name);
- for (i = 1; i < zone_count; i++) {
- if ((strcmp((_ret_st_mainstruct_domain_zone + i)->domain_zone, a_name)) == 0) {
- printf("\t[+] found match zone a name : [%s]\n",(_ret_st_mainstruct_domain_zone + i)->domain_zone);
- dns_response = do_craft_dns_ns_response(qid, a_name, dns_response, receive, i);
- }
- }
- return dns_response;
- }
- static inline char *do_craft_dns_mx_response(char *qid, char *a_name, char *dns_response, int receive, int zone_uid)
- {
- int qid_ar;
- /** flags **/
- dns_response[0] = qid[0];
- dns_response[1] = qid[1]; /** dns qid**/
- /**forget to casting here **/
- qid_ar = (int)(qid[0]) + (int)(qid[1]);
- dns_response[2] = 0x85;
- dns_response[3] = 0x00;
- dns_response[4] = 0x0;
- dns_response[5] = 0x1; /** defined question num **/
- dns_response[6]= 0x0;
- dns_response[7] = 0x2; /** answer num **/
- dns_response[8] = 0x0;
- dns_response[9] = 0x00; /** NSCount : Authority Record Count **/
- dns_response[10] = 0x0;
- /***for additional record we will use only 1 **/
- dns_response[11] = 0x0; /**ARCount : Additional Record Count: Specifies the number of resource records in the Additional section of the message.**/
- /** craft answer section **/
- dns_response[receive++] = 0xc0;
- dns_response[receive++] = 0x0c; /** defined offset here **/
- dns_response[receive++] = 0x0;
- dns_response[receive++] = 0x0f; /** mx answer type**/
- dns_response[receive++] = 0x0;
- dns_response[receive++] = 0x01; /** class **/
- dns_response[receive++] = 0x0;
- dns_response[receive++] = 0x0;
- dns_response[receive++] = 0x01;
- dns_response[receive++] = 0x2c; /** ttl defined as 5 minutes **/
- dns_response[receive++] = 0x0;
- dns_response[receive++] = 0x09; /**data length : 9 (ringlayer)**/
- dns_response[receive++] = 0x0;
- dns_response[receive++] = 0x0a; /**preference = 10 **/
- /** mail **/
- dns_response[receive++] = 0x04;
- dns_response[receive++] = 0x6d;
- dns_response[receive++] = 0x61;
- dns_response[receive++] = 0x69;
- dns_response[receive++] = 0x6c;
- dns_response[receive++] = 0xc0;
- dns_response[receive++] = 0xc;
- /** craft second answer **/
- dns_response[receive++] = 0xc0;
- dns_response[receive++] = 0x0c; /** defined offset **/
- dns_response[receive++] = 0x0;
- dns_response[receive++] = 0x0f; /** mx answer type**/
- dns_response[receive++] = 0x0;
- dns_response[receive++] = 0x01; /** class **/
- dns_response[receive++] = 0x0;
- dns_response[receive++] = 0x0;
- dns_response[receive++] = 0x01;
- dns_response[receive++] = 0x2c; /** ttl defined as 5 minutes **/
- dns_response[receive++] = 0x0;
- dns_response[receive++] = 0x9; /**data length : 9 (ringlayer)**/
- dns_response[receive++] = 0x0;
- dns_response[receive++] = 0xA; /**preference = 10 **/
- /** smtp
- 73:6d:74:70
- **/
- dns_response[receive++] = 0x04;
- dns_response[receive++] = 0x73;
- dns_response[receive++] = 0x6d;
- dns_response[receive++] = 0x74;
- dns_response[receive++] = 0x70;
- dns_response[receive++] = 0xc0;
- dns_response[receive++] = 0xc;
- /***just like mx response before , similar code will be applied for ns response**/
- (_ret_st_struct_current_dns_resp + qid_ar)->_cur_receive = receive;
- (_ret_st_struct_current_dns_resp + qid_ar)->_cur_ans_count = 1;
- return dns_response;
- }
- static inline char *do_craft_dns_ns_response(char *qid, char *a_name, char *dns_response, int receive, int zone_uid)
- {
- int qid_ar;
- /**qid_ar should be integer**/
- qid_ar = (int)(qid[0]) + (int)(qid[1]);
- /** flag **/
- dns_response[0] = qid[0];
- dns_response[1] = qid[1];
- dns_response[2] = 0x85;
- dns_response[3] = 0x00;
- dns_response[4] = 0x0;
- dns_response[5] = 0x01; /** question number **/
- dns_response[6] = 0x00;
- dns_response[7] = 0x02; /** number of answer = 2, test with 2 answer **/
- dns_response[8] = 0x0;
- dns_response[9] = 0x0; /** authority rrs **/
- dns_response[10] = 0x0;
- dns_response[11] = 0x0; /** additional records **/
- /** craft 1st answer
- receive is integer will contains next array number after question
- **/
- dns_response[receive++] = 0xc0;
- dns_response[receive++] = 0xc; /** offset **/
- dns_response[receive++] = 0x00;
- dns_response[receive++] = 0x02; /** answer type : ns **/
- dns_response[receive++] = 0x00;
- dns_response[receive++] = 0x01; /** class **/
- dns_response[receive++] = 0x00;
- dns_response[receive++] = 0x01;
- dns_response[receive++] = 0x51;
- dns_response[receive++] = 0x80; /** ttl = 1d **/
- dns_response[receive++] = 0x00;
- dns_response[receive++] = 0x06;
- dns_response[receive++] = 0x03;
- dns_response[receive++] = 0x6e; //n
- dns_response[receive++] = 0x73; //s
- dns_response[receive++] = 0x31; //1
- dns_response[receive++] = 0xc0;
- dns_response[receive++] = 0xc;
- /** craft 2nd answer
- receive is integer will contains next array number after question
- **/
- dns_response[receive++] = 0xc0;
- dns_response[receive++] = 0xc; /** offset **/
- dns_response[receive++] = 0x00;
- dns_response[receive++] = 0x02; /** answer type : ns **/
- dns_response[receive++] = 0x00;
- dns_response[receive++] = 0x01; /** class **/
- dns_response[receive++] = 0x00;
- dns_response[receive++] = 0x01;
- dns_response[receive++] = 0x51;
- dns_response[receive++] = 0x80; /** ttl = 1d **/
- dns_response[receive++] = 0x00;
- dns_response[receive++] = 0x06;
- dns_response[receive++] = 0x03;
- dns_response[receive++] = 0x6e; //n
- dns_response[receive++] = 0x73; //s
- dns_response[receive++] = 0x32; //2
- dns_response[receive++] = 0xc0;
- dns_response[receive++] = 0xc;
- (_ret_st_struct_current_dns_resp + qid_ar)->_cur_receive = receive; /**fillin the struct to record last array number***/
- //(_ret_st_struct_current_dns_resp + qid_ar)->_cur_ans_count = 1;
- return dns_response;
- }
- static int rldns_main()
- {
- int qid_ar, len, rldns_sock;
- char *dns_packet, *client_ip, *a_name, *a_name_without_tld, *dns_response_type, *qid;
- char buf_dns_packet[PACKET_SIZE];
- int rcv_flag = 0;
- int receive;
- _ret_st_struct_current_dns_resp = malloc(77 *sizeof(_ret_st_struct_current_dns_resp));
- buf_dns_packet[PACKET_SIZE + 1] = '\0';
- dns_packet = n_malloc(PACKET_SIZE);
- epoll_fd = epoll_create(10);
- rldns_sock = create_sock();
- rldns_sock = nb_bind(rldns_sock);
- len = sizeof(client_addr);
- while (1) {
- receive = recvfrom(rldns_sock, dns_packet, PACKET_SIZE, rcv_flag, (struct sockaddr *) &client_addr, (socklen_t * __restrict__)&len);
- if (receive < 0) {continue;}
- client_ip = n_malloc(16);
- client_ip = inet_ntoa(client_addr.sin_addr);
- printf("\n=========================dns operation================================\n\n");
- printf("\t[+] got new client from [%s]\n", client_ip);
- a_name = n_malloc(max_domain_name_length);
- a_name = parse_dns_query_and_fetch_a_req(dns_packet, "a_name");
- a_name = n_malloc(max_domain_name_length);
- a_name_without_tld = parse_dns_query_and_fetch_a_req(dns_packet, "a_name_without_tld");
- qid = n_malloc(2);
- qid = get_current_dns_qid(dns_packet);
- printf("\t[+] got current qid : 0x%x 0x%x\n", (unsigned)(unsigned char)qid[0],(unsigned)(unsigned char)qid[1]);
- dns_response_type = determine_dns_request_type(dns_packet);
- printf("\t[+] got ret dns req type : [%s]\n", dns_response_type);
- qid_ar = (int)(qid[0]) + (int)(qid[1]);
- if (strcmp(dns_response_type, "A") == 0) {
- dns_packet = craft_dns_aname_response(qid, dns_packet, receive);
- receive = (_ret_st_struct_current_dns_resp + qid_ar)->_cur_receive;
- }
- else if (strcmp(dns_response_type, "mx") == 0) {
- dns_packet = craft_dns_mx_response(qid, dns_packet, receive);
- receive = (_ret_st_struct_current_dns_resp + qid_ar)->_cur_receive;
- }
- else if (strcmp(dns_response_type, "ns") == 0) {
- dns_packet = craft_dns_ns_response(qid, dns_packet, receive);
- receive = (_ret_st_struct_current_dns_resp + qid_ar)->_cur_receive;
- }
- else {
- dns_packet = craft_dns_aname_response(qid, dns_packet, receive);
- receive = (_ret_st_struct_current_dns_resp + qid_ar)->_cur_receive;
- }
- /**
- for (i = 0; i < 513; i++) {
- printf("hex packet : [%d] : [0x%x] \n", i, (unsigned)(unsigned char)dns_response[i]);
- }
- **/
- sendto(rldns_sock, dns_packet, receive, rcv_flag,(struct sockaddr *)&client_addr, len);
- }
- return 0;
- }
- int main()
- {
- _check_config();
- _cfg = _init_read_parse_config();
- _read_zone_file();
- rldns_port = _cfg[0].port;
- rldns_main();
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement