Dns.c
Copy Code code as follows:
/*
* DNS Query Program on Linux
*
* author:ismdeep@live.com
*
* */
Header Files
#include <stdio.h>//printf
#include <string.h>//strlen
#include <stdlib.h>//malloc
#include <sys/socket.h>//you know what
#include <arpa/inet.h>//inet_addr, Inet_ntoa, Ntohs etc
#include <netinet/in.h>
#include <unistd.h>//getpid
List of DNS Servers registered on the system
Char dns_servers[10][100];
int dns_server_count = 0;
Types of DNS resource records:)
#define T_A 1//ipv4 Address
#define T_NS 2//nameserver
#define T_CNAME 5//canonical name
#define T_SOA 6/* Start of authority zone * *
#define T_PTR/* Domain name pointer * *
#define T_MX//mail Server
Function prototypes
void Ngethostbyname (unsigned char*, int);
void Changetodnsnameformat (unsigned char*,unsigned char*);
unsigned char* readname (unsigned char*,unsigned char*,int*);
void Get_dns_servers ();
DNS Header Structure
struct Dns_header
{
unsigned short ID; Identification number
unsigned char rd:1; Recursion desired
unsigned char tc:1; Truncated message
unsigned char aa:1; Authoritive answer
unsigned char opcode:4; Purpose of Message
unsigned char qr:1; Query/response Flag
unsigned char rcode:4; Response code
unsigned char cd:1; Checking disabled
unsigned char ad:1; Authenticated data
unsigned char z:1; Its z! Reserved
unsigned char ra:1; Recursion available
unsigned short q_count; Number of question entries
unsigned short ans_count; Number of answer entries
unsigned short auth_count; Number of authority entries
unsigned short add_count; Number of resource entries
};
Constant sized fields of query structure
struct question
{
unsigned short qtype;
unsigned short qclass;
};
Constant sized fields of the resource record structure
#pragma pack (push, 1)
struct R_data
{
unsigned short type;
unsigned short _class;
unsigned int ttl;
unsigned short data_len;
};
#pragma pack (POP)
Pointers to resource record contents
struct Res_record
{
unsigned char *name;
struct R_data *resource;
unsigned char *rdata;
};
Structure of a Query
typedef struct
{
unsigned char *name;
struct question *ques;
} QUERY;
int main (int argc, char *argv[])
{
unsigned char hostname[100];
Get the DNS servers from the resolv.conf file
Get_dns_servers ();
Get the hostname from the terminal
printf ("Enter Hostname to Lookup:");
scanf ("%s", hostname);
Now get the IP of this hostname, A record
Ngethostbyname (hostname, t_a);
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
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 was 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 ...");
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 answer
i = sizeof dest;
printf ("\nreceiving answer ...");
if (Recvfrom (S, (char*) buf, 65536, 0, (struct sockaddr*) &dest, (socklen_t*) &i) < 0)
{
Perror ("Recvfrom failed");
}
printf ("Done");
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;
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 a 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)] = ';
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)]= ';
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
}
/*
*
* */
u_char* readname (unsigned char* reader,unsigned char* buffer,int* count)
{
unsigned char *name;
unsigned int p=0,jumped=0,offset;
int I, J;
*count = 1;
Name = (unsigned char*) malloc (256);
Name[0]= ' ";
Read the names in 3www6google3com format
while (*reader!=0)
{
if (*reader>=192)
{
offset = (*reader) *256 + * (reader+1)-49152; 49152 = 11000000 00000000;)
Reader = buffer + offset-1;
jumped = 1; We have jumped to another location so counting wont go up!
}
Else
{
Name[p++]=*reader;
}
reader = reader+1;
if (jumped==0)
{
*count = *count + 1; If we havent jumped to another location then we can count up
}
}
Name[p]= ' "; String complete
if (jumped==1)
{
*count = *count + 1; Number of steps we actually moved forward in the packet
}
//now convert 3www6google3com0 to www.google.com
for (i=0;i< (int) strlen ((const char*) name); i++)
{
p=name[i];
for (j=0;j< (int) p;j++)
{
name[i]=name[i+1];
i=i+1;
}
name[i]= '. ';
}
name[i-1]= ';//remove the last dot
return name;
}
/*
* get the DNS servers from/etc/resolv.conf file on Linux
* */
void get_dns_servers ()
{
file *FP;
char line[200], *p;
if ((fp = fopen ("/etc/resolv.conf", "r") = = NULL)
{
printf ("Failed opening/etc/ resolv.conf file \ n ");
}
while (fgets, FP)
{
if (line[0] = = ' # ')
{
continue;
}
if (line, nameserver, ten) = = 0)
{
p = strtok (line, ""); Br> p = Strtok (NULL, "");
//p The now is the DNS IP:)
//????
}
}
strcpy (dns_servers[0], "208.67.222.222");
strcpy (Dns_servers[1], "208.67.220.220");
}
/*
* This'll convert www.google.com to 3www6google3com
* Got it:)
* */
void Changetodnsnameformat (unsigned char* dns,unsigned char* host)
{
int lock = 0, I;
Strcat ((char*) host, ".");
for (i = 0; I < strlen ((char*) host); i++)
{
if (host[i]== '. ')
{
*dns++ = I-lock;
for (; lock<i;lock++)
{
*dns++=host[lock];
}
lock++; or lock=i+1;
}
}
*dns++= ' ";
}
Dns.c
Copy Code code as follows:
/*
* DNS Query Program on Linux
*
* author:ismdeep@live.com
*
* */
Header Files
#include <stdio.h>//printf
#include <string.h>//strlen
#include <stdlib.h>//malloc
#include <sys/socket.h>//you know what
#include <arpa/inet.h>//inet_addr, Inet_ntoa, Ntohs etc
#include <netinet/in.h>
#include <unistd.h>//getpid
List of DNS Servers registered on the system
Char dns_servers[10][100];
int dns_server_count = 0;
Types of DNS resource records:)
#define T_A 1//ipv4 Address
#define T_NS 2//nameserver
#define T_CNAME 5//canonical name
#define T_SOA 6/* Start of authority zone * *
#define T_PTR/* Domain name pointer * *
#define T_MX//mail Server
Function prototypes
void Ngethostbyname (unsigned char*, int);
void Changetodnsnameformat (unsigned char*,unsigned char*);
unsigned char* readname (unsigned char*,unsigned char*,int*);
void Get_dns_servers ();
DNS Header Structure
struct Dns_header
{
unsigned short ID; Identification number
unsigned char rd:1; Recursion desired
unsigned char tc:1; Truncated message
unsigned char aa:1; Authoritive answer
unsigned char opcode:4; Purpose of Message
unsigned char qr:1; Query/response Flag
unsigned char rcode:4; Response code
unsigned char cd:1; Checking disabled
unsigned char ad:1; Authenticated data
unsigned char z:1; Its z! Reserved
unsigned char ra:1; Recursion available
unsigned short q_count; Number of question entries
unsigned short ans_count; Number of answer entries
unsigned short auth_count; Number of authority entries
unsigned short add_count; Number of resource entries
};
Constant sized fields of query structure
struct question
{
unsigned short qtype;
unsigned short qclass;
};
Constant sized fields of the resource record structure
#pragma pack (push, 1)
struct R_data
{
unsigned short type;
unsigned short _class;
unsigned int ttl;
unsigned short data_len;
};
#pragma pack (POP)
Pointers to resource record contents
struct Res_record
{
unsigned char *name;
struct R_data *resource;
unsigned char *rdata;
};
Structure of a Query
typedef struct
{
unsigned char *name;
struct question *ques;
} QUERY;
int main (int argc, char *argv[])
{
unsigned char hostname[100];
Get the DNS servers from the resolv.conf file
Get_dns_servers ();
Get the hostname from the terminal
printf ("Enter Hostname to Lookup:");
scanf ("%s", hostname);
Now get the IP of this hostname, A record
Ngethostbyname (hostname, t_a);
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
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 was 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 ...");
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 answer
i = sizeof dest;
printf ("\nreceiving answer ...");
if (Recvfrom (S, (char*) buf, 65536, 0, (struct sockaddr*) &dest, (socklen_t*) &i) < 0)
{
Perror ("Recvfrom failed");
}
printf ("Done");
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;
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 a 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)] = ';
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)]= ';
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
}
/*
*
* */
u_char* readname (unsigned char* reader,unsigned char* buffer,int* count)
{
unsigned char *name;
unsigned int p=0,jumped=0,offset;
int I, J;
*count = 1;
Name = (unsigned char*) malloc (256);
Name[0]= ' ";
Read the names in 3www6google3com format
while (*reader!=0)
{
if (*reader>=192)
{
offset = (*reader) *256 + * (reader+1)-49152; 49152 = 11000000 00000000;)
Reader = buffer + offset-1;
jumped = 1; We have jumped to another location so counting wont go up!
}
Else
{
Name[p++]=*reader;
}
reader = reader+1;
if (jumped==0)
{
*count = *count + 1; If we havent jumped to another location then we can count up
}
}
Name[p]= ' "; String complete
if (jumped==1)
{
*count = *count + 1; Number of steps we actually moved forward in the packet
}
//now convert 3www6google3com0 to www.google.com
for (i=0;i< (int) strlen ((const char*) name); i++)
{
p=name[i];
for (j=0;j< (int) p;j++)
{
name[i]=name[i+1];
i=i+1;
}
name[i]= '. ';
}
name[i-1]= ';//remove the last dot
return name;
}
/*
* get the DNS servers from/etc/resolv.conf file on Linux
* */
void get_dns_servers ()
{
file *FP;
char line[200], *p;
if ((fp = fopen ("/etc/resolv.conf", "r") = = NULL)
{
printf ("Failed opening/etc/ resolv.conf file \ n ");
}
while (fgets, FP)
{
if (line[0] = = ' # ')
{
continue;
}
if (line, nameserver, ten) = = 0)
{
p = strtok (line, ""); Br> p = Strtok (NULL, "");
//p The now is the DNS IP:)
//????
}
}
strcpy (dns_servers[0], "208.67.222.222");
strcpy (Dns_servers[1], "208.67.220.220");
}
/*
* This'll convert www.google.com to 3www6google3com
* Got it:)
* */
void Changetodnsnameformat (unsigned char* dns,unsigned char* host)
{
int lock = 0, I;
Strcat ((char*) host, ".");
for (i = 0; I < strlen ((char*) host); i++)
{
if (host[i]== '. ')
{
*dns++ = I-lock;
for (; lock<i;lock++)
{
*dns++=host[lock];
}
lock++; or lock=i+1;
}
}
*dns++= ' ";
}