分类: LINUX
2008-12-08 15:54:33
下边是DNS报文的大致格式:
+---------------------------+---------------------------+
| 标识 (最重要的 :) | 参数 |
+---------------------------+---------------------------+
| 问题数 | 回答数 |
+---------------------------+---------------------------+
| 管理机构数 | 附加信息数 |
+---------------------------+---------------------------+
| |
\ \
\ 问题 \
| |
+-------------------------------------------------------+
| |
\ \
\ 回答 \
| |
+-------------------------------------------------------+
| |
\ \
\ 附加信息(无关紧要) \
| |
+-------------------------------------------------------+
DNS报文结构
标识(id)
这是用来鉴证每个DNS报文的印记,由客户端设置,由服务器返回,它可以让客户匹
配请求与响应。
参数(flags)
参数域被分成好几个部份:
4 位 3 位,总是0
| |
| |
[QR | opcode | AA| TC| RD| RA | zero | rcode ]
|
| |__|__|__|__|__| |______ 4 位
| |_ 1 位
|
1 位
QR = 如果QR位设为0表示报为是查询,如果1则是响应
opcode = 通常是0,指标准查询,1是反向查询,2是服务器状态查询。
AA = 如果此位为1,表示服务器对问题部份的回答是权威性的。
TC = 截断,如果UDP包超过512字节将被截流
RD = 表示希望递归,如果它设为1的话,表示递归查询。
RA = 如果设为1,表示递归可用。
Zero = 如它的名称一样,总是0
rcode = 就象errno一样,0表示没有错误,3表示名字错误。
DNS查询报文:
下面是DNS报文查询的格式:
+--------------------------------------------------------------------+
| 查询名 |
+--------------------------------------------------------------------+
| 查询类型 | 查询类 |
+--------------------------------+-----------------------------------+
一个报文查询的结构是下面这样的
查询名是要查找的名字,它是一个或多个标识符的序列。每个标识符以首字节的计数值
来说明随后标识符的字节长度,每个名字以最后字节为0结束,长度为0的标识符是根标识符。
计数字节的值必须是0 ~ 6 3的数,因为标识符的最大长度仅为6 3(在本节的后面我们将看到计数字节的最高两比特为1,即值1 9 2 ~ 2 5 5,将用于压缩格式)。不像我们已经看到的许多其他报文格式,该字段无需以整32 bit边界结束,即无需填充字节。
示例:
是[3|w|w|w|5|h|e|i|k|e|3|c|o|m|0]
对IP地址来说,也是同样的;)
44.33.88.123.in-addr.arpa是:
[2|4|4|2|3|3|2|8|8|3|1|2|3|7|i|n|-|a|d|d|r|4|a|r|p|a|0]
还有一种压缩格式,但我们不需要用到,就略过了。
查询类型:
这里是一些我们最经常用到的查询类型——这些类型大约有20种不同的类型,我可懒得全部列出来了;)
名称 值
A | 1 | IP地址 (将域名解析为IP)
PTR | 12 | 指针 (将IP解析为域名)
DNS响应报文:
响应报文有个共同的格式,我们称之为资源记录——RR
下面是响应报文的格式(RR)
+--------------------------------------------------------------------+
| 域名 |
+--------------------------------------------------------------------+
| 类型 | 类 |
+----------------------------------+---------------------------------+
| TTL (生存时间) |
+--------------------------------------------------------------------+
| 资源数据长度 | |
|---------------------------+ |
| 资源数据 |
+--------------------------------------------------------------------
域名:
域名是与下面的资源数据对应的名字,它的格式同前面讲到的查询名一样,比如还是
吧,它的域名是用下面方式表现的:[3|w|w|w|5|h|e|i|k|e|3|c|o|m|0]
类型:
类型标识了RR类型代码号,它同前面讲到的查询类值一样。
类:
通常为1,表示因特网数据。
生存时间:
表示客户方将RR放在高速缓存里的时间,RRs的TTL通常为2天。
资源数据长度:
标识资源数据的大小。
下面我们将用一个简单的例子来帮助大家理解:
这个例子展示了当ns.bibi.com向ns.heike.com询问地址时,这些数据报文的模样。
ns.bibi.com:53 ---> [?] ----> ns.heike.com:53 (Phear Heike ;)
+---------------------------------+----------------------------------+
| 标识(ID) = 1999 | QR = 0 opcode = 0 RD = 1 |
+---------------------------------+----------------------------------+
| 问题数 = htons(1) | 回答数 = 0 |
+---------------------------------+----------------------------------+
| 管理机构数 = 0 | 附加信息数 = 0 |
+---------------------------------+----------------------------------+
<问题部份>
+-------------------------------------------------------------------+
| 查询名 = [3|w|w|w|5|h|e|i|k|e|3|c|o|m|0] |
+--------------------------------------------------------------------+
| 查询类型 = htons(1) | 查询类=htons(1) |
+---------------------------------+----------------------------------+
上面是查询报文
现在我们来看看ns.heike.com的回答
ns.heike.com:53 -->[IP of is 31.33.7.44] --> ns.bibi.com:53
+---------------------------------+----------------------------------+
| 标识(ID) = 1999 | QR=1 opcode=0 RD=1 AA =1 RA=1 |
+---------------------------------+---------------------------------+
| 问题数 = htons(1) | 回答数 = htons(1) |
+---------------------------------+----------------------------------+
| 管理机构数 = 0 | 附加信息数 = 0 |
+---------------------------------+----------------------------------+
+--------------------------------------------------------------------+
| 查询名 = [3|w|w|w|5|h|e|i|k|e|3|c|o|m|0] |
+--------------------------------------------------------------------+
| 查询类型 = htons(1) | 查询类 = htons(1) |
+--------------------------------------------------------------------+
+--------------------------------------------------------------------+
| 查询名 = [3|w|w|w|5|h|e|i|k|e|3|c|o|m|0] |
+--------------------------------------------------------------------+
| 类型 = htons(1) | 类 = htons(1) |
+--------------------------------------------------------------------+
| time to live = 999999 |
+--------------------------------------------------------------------+
| 资源数据长度 = htons(4) | 资源数据=inet_addr("31.33.7.44") |
+-------------------------------------------------------------------+
OK,就这么多了;)
分析:
在应答中QR = 1 是因为它是应答;)
AA = 1 因为名称服务器是权威服务器
RA = 1 是因为递归是可用的