关于我们 广告服务 社区论坛
设为首页 加入收藏

行业新闻
服 务 器
模版下载
建站指南
冲浪宝典
办公软件
网站运营
操作系统
QQ 专题
网页制作
安全防御
视频教程
网络编程
SEO专区
软件下载
图像设计
Cisco
网页特效
Wap 技术
联盟赚钱
网页素材
 首页 | 企业建站 | 网页制作 | 网站运营 | 网络编程 | 图像设计 | 冲浪宝典 | 操作系统 | SEO专区 | 联盟赚钱 | Cisco

欢迎来到e天下网络首页>>服务器>>Dns服务器>>正文|Dns解析(下)

Dns解析(下)

[ 来路:21kn.com    时间:2007-7-11 15:20:06    点击: ]

 

Dns解析()

上篇讲述了Dns的查询包和发送,本文将分析Dns的返回包。

下面这段程序是从Dns服务器上得到dns的返回包:

ID_Packet=new DatagramPacket(new byte[Constant.DNSUDPLEN],

Constant.DNSUDPLEN);

ID_Socket.receive(ID_Packet);

这里的变量已在上篇中定义了,Constant.DNSUDPLEN512

接下来就只要将这数据解压缩就可以了。这里就涉及了RR的格式了(Resource Record Format)。

     0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                                               |
    /                                               /
    /                      NAME                     /
    |                                               |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                      TYPE                     |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                     CLASS                     |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                      TTL                      |
    |                                               |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                   RDLENGTH                    |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--|
    /                     RDATA                     /
    /                                               /
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+

这是在rfc文档中定义的RR格式。

NAME:就是在question中的QNAME

TYPEquestion中的QTYPE

CLASSquestion中的QCLASS

RDLENGTHRDATA的长度;

RDATA:返回的数据,这才是真正有用的数据,也是我们要解析的东西。

 

因为其数据是被压缩的,所以得想知道他的压缩格式:

0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    | 1  1|                OFFSET                   |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+

他的压缩方式是将在数据中重复出现的字符放在一起,然后再字符出现的地方加上一个偏移位置,即如上图所示,16位的数据以11开头,后跟偏移量。偏移量是从信息的头部开始算得。下面是一个rfc文档中的例子:

0  1   2   3   4  5  6  7   8  9  A   B  C  D  E  F

       +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    20 |           1           |           F           |
       +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    22 |           3           |           I           |
       +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    24 |           S           |           I           |
       +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    26 |           4           |           A           |
       +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    28 |           R           |           P           |
       +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    30 |           A           |           0           |
       +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
 
       +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    40 |           3           |           F           |
       +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    42 |           O           |           O           |
       +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    44 | 1  1|                20                       |
       +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
   

这个结果是:在40位置的域名是FOO.F.ISI.ARPA

了解了他的压缩方式,解析就简单了。

上篇中在Header中我们已提到ANCOUNT这个字段,他表示的是回复中结果的数目,我们相见他解析出来:

public int getAnswerCount()

    {

        int INDEX=6;

        byte[] AnCountArray=new byte[2];

       

        System.arraycopy(message,INDEX,AnCountArray,0,2);

        return DnsTool.BytesToInt(AnCountArray);//byte[]变为int

    }

得到了ANCOUNT,就可以解释结果了:

public Vector parseAnswer()

    {

        int theOffset=8;

        int pos=thePosOfAnswer;(thePosOfAnswer是你发得dns包的长度)

        int i=0,p;

        int RDlength;

        byte[] tmp;

        String Name="";

Vector IV_ Answer=new Vector();

       

        //get return name from message

        while(i<getAnswerCount())

        {

            Name="";

            //get type

            pos+=2;

            tmp=new byte[2];

            System.arraycopy(message,pos,tmp,0,2);

           

            if(DnsTool.BytesToInt(tmp)==Constant.TYPE_MX)//check the type

            {

                pos+=theOffset;

                //get RDlength

                tmp=new byte[2];

                System.arraycopy(message,pos,tmp,0,2);

                RDlength=DnsTool.BytesToInt(tmp);

               

                pos+=4;

                p=pos;

                while((pos-p)<RDlength-2)

                {

                    if((message[pos]&0xC0)==0xC0)

                    {

                        //this is a offset

                        Name+=getPrior((message[pos]&0x3F)

|(message[pos+1]&0xFF));

                        pos+=2;

                    }

                    else

                    {

                        //not offset

                        tmp=new byte[message[pos]];

                        System.arraycopy(message,pos+1,tmp,0,tmp.length);

                        pos+=message[pos]+1;

                       

                        if(message[pos]!=0)

                            Name+=new String(tmp)+".";

                        else

                            Name+=new String(tmp);

                    }

                }

            }

         IV_Answer.addElement(Name);  

         i++;  

        }

    }

函数Stirng getPrior(int)是根据其偏移量等到所要的字符串,这是一个递归函数:

private String getPrior(int j)

    {

        byte[] tmp;

        String Name="";

       

        while(message[j]!=0)

        {

            if((message[j]&0xC0)==0xC0)

            {

                String mid=getPrior((message[j]&0x3F)|(message[j+1]&0xFF));

                Name+=mid;

                j+=mid.length()+1;

            }

            else

            {

                tmp=new byte[message[j]];

                System.arraycopy(message,j+1,tmp,0,tmp.length);

                j+=message[j]+1;

                if(message[j]!=0)

                    Name+=new String(tmp)+".";

                else

                    Name+=new String(tmp);

            }

        }

        return Name;

    }

我们只介绍了mail地址的dns解析,其他几类都大同小异,如需要可参考rfc1035

文章不免有错,请各位多指点craks@263.net

 


::::站长友情提示:多花一分钟学点什么都好::::

 

上一篇:Dns解析(上)  下一篇:DSP v1.0--序列化和反序列化对象和DNS v1.0--得到域的邮件服务器

 ::热点信息::

 

= = 免责声明 = =

① 欢迎转载我网所刊信息,请注明“来源:E天下网络”。
② 凡本网注明“来源:XXX(非E天下网络)”的作品,均转载自其它媒体,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。如因作品内容、版权和其它问题需要同本网联系的,请在30日内进行。
※联系方式:Airtofly@163.com

::推荐文章::

 

Win 2000中DNS服务器的设置

::视频教程::

 

Photoshop Dreamweaver
Flash MX Fireworks
Office AutoCAD
FrontPage CORELDRAW
用Dreamweaver开发ASP—建立
用Dreamweaver开发ASP—建立
用Dreamweaver开发ASP—建立
用Dreamweaver开发ASP—高级
用Dreamweaver开发ASP—限制
用Dreamweaver开发ASP—删除
用Dreamweaver开发ASP—修改
用Dreamweaver开发ASP—显示
更多内容..

 

 

关于我们 广告服务 友情链接 合作伙伴 社区论坛 免责声明

Copyright © 2007   21kn.com Inc. All rights reserved.e天下网络工作室

网站白天客服QQ:26875416 (非24小时)  合作QQ:597004688    粤ICP备06026423号