Host to dns encoding program

Host to dns encoding program

#include<stdio.h>

#include<sys/socket.h>

#include<netinet/in.h>

#include<stdlib.h>

#include<string.h>

#define DNSHEADERSIZE 12

#define QUERYSIZE 4

#define PREFERENCE_SIZE 2

#define QUERYTYPE_A 1

#define QUERYTYPE_NS 2

#define QUERYTYPE_MX 15

#define RESRECORDOFFSET 10

#define RESRECORD_TYPEOFFSET 0

#define RESRECORD_CLASSOFFSET 2

#define RESRECORD_TTLOFFSET 4

#define RESRECORD_RDLENOFFSET 8

void hostNameToDNSEncoding (unsigned char*,unsigned char*);

unsigned char* queryNameFind (unsigned char*,unsigned char*,int*);

struct DNS_HEADER

{

unsigned short id;

unsigned char rd :1;

unsigned char tc :1;

unsigned char aa :1;

unsigned char opcode :4;

unsigned char qr :1;

unsigned char rcode :4;

unsigned char z1 :1;

unsigned char z2 :1;

unsigned char z3 :1;

unsigned char ra :1;

unsigned short questionCount;

unsigned short answerCount;

unsigned short auth_count;

unsigned short add_count;

};

struct QUESTION

{

unsigned short qtype;

unsigned short qclass;

};

int main()

{

int i , j , s;

int nbytes;

int qqueryNameSize;

int offsetToNextRecord;

int queryType;

unsigned char hostqueryName[100];

unsigned char dnsServerName[100];

unsigned char buf[65536],*qqueryName;

unsigned char answerbuf[65536],*answersPtr;

unsigned char *temp;

struct sockaddr_in a;

struct sockaddr_in dest;

struct DNS_HEADER *dns = NULL;

struct QUESTION *qinfo = NULL;

printf("Enter DNS Server name : ");

gets((char*)dnsServerName);

printf("Enter HostName to Lookup (Ex:www.google.com):");

gets((char*)hostqueryName);

printf("Following are the valid query types\r\n");

printf("TYPE value and meaning \r\n"

"A 1 a host address \r\n"

"NS 2 an authoritative name server \r\n"

"MX 15 mail exchange \r\n");

printf("Enter query type (1,2 or 15):");

scanf("%d",&queryType);

temp = (char *)malloc(sizeof(100*sizeof(char)));

/*

Creating socket to send data query to the server

*/

s = socket(AF_INET , SOCK_DGRAM , IPPROTO_UDP);

dest.sin_family = AF_INET;

dest.sin_port = htons(53);

dest.sin_addr.s_addr = inet_addr(dnsServerName);

//Set the DNS structure to standard queries

dns = (struct DNS_HEADER *)&buf;

dns->id = (unsigned short) htons(100);

dns->qr = 0;

dns->opcode = 0;

dns->aa = 0;

dns->tc = 0;

dns->rd = 1;

dns->ra = 0;

dns->z3 = 0;

dns->z2 = 0;

dns->z1 = 0;

dns->rcode = 0;

dns->questionCount = htons(1);

dns->answerCount = 0;

dns->auth_count = 0;

qqueryName =(unsigned char*)&buf[DNSHEADERSIZE];

hostNameToDNSEncoding(qqueryName , hostqueryName);

qinfo=(struct QUESTION*)&buf[DNSHEADERSIZE + (strlen((const char*)qqueryName) + 1)]; //fill it

switch (queryType)

{

case 1:

qinfo->qtype = htons(QUERYTYPE_A);

break;

case 2:

qinfo->qtype = htons(QUERYTYPE_NS);

break;

case 15:

qinfo->qtype = htons(QUERYTYPE_MX);

break;

default:

printf("Incorrect option entered:Default to A\r\n");

qinfo->qtype = htons(QUERYTYPE_A);

break;

}

qinfo->qclass = htons(1);

if(sendto(s,(char*)buf,DNSHEADERSIZE + (strlen((const char*)qqueryName)+1) + QUERYSIZE,0,(struct sockaddr*)&dest,sizeof(dest)) == 0)

{

printf("Error: Sending message to DNS server\r\n");

}

i = sizeof(dest);

if((nbytes=recvfrom (s,(char*)buf,65536,0,(struct sockaddr*)&dest,&i)) == 0)

{

printf("Error: Failed to receive from DNS server\r\n");

}

dns = (struct DNS_HEADER*) buf;

answersPtr=&buf[DNSHEADERSIZE + (strlen((const char*)qqueryName)+1) + QUERYSIZE];

/*

Checking for the retunred error condition if any

*/

switch ((dns->rcode))

{

case 1:

printf("ERROR: FORMAT ERROR\r\n");

break;

case 2:

printf("ERROR: SERVER FAILURE\r\n");

break;

case 3:

printf("ERROR: NAME ERROR\r\n");

break;

case 4:

printf("ERROR: NOT IMPLEMENTED\r\n");

break;

case 5:

printf("ERROR: REFUSED\r\n");

break;

}

if((dns->rcode)!=0)

{

free(temp);

exit(1);

}

offsetToNextRecord=0;

printf("ANSWER SECTION:\n");

for(i = 0 ; i < ntohs(dns->answerCount) ;i ++)

{

int rrType;

int rrClass;

int rrTTL;

int rrRDLength;

temp=queryNameFind(answersPtr,buf,&offsetToNextRecord);

printf("%s\t",temp);

answersPtr = answersPtr + offsetToNextRecord;

#if 0

printf("size of int is %d \r\n", sizeof(int));

printf("size of ushort is %d \r\n", sizeof(unsigned short));

printf("TYPE is %d \r\n", ntohs(*(unsigned short *)answersPtr));

printf("CLASS is %d \r\n", ntohs(*(unsigned short *)(answersPtr+2)));

printf("TTL is %d \r\n", ntohs(*(int *)(answersPtr+4)));

printf("RDLENGTH is %d \r\n", ntohs(*(unsigned short *)(answersPtr+8)));

#endif

rrType= ntohs(*(unsigned short *)answersPtr);

rrClass = ntohs(*(unsigned short *)(answersPtr+RESRECORD_CLASSOFFSET));

rrTTL = ntohs(*(int *)(answersPtr+RESRECORD_TTLOFFSET));

rrRDLength = ntohs(*(unsigned short *)(answersPtr+RESRECORD_RDLENOFFSET));

answersPtr = answersPtr + RESRECORDOFFSET;

if(rrType == QUERYTYPE_A)

{

printf("A \tIPv4 address : ");

for(j=0 ; j<rrRDLength ; j++)

{

printf("%d",answersPtr[j]);

if(j<rrRDLength-1)

printf(".");

}

printf("\n");

answersPtr = answersPtr + rrRDLength;

}

else if(rrType == QUERYTYPE_MX)

{

printf("MX Pref : %d \t",ntohs(*((unsigned short *)answersPtr)));

answersPtr += PREFERENCE_SIZE;

free(temp);

temp=queryNameFind(answersPtr,buf,&offsetToNextRecord);

printf("Exch Server: %s\r\n",temp);

answersPtr = answersPtr + offsetToNextRecord;

}

else

{

free(temp);

temp=queryNameFind(answersPtr,buf,&offsetToNextRecord);

printf("\tIN\tNS\t%s\r\n",temp);

answersPtr = answersPtr + offsetToNextRecord;

}

}

free(temp);

return;

}

void hostNameToDNSEncoding(unsigned char* encodedDns,unsigned char* host)

{

int location = 0 , i;

strcat((char*)host,".");

for(i = 0 ; host[i]!=0 ; i++) {

if(host[i]=='.') {

[

*encodedDns++=i-location;

for(;location<i;location++) {

*encodedDns++=host[location];

}

location++;

}

}

*encodedDns++='\0';

}

unsigned char* queryNameFind(unsigned char* replyRR,unsigned char* buffer,int* count)

{

unsigned char *queryName;

unsigned int p=0,moved=0,offset;

int i , j;

*count = 1;

queryName = (unsigned char*)malloc(256);

queryName[0]='\0';

while(*replyRR!=0)

{

//Checking if the 1st byte has the MSB 2 bits being set

// ex: 11000001 00001100

if(*replyRR>=0xC0)

{

(*replyRR) = (*replyRR) & 0x3F;

//00000001 00001100

offset = htons(*((unsigned short *)replyRR));

(*replyRR) = (*replyRR) | 0xC0;

//11000001 00001100

replyRR = buffer + offset - 1;

moved = 1;

}

else

queryName[p++]=*replyRR;

replyRR=replyRR+1;

if(moved==0)

*count = *count + 1;

}

queryName[p]='\0';

if(moved==1)

*count = *count + 1;

for(i=0;i<(int)strlen((const char*)queryName);i++) {

p=queryName[i];

for(j=0;j<(int)p;j++) {

queryName[i]=queryName[i+1];

i=i+1;

}

queryName[i]='.';

}

queryName[i-1]='\0';

return queryName;

}

Please be aware that the free essay that you were just reading was not written by us. This essay, and all of the others available to view on the website, were provided to us by students in exchange for services that we offer. This relationship helps our students to get an even better deal while also contributing to the biggest free essay resource in the UK!