DNS 协议包含不同类型的 DNS 消息根据其邮件域中的信息来处理的。 本节讨论的 DNS 消息类型以及每种消息类型中的字段。
在此部分中,讨论了下列 DNS 邮件主题:
有三种类型的 DNS 消息:
查询和响应中的原始 DNS 标准,定义和 RFC 2136 中定义的更新。 所有三种类型按照常见的邮件格式。
常见的 DNS 邮件格式具有固定长度、 12 字节的标头和变量的位置,保留的问题、 答案、 授权和其他 DNS 资源记录。 常见的邮件格式如下所示:
标准 DNS 查询邮件格式
DNS 邮件格式 |
---|
DNS 标头 (固定长度) |
问题的条目 (可变长度) |
应答资源记录 (可变长度) |
颁发机构资源记录 (可变长度) |
其他资源记录 (可变长度) |
DNS 消息标头包含以下字段,按以下顺序:
DNS 查询消息标头字段
字段名称 | 说明 |
---|---|
事务 ID |
16 位字段,用于标识一个特定的 DNS 事务。 事务 ID 创建的邮件原始发件人,并复制到其响应消息的响应情况。 使用事务 ID,DNS 客户端可以匹配其请求的响应。 |
标志: |
包含 DNS 客户端和 DNS 服务器之间通讯的各种服务标志的 16 位字段包括: |
请求/响应 |
1 位字段设置为 0,则表示名称服务请求,或者设置为 1,以表示名称服务的响应。 |
操作代码 |
4 位字段表示数据包的名称服务操作: 0x0 是一个查询。 |
权威性应答 |
1 位字段表示响应方是查询消息中的域名具有权威性。 |
截断 |
如果响应总数超过用户数据报协议 (UDP) 数据报被设置为 1 的 1 位字段。 除非启用了 UDP 数据报大于 512 字节或 EDNS0,只有第一个 512 字节的 UDP 答复返回。 |
所需的递归 |
1 位字段设置为 1 以指示递归查询,并且对于迭代查询 0。 如果 DNS 服务器收到查询消息与该域设置为 0 时,它将返回客户端可以联系其他 DNS 服务器的列表。 此列表是从本地缓存数据填充的。 |
可用的递归 |
1 位设置字段 1 以表示一个 DNS 服务器的 DNS 服务器可以处理针对递归查询。 如果禁用递归,则 DNS 服务器将适当地设置的字段。 |
保留 |
3 位字段是保留,设置为 0。 |
返回代码 |
4 位字段中保存的返回代码:
|
试题资源记录计数 |
16 位字段代表 DNS 消息中的问题一节中的条目数。 |
应答资源记录计数 |
16 位字段代表 DNS 消息的应答部分中的条目数。 |
颁发机构资源记录计数 |
16 位字段代表的 DNS 消息中的颁发机构资源记录数。 |
其他资源记录计数 |
16 位字段表示 DNS 消息中的其他资源记录的数目。 |
DNS 消息的问题项部分包含的域名称,被查询,并且具有以下三个字段:
DNS 查询问题输入字段
字段名称 | 说明 |
---|---|
问题名称 |
正在查询的域名。 DNS 域名称的表示为一系列的标签,如 microsoft.com,但在问题名称字段中的域名称被编码为一系列的长度-值对包含 1 字节的文件,指示该值,跟值 (标签) 的长度。 例如,域 microsoft.com 表示为0x09microsoft0x03com0x00,其中十六进制数字表示每个标签的长度、 ASCII 字符表示单个标签,并最终 0 指示名称的结尾。 |
问题类型 |
16 位整数,用于表示应返回的资源记录类型,如下面来表示: |
类型值 |
返回的记录 |
0x01 |
主机 (A) 记录 |
0x02 |
名称服务器 (NS) 记录 |
0x05 |
别名 (CNAME) 记录 |
0x0C (12) |
反向搜索 (PTR) 记录 |
0x0F (15) |
邮件交换 (MX) 记录 |
0x21 (33) |
服务 (SRV) 记录 |
0xFB (251) |
增量区域传输 (IXFR) 记录 |
0xFC (252) |
标准的区域传输 (AXFR) 记录 |
0xFF (255) |
所有记录 |
问题类别 |
代表 IN (Internet) 问题类并且通常设置为 0x0001。 |
答案、 授权和 DNS 响应消息的部分可以包含应答的查询消息问题部分的资源记录的其他信息。 资源记录的格式如下:
DNS 资源记录的消息字段
字段名称 | 说明 |
---|---|
资源记录名称 |
为可变长度字段后面与问题名称字段相同的格式记录的 DNS 域名。 |
资源记录类型 |
资源记录类型值。 |
资源记录类 |
资源记录类代码,互联网类,0x0001。 |
生存时间 |
将秒显示为一个 32 位无符号字段以表示 TTL。 |
资源数据长度 |
2 字节指示资源数据的长度字段。 |
资源数据 |
对应于该资源记录的可变长度数据类型。 |
除非名称已存在 DNS 消息,此时 2 字节的字段来代替一个长度值编码名称和充当一个指针,指向已存在的名称中的其他地方,资源记录名称字段进行编码问题名称字段的方式相同。
名称查询邮件格式是上面所述的 DNS 消息格式相同。 在典型的名称查询邮件中,设置 DNS 消息字段如下:
DNS 名称查询消息字段
字段名称 | 说明 |
---|---|
查询标识符 (事务 ID) |
若要启用 DNS 客户端解析程序以匹配对查询的响应,将设置为一个唯一的编号。 查询响应事务 ID 始终匹配查询请求事务 id。 |
标志 |
设置以启用递归指示一个标准查询。 |
试题计数 |
设置为 1。 |
问题条目 |
返回设置为查询的域名和资源记录类型。 |
名称查询响应邮件格式是上面所述的 DNS 消息格式相同。 在典型的名称查询邮件中,将按以下方式设置 DNS 消息字段:
DNS 名称查询响应字段
字段名称 | 说明 |
---|---|
查询标识符 (事务 ID) |
若要启用 DNS 客户端解析程序以匹配对查询的响应,将设置为一个唯一的编号。 |
标志 |
设置以启用递归指示一个标准查询。 |
试题计数 |
设置为 1。 |
问题条目 |
返回设置为查询的域名和资源记录类型。 |
反向名称查询邮件使用常见的邮件格式具有以下区别:
利用 DNS 更新格式使用标头定义更新操作执行的消息和一个包含更新的资源记录集。 利用 DNS 更新消息格式包含了以下字段:
利用 DNS 更新邮件标志字段使用了以下标志:
结果代码值 | 说明 |
---|---|
0 (NOERROR) |
没有错误;成功的更新。 |
1 (FORMERR) |
格式错误。DNS 服务器不理解更新请求。 |
0X2 (SERVFAIL) |
DNS 服务器遇到内部错误,如转发超时。 |
0X3 (NXDOMAIN) |
应该存在的名称不存在。 |
0X4 (NOTIMP) |
DNS 服务器不支持指定的操作代码。 |
0X5 (拒绝) |
DNS 服务器将拒绝执行更新。 |
0X6 (YXDOMAIN) |
不应存在的名称确实存在。 |
0X7 (YXRRSET) |
不应存在的资源记录集不存在。 |
0X8 (NXRRSET) |
应存在的资源记录集不存在。 |
0X9 (NOTAUTH) |
无法在区域部分中命名该区域的权威 DNS 服务器。 |
0XA (NOTZONE) |
系统必备组件或更新部分中使用的名称不是通过区域部分中指定的区域内。 |
动态更新响应消息遵循相同的格式如 DNS 更新消息,DNS 标志的除外。 动态更新的响应消息标头标志指示更新是否成功通过包括成功的响应代码或 DNS 更新邮件标志中所述的错误代码之一。
所有的DNS,不论是发送和接收到,都遵循相同的消息格式,如
其中消息头部的格式比较固定,如下:
在填充和解析报文的时候,必须注意,这里报文所有的数据格式都是大端格式,而且协议描述的flag部分非常容易出错,必须予以强调。
假设QR=1,其他为0,那么这个字节的值为0x80;如果RD=1,而其他为0,那么这个字节的值为0x01。我们假设QR字段到RCODE字段的这两个字节中,QR=1,RD=1,RC=1,其他部分都是0,那么这2个字节的值为0x81 , 0x80。
仔细理解上面这段描述,才能理解各个标志位的含义。
HEADER中的QDCOUNT只是question节的数量,ANCOUNT为answer节的数量,NSCOUNT为auth节的数量,ARCOUNT为addition节的数量。这几个2字节构成的整型也是大端格式。
question主要是由客户端请求来填的,他的格式为
一般来说QTYPE如果是域名解析的话,为T_A =1 ,当然也有T_MX(mail exchange)。在所以名称字段,比较特殊,比如这里的QNAME,其他以字符串形式出现的都是一样的规则。
比如www.csdn.net,他会编成这样的形式:
0x03 0x77 0x77 0x77 0x04 0x63 0x73 0x64 0x6e 0x03 0x6e 0x65 0x74 0x00
和其他字符串一样,这个格式仍然以0x00结尾,不过中间确实不同,他是len + data来混合编码,每个字符串都是以长度开始,然后接着内容。比如"www",他的字符值为0x77 , 在前头是0x03开始,表示后面紧跟着3个字符。
还有一种格式,是使用指针,准确地说应该是偏移量,如下:
0xc0 0x0c 0x00 0x01 0x00 0x01 0x00 0x00 0x02 0x1a 0x00 0x04
这个是DNS服务端返回报文中地一段。0xc0开头,表示这个是指针,后面字节跟着地是偏移量。这个偏移量应该是这样计算的:0xc0 & (~0xc0),这样得到偏移量的高字节,然后和0x0c拼接成一个大端格式短整型。这偏移量是相对于报文起点的偏移量。
我打个比方,比如偏移量超过256,是300 ,他的小端格式为0x012c,那么他在内存中的印象应该是这样的:
0xc1 0x2c。
ANSWER/AUTH/ADDS的几个报文格式都是一样:
只需要关注的是,每个TYPE都会有自己格式填充在RDATA中,RDATA实际上存放的是一个缓冲区。根据具体TYPE,来解析他的含义,一般说来,我们比较关注的A/CNAME/MX等格式,其他都可以忽略。