DNS 协议分析
DNS_协议报文格式
一、Header
(1)会话标识(2字节)
-
是DNS报文的ID标识,对于请求报文和其对应的应答报文,这个字段是相同的,通过它可以区分DNS应答报文是哪个请求的响应。
-
长度为16位,是一个用户发送查询的时候定义的随机数,当服务器返回结果的时候,返回包的ID与用户发送的一致
(2)标志(2字节)
QR(1bit) : 查询/响应标志,0 为查询,1 为响应
Opcode(4bit) : 0表示标准查询,1 表示反向查询,2 表示服务器状态请求
AA(1bit) : 授权回答,表示是否是权威服务器 - (Answer)。
TC(1bit) : 表示响应是否已超过512字节,被截断。
RD(1bit) : 1表示客户端希望得到递归回答。
RA(1bit) : 服务器是否能递归解析 - (Answer)。
Zero (3bit):保留字段。
RCode(4bit) : 表示返回码 - (Answer)。
(0表示没有差错,1表示格式差错、2表示服务器错误、3表示名字差错、4表示查询类型不支持、5表示在管理上被禁止)
二、Queries区域
长度16位,报文请求段中的问题记录数
(1)查询名
长度不固定,且不使用填充字节,一般该字段表示的就是需要查询的域名(如果是反向查询,则为IP,反向查询即由IP地址反查域名),一般的格式如下图所示。
(2)查询类型
enum QueryType //查询的资源记录类型。
{
A=0x01, //指定计算机 IP 地址。
NS=0x02, //指定用于命名区域的 DNS 名称服务器。
MD=0x03, //指定邮件接收站(此类型已经过时了,使用MX代替)
MF=0x04, //指定邮件中转站(此类型已经过时了,使用MX代替)
CNAME=0x05, //指定用于别名的规范名称。
SOA=0x06, //指定用于 DNS 区域的“起始授权机构”。
MB=0x07, //指定邮箱域名。
MG=0x08, //指定邮件组成员。
MR=0x09, //指定邮件重命名域名。
NULL=0x0A, //指定空的资源记录
WKS=0x0B, //描述已知服务。
PTR=0x0C, //如果查询是 IP 地址,则指定计算机名;否则指定指向其它信息的指针。
HINFO=0x0D, //指定计算机 CPU 以及操作系统类型。
MINFO=0x0E, //指定邮箱或邮件列表信息。
MX=0x0F, //指定邮件交换器。
TXT=0x10, //指定文本信息。
UINFO=0x64, //指定用户信息。
UID=0x65, //指定用户标识符。
GID=0x66, //指定组名的组标识符。
ANY=0xFF //指定所有数据类型。
};
(3)指定信息的协议组
Question class:长度为16位,表示分类。
enum QueryClass //指定信息的协议组。
{
IN=0x01, //指定 Internet 类别。
CSNET=0x02, //指定 CSNET 类别。(已过时)
CHAOS=0x03, //指定 Chaos 类别。
HESIOD=0x04,//指定 MIT Athena Hesiod 类别。
ANY=0xFF //指定任何以前列出的通配符。
};
一个实际查询www.ifeng.com的请求包:
三、资源记录(RR)区域
(包括回答区域,授权区域和附加区域)
三个区域分别是:回答区域,授权区域和附加区域
域名(2字节或不定长):
-
它的格式和Queries区域的查询名字字段是一样的。有一点不同就是,当报文中域名重复出现的时候,该字段使用2个字节的偏移指针来表示。
-
比如,在资源记录中,域名通常是查询问题部分的域名的重复,因此用2字节的指针来表示,具体格式是最前面的两个高位是 11,用于识别指针。
-
其余的14位从DNS报文的开始处计数(从0开始),指出该报文中的相应字节数。一个典型的例子,C00C(1100000000001100,12正好是头部的长度,其正好指向Queries区域的查询名字字段)。
查询类:
- 对于Internet信息,总是IN
生存时间(TTL):
- 以秒为单位,表示的是资源记录的生命周期,一般用于当地址解析程序取出资源记录后决定保存及使用缓存数据的时间,它同时也可以表明该资源记录的稳定程度,极为稳定的信息会被分配一个很大的值(比如86400,这是一天的秒数)。
资源数据(RD):
- 该字段是一个可变长字段,表示按照查询段的要求返回的相关资源记录的数据。可以是Address(表明查询报文想要的回应是一个IP地址)或者CNAME(表明查询报文想要的回应是一个规范主机名)等。
四、DNS响应包
响应包也有一个与请求包相同格式,都是固定12字节的头部。
每个answer的结构包括:name, type, class, TTL, data length, data
其余部分包括
**Queries: ** 查询的问题(与请求包中的一样)
Answers:查询的问题的回答
Authoritative nameservers: 一些域名服务器(应该是与该本次查询有关的吧)
name (2字节) :
c0 0c , c0表示后面的一个字节是一个偏移地址,该偏移地址中存储了一个名字,这样表示是为了节约空间,不过也增加了 复杂性。
type, class(各两字节):与前面描述相同
TTL(4字节):表示查询的地址的有效时间
data length(2字节):后面数据部分的长度
data:一个域名(查询域名的一个别名)或一个IP地址