当前位置:  编程技术>c/c++/嵌入式

linux中查询dns示例

    来源: 互联网  发布时间:2014-10-25

    本文导语:  dns.c 代码如下:/* * DNS Query Program on Linux * * Author : ismdeep@live.com * * *///Header Files#include //printf#include //strlen#include //malloc#include //you know what this is for#include //inet_addr , inet_ntoa , ntohs etc#include#include //getpid //List of DNS Servers regi...

dns.c

代码如下:

/*
 * DNS Query Program on Linux
 *
 * Author : ismdeep@live.com
 *
 * */
//Header Files
#include //printf
#include //strlen
#include //malloc
#include //you know what this is for
#include //inet_addr , inet_ntoa , ntohs etc
#include
#include //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 12 /* domain name pointer */
#define T_MX 15 //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 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...");
 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.nn",ntohs(dns->add_count));

 //Start reading answers
 stop=0;

 for(i=0;ians_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 ; jdata_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;iauth_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;iadd_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;jdata_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;iopcode = 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...");
 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.nn",ntohs(dns->add_count));

 //Start reading answers
 stop=0;

 for(i=0;ians_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 ; jdata_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;iauth_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;iadd_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;jdata_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


    
 
 

您可能感兴趣的文章:

  • Linux c++虚函数(virtual function)简单用法示例代码
  • linux下运行libnids那个自带的示例程序printall,有点问题
  • linux c 生成随机数srand函数和rand函数介绍及代码示例
  • linux下怎样修改DNS相关的文件? iis7站长之家
  • Linux系统命令:find(文件查找命令)介绍及用法示例
  • linux使用shell脚本,如何创建用户,并设置用户密码?能否给出示例?
  • 诚求<<LINUX编程宝典>>的示例代码!!!
  • unp(unix network programming)中的示例是针对 BSD 的,如何移植到 LINUX 上来?
  • 谁有《linux设备驱动程序》书的示例代码,发给我好么?
  • linux c 获得当前进程的进程名和执行路径(示例)
  • linux增加iptables防火墙规则的示例
  • 问一个《linux设备驱动程序第三版》第二章中运行那个示例模块的问题
  • linux下php与php-fpm安装配置示例
  • linux生成(加载)动态库静态库和加载示例方法
  • linux获取系统启动时间示例详解
  • linux获取进程执行时间方法示例
  • Linux网络编程之UDP Socket程序示例
  • Linux网络编程之socket文件传输示例
  • Linux网络编程之基于UDP实现可靠的文件传输示例
  • linux命令详解date使用方法(计算母亲节和父亲节日期脚本示例)
  • 利用linux的timerfd_create实现计时器示例分享
  • 问个比较菜的问题: LINUX如何查询C函数的使用方法?
  • 请问在linux下面编程怎样查询stl类的成员函数
  • linux编程时候,要查询某个系统调用的库函数,如何查?
  • 在linux系统中如何查询自己的ip地址?我用的是adsl上网,因此....
  • 如何查询Linux系统下是否装了gcc编译器?
  • linux下将查询的内容保存到.txt文本文件中.
  • linux内核和版本查询命令
  • linux下通过对文件读取方式查询oracle的版本信息
  • Linux,aix,windows下可以查询非本进程的信号处理函数吗?
  • 在LINUX系统中如果网络设备没有中断的话,可以通过查询接收包吗?谢谢!
  •  
    本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
    本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐
  • LINUX下DNS的设置问题
  • Debian Linux如何架设DNS服务器
  • 请教各位高手关于Linux下的DNS解析问题?
  • Linux 下设置拨号上网,DNS 项怎么设?
  • linux中DNS的问题
  • Linux环境下DNS配置
  • 求linux下能用的dns的ip地址
  • linux中dns老是连接不上
  • Linux的DNS正向成功,反向解析失败,望指教!
  • LINUX DNS SERVER 配置问题
  • 关于LINUX下DNS配置 (均衡负载)
  • fedora linux下如何配置DNS
  • linux下面架设的dns服务器
  • Linux下ADSL的DNS问题.
  • linux下怎样修改DNS相关的文件?
  • linux 域名解析问题(dns)
  • 急!!!!!!!!!!!!Linux下部署DNS和sendmail的问题??????????
  • linux系统加入网络中的DNS服务
  • 怎样添加或更改DNS(linux版本为7.3)
  • Oracle Enterprise Linux dns问题
  • linux c/c++ IP字符串转换成可比较大小的数字
  • 在win分区上安装linux和独立分区安装linux有什么区别?可以同时安装吗?(两个linux系统)
  • linux哪个版本好?linux操作系统版本详细介绍及选择方案推荐
  • 在虚拟机上安装的linux上,能像真的linux系统一样开发linux程序么?
  • secureCRT下Linux终端汉字乱码解决方法
  • 我重装window后,把linux的引导区覆盖了,进不了linux怎么办?急啊,望热心的人帮助 (现在有linux的盘)
  • Linux c字符串中不可打印字符转换成16进制
  • 安装vmware软件,不用再安装linux系统,就可以模拟linux系统了,然后可以在其上学习一下LINUX下的基本操作 了?
  • Linux常用命令介绍:更改所属用户群组或档案属性
  • 红旗Linux主机可以通过127.0.0.1访问,但如何是连网的Win2000机器通过Linux的IP去访问Linux
  • linux命令大全详细分类介绍及常用linux命令文档手册下载




  • 特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3