DNS数据包解析.docx

上传人:b****2 文档编号:1944482 上传时间:2023-05-02 格式:DOCX 页数:8 大小:17.21KB
下载 相关 举报
DNS数据包解析.docx_第1页
第1页 / 共8页
DNS数据包解析.docx_第2页
第2页 / 共8页
DNS数据包解析.docx_第3页
第3页 / 共8页
DNS数据包解析.docx_第4页
第4页 / 共8页
DNS数据包解析.docx_第5页
第5页 / 共8页
DNS数据包解析.docx_第6页
第6页 / 共8页
DNS数据包解析.docx_第7页
第7页 / 共8页
DNS数据包解析.docx_第8页
第8页 / 共8页
亲,该文档总共8页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

DNS数据包解析.docx

《DNS数据包解析.docx》由会员分享,可在线阅读,更多相关《DNS数据包解析.docx(8页珍藏版)》请在冰点文库上搜索。

DNS数据包解析.docx

DNS数据包解析

仔细看了看DNS协议的相关东西,其实实际编程的时候根本用不到DNS细节的东西,要获取域名的时候经终端下用host或者nslookup指令就可以,在c里面使用gethostbyname或者getaddrinfo都能很轻松得将dns域名解析为ip地址,写这个纯粹出于个人兴趣,或者说是闲得吧。

在进行域名解析的时候,解析程序向域名服务器发起请求,域名服务器也就是在操作系统网络配置的时候写进去的那个DNS服务器地址,或者也有可能是由ISP提供的自动获取的,原理都一样,域名服务器收到请求后进行处理,首先在本地缓存中查找对应的域名,找到后将IP地址直接返回,找不到就向其它的授权服务器请求数据,又可以分为著名的递归查询和非递归查询。

递归查询就是说自始至终都由一台域名服务器进行查询,它在自己这里找不到的时候会向其它的域名服务器请求并且获取数据,然后返回给请求方。

非递归查询是指域名服务器收到请求后,如果自己有这个域名的信息就返回,如果没有就返回其它域名服务器的指针,请求方再根据这些域名服务器再发起查询。

按自己的理解瞎扯了一通,也不知道准不准确,关于DNS的相关资料网上有的是,中文的都大批大批的。

DNS服务器的原理其实没什么好说的,每天都在跟DNS打交道,但DNS的协议在实现上还是稍微有点意思的,本来想写个程序来测试一个我所了解的DNS协议,后来在写的时候还真发现一个小问题,DNS域名有时候会是一个主域名的别名,比如,它就是这个域名的别名,在DNS请求发送过去之后,response里面会有一个类型为CNAME的Answers项,里面包含了主域名的相关信息(其实也就是主域名的名称和TTL),在这个应答消息里面可能会出现多个域名消息,比如每个Answers的第一个字段就是一个域名,当然为了减少数据包的容量,DNS系统对域名进行了压缩,同一个域名只会出现一次,其它的时候再出现的话就会用一个DNS指针表示。

比如域名:

在数据包中的表示是0377777705626169647503636f6d00

粗体的是长度,将域名中的点去掉,用长度来分隔域名,以0结束。

DNS允许的长度为0-63个字节,所以一个8位的长度最高两位都为0。

而如果此处域名重复出现,信令中便会用DNS指针代替长度,指针为两个字节,16位的最位都为1,剩下的14位表示在在整个数据包中的偏移量,当程序读取到c00c的时候很容易判断它是一个指针而不是一个长度字段,于是根据c00c指向的领移量,即从数据包开始后的第12个字节,跳转过去读取出域名信息。

 

#include

#include

#include

#include

#include

#include

#include

#include

#defineDNS_SVR"211.68.71.4"

#defineDNS_HOST0x01

#defineDNS_CNAME0x05

intsocketfd;

structsockaddr_indest;

staticvoid

send_dns_request(constchar*dns_name);

staticvoid

parse_dns_response();

/**

*GenerateDNSquestionchunk

*/

staticvoid

generate_question(constchar*dns_name

                ,unsignedchar*buf,int*len);

/**

*Checkwhetherthecurrentbyteis

*adnspointeroralength

*/

staticint

is_pointer(intin);

/**

*Parsedatachunkintodnsname

*@paramchunkThecompleteresponsechunk

*@paramptrThepointerpointstodata

*@paramoutThiswillbefilledwithdnsname

*@paramlenThiswillbefilledwiththelengthofdnsname

*/

staticvoid

parse_dns_name(unsignedchar*chunk,unsignedchar*ptr

                ,char*out,int*len);

intmain(intargc,char*argv[]){

        if(argc!

=2){

                printf("Usage:

%s\n",argv[0]);

                exit(-1);

        }

        socketfd=socket(AF_INET,SOCK_DGRAM,0);

        if(socketfd<0){

                perror("createsocketfailed");

                exit(-1);

        }

        bzero(&dest,sizeof(dest));

        dest.sin_family=AF_INET;

        dest.sin_port=htons(53);

        dest.sin_addr.s_addr=inet_addr(DNS_SVR);

        send_dns_request(argv[1]);

        parse_dns_response();

        return0;

}

staticvoidparse_dns_response(){

        unsignedcharbuf[1024];

        unsignedchar*ptr=buf;

        structsockaddr_inaddr;

        char*src_ip;

        intn,i,flag,querys,answers;

        inttype,ttl,datalen,len;

        charcname[128],aname[128],ip[20],*cname_ptr;

        unsignedcharnetip[4];

        size_taddr_len=sizeof(structsockaddr_in);

        n=recvfrom(socketfd,buf,sizeof(buf),0

                ,(structsockaddr*)&addr,&addr_len);

        ptr+=4;/*moveptrtoQuestions*/

        querys=ntohs(*((unsignedshort*)ptr));

        ptr+=2;/*moveptrtoAnswerRRs*/

        answers=ntohs(*((unsignedshort*)ptr));

        ptr+=6;/*moveptrtoQuerys*/

        /*moveoverQuerys*/

        for(i=0;i

                for(;;){

                        flag=(int)ptr[0];

                        ptr+=(flag+1);

                        if(flag==0)

                                break;

                }

                ptr+=4;

        }

        printf("-------------------------------\n");

        /*nowptrpointstoAnswers*/

        for(i=0;i

                bzero(aname,sizeof(aname));

                len=0;

                parse_dns_name(buf,ptr,aname,&len);

                ptr+=2;/*moveptrtoType*/

                type=htons(*((unsignedshort*)ptr));

                ptr+=4;/*moveptrtoTimetolive*/

                ttl=htonl(*((unsignedint*)ptr));

                ptr+=4;/*moveptrtoDatalenth*/

                datalen=ntohs(*((unsignedshort*)ptr));

                ptr+=2;/*moveptrtoData*/

                if(type==DNS_CNAME){

                        bzero(cname,sizeof(cname));

                        len=0;

                        parse_dns_name(buf,ptr,cname,&len);

                        printf("%sisanaliasfor%s\n",aname,cname);

                        ptr+=datalen;

                }

                if(type==DNS_HOST){

                        bzero(ip,sizeof(ip));

                        if(datalen==4){

                                memcpy(netip,ptr,datalen);

                                inet_ntop(AF_INET,netip,ip,sizeof(structsockaddr));

                                printf("%shasaddress%s\n",aname,ip);

                                printf("\tTimetolive:

%dminutes,%dseconds\n"

                                                ,ttl/60,ttl%60);

                        }

                        ptr+=datalen;

                }

        }

        ptr+=2;

}

staticvoid

parse_dns_name(unsignedchar*chunk

                ,unsignedchar*ptr,char*out,int*len){

        intn,alen,flag;

        char*pos=out+(*len);

        for(;;){

                flag=(int)ptr[0];

                if(flag==0)

                        break;

                if(is_pointer(flag)){

                        n=(int)ptr[1];

                        ptr=chunk+n;

                        parse_dns_name(chunk,ptr,out,len);

                        break;

                }else{

                        ptr++;

                        memcpy(pos,ptr,flag);        

                        pos+=flag;

                        ptr+=flag;

                        *len+=flag;

                        if((int)ptr[0]!

=0){

                                memcpy(pos,".",1);

                                pos+=1;

                                (*len)+=1;

                        }

                }

        }

}

staticintis_pointer(intin){

        return((in&0xc0)==0xc0);

}

staticvoidsend_dns_request(constchar*dns_name){

        unsignedcharrequest[256];

        unsignedchar*ptr=request;

        unsignedcharquestion[128];

        intquestion_len;

        generate_question(dns_name,question,&question_len);

        *((unsignedshort*)ptr)=htons(0xff00);

        ptr+=2;

        *((unsignedshort*)ptr)=htons(0x0100);

        ptr+=2;

        *((unsignedshort*)ptr)=htons

(1);

        ptr+=2;

        *((unsignedshort*)ptr)=0;

        ptr+=2;

        *((unsignedshort*)ptr)=0;

        ptr+=2;

        *((unsignedshort*)ptr)=0;

        ptr+=2;

        memcpy(ptr,question,question_len);

        ptr+=question_len;

        sendto(socketfd,request,question_len+12,0

        ,(structsockaddr*)&dest,sizeof(structsockaddr));

}

staticvoid

generate_question(constchar*dns_name,unsignedchar*buf,int*len){

        char*pos;

        unsignedchar*ptr;

        intn;

        *len=0;

        ptr=buf;        

        pos=(char*)dns_name;

        for(;;){

                n=strlen(pos)-(strstr(pos,".")?

strlen(strstr(pos,".")):

0);

                *ptr++=(unsignedchar)n;

                memcpy(ptr,pos,n);

                *len+=n+1;

                ptr+=n;

                if(!

strstr(pos,".")){

                        *ptr=(unsignedchar)0;

                        ptr++;

                        *len+=1;

                        break;

                }

                pos+=n+1;

        }

        *((unsignedshort*)ptr)=htons

(1);

        *len+=2;

        ptr+=2;

        *((unsignedshort*)ptr)=htons

(1);

        *len+=2;

}

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 解决方案 > 学习计划

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2