(一)DNS报文格式
(1)公共报文头格式其中header报文头是必须有的,其他的有没有在报文头里有定义:
标识ID: 请求客户端设置的16位标示,服务器给出应答的时候会带相同的标示字段回来,这样请求客户端就可以区分不同的请求应答了。
OPCODE 4个比特位用来设置查询的种类,应答的时候会带相同值,可用的值如下:
0 标准查询 (QUERY)
1 反向查询 (IQUERY)
2 服务器状态查询 (STATUS)
3-15 保留值,暂时未使用
AA 授权应答(Authoritative Answer) - 这个比特位在应答的时候才有意义,指出给出应答的服务器是查询域名的授权解析服务器。
注意因为别名的存在,应答可能存在多个主域名,这个AA位对应请求名,或者应答中的第一个主域名。
TC 截断(TrunCation) - 用来指出报文比允许的长度还要长,导致被截断。
RD 期望递归(Recursion Desired) - 这个比特位被请求设置,应答的时候使用的相同的值返回。如果设置了RD,就建议域名服务器进行递归解析,递归查询的支持是可选的。
RA 支持递归(Recursion Available) - 这个比特位在应答中设置或取消,用来代表服务器是否支持递归查询。
Z 保留值,暂时未使用。在所有的请求和应答报文中必须置为0。
RCODE 应答码(Response code) - 这4个比特位在应答报文中设置,代表的含义如下:
0 没有错误。
1 报文格式错误(Format error) - 服务器不能理解请求的报文。
2 服务器失败(Server failure) - 因为服务器的原因导致没办法处理这个请求。
3 名字错误(Name Error) - 只有对授权域名解析服务器有意义,指出解析的域名不存在。
4 没有实现(Not Implemented) - 域名服务器不支持查询类型。
5 拒绝(Refused) - 服务器由于设置的策略拒绝给出应答。比如,服务器不希望对某些请求者给出应答,或者服务器不希望进行某些操作(比如区域传送zone transfer)。
6-15 保留值,暂时未使用。
问题数QDCOUNT 无符号16位整数表示报文请求段中的问题记录数。
资源记录数ANCOUNT 无符号16位整数表示报文回答段中的回答记录数。
授权资源记录数NSCOUNT 无符号16位整数表示报文授权段中的授权记录数。
额外资源记录数ARCOUNT 无符号16位整数表示报文附加段中的附加记录数。
(2)查询报文格式:
查询名QNAME 要查找的名字,是一个或多个标识符的序列。每个标识符以首字节的计数值来说明随后标识符的字节长度,每个名字以最后字节为0结束,长度为0的标识符是根标识符。单个标识符最大长度为63字节。
查询类型QTYPE 每个问题有一个查询类型。2个字节表示查询类型,取值可以为任何可用的类型值,以及通配码来表示所有的资源记录。
名字 数值 描述
A (1) 期望获得查询名的IP地址。
NS (2) 一个授权的域名服务器。
CNAME (5) 规范名称。
PTR (12) 指针记录。
HINFO (13) 主机信息。
MX (15) 邮件交换记录。
AXFR (252) 对区域转换的请求。
ANY (255) 对所有记录的请求。
其他QTYPE类型有
MD 3 a mail destination (Obsolete - use MX)
MF 4 a mail forwarder (Obsolete - use MX)
SOA 6 marks the start of a zone of authority
MB 7 a mailbox domain name (EXPERIMENTAL)
MG 8 a mail group member (EXPERIMENTAL)
MR 9 a mail rename domain name (EXPERIMENTAL)
NULL 10 a null RR (EXPERIMENTAL)
WKS 11 a well known service description
MINFO 14 mailbox or mail list information
TXT 16 text strings
查询类型出现在问题字段中,查询类型是类型的一个超集,所有的类型都是可用的查询类型
AXFR 252 A request for a transfer of an entire zone
MAILB 253 A request for mailbox-related records (MB, MG or MR)
MAILA 254 A request for mail agent RRs (Obsolete - see MX)
查询类:
IN (1) 指互联网地址。
CS 2 the CSNET class (Obsolete - used only for examples in some obsolete RFCs)
CH 3 the CHAOS class
HS 4 Hesiod [Dyer 87]
查询类是类的一个超集
* 255 any class
(3)应答报文格式:
类型TYPE 2个字节表示资源记录的类型,指出RDATA数据的含义
类CLASS 2个字节表示RDATA的类
生存时间TTL 4字节无符号整数表示资源记录可以缓存的时间。0代表只能被传输,但是不能被缓存。
**资源数据长度URDLENGT**H 2个字节无符号整数表示RDATA的长度
资源数据RDATA 不定长字符串来表示记录,格式根TYPE和CLASS有关。比如,TYPE是A,CLASS 是 IN,那么RDATA就是一个4个字节的ARPA网络地址。
(4)报文压缩:
为了减小报文,域名系统使用一种压缩方法来消除报文中域名的重复。使用这种方法,后面重复出现的域名或者labels被替换为指向之前出现位置的指针。
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+–+–+–+–+–+–+–+–+–+–+–+–+–+–+–+–+
| 1 1 | OFFSET |
+–+–+–+–+–+–+–+–+–+–+–+–+–+–+–+–+
前两个比特位都为1。因为lablels限制为不多于63个字节,所以label的前两位一定为0,这样就可以让指针与label进行区分。(10 和 01 组合保留,以便日后使用) 。偏移值(OFFSET)表示从报文开始的字节指针。偏移量为0表示ID字段的第一个字节。
压缩方法让报文中的域名成为:
以0结尾的labels序列
一个指针
指针结尾的labels序列
指针只能在域名不是特殊格式的时候使用,否则域名服务器或解析器需要知道资源记录的格式。目前还没有这种情况,但是以后可能会出现。
如果报文中的域名需要计算长度,并且使用了压缩算法,那么应该使用压缩后的长度,而不是压缩前的长度。
程序可以自由选择是否使用指针,虽然这回降低报文的容量,而且很容易产生截断。不过所有的程序都应该能够理解收到的报文中包含的指针。
比如,一个报文需要使用域名F.ISI.ARPA,FOO.F.ISI.ARPA,ARPA,以及根。忽略报文中的其他字段,应该编码为:
偏移20的是域名F.ISI.ARPA。域名FOO.F.ISI.ARPA偏移40; 这样表示FOO的label后面跟着一个指向之前F.ISI.ARPA的指针。域名ARPA偏移64,使用一个指针指向F.ISI.ARPA的ARPA。注意可以用这个指针是因为ARPA是从偏移位置20开始的labels序列中的最后一个label。 根域名在位置92定义为一个0,没有labels。
一个应答帧的例子:
0000 00 24 8c 87 39 7e 74 ea 3a 5b fe a4 08 00 45 00 .$..9~t. :[….E.
0010 00 91 55 bd 00 00 30 11 62 82 08 08 08 08 c0 a8 ..U…0. b…….
0020 01 65 00 35 ee c4 00 7d 78 64 3a 8b 81 80 00 01 .e.5…} xd:…..
0030 00 01 00 00 00 00 03 77 77 77 07 69 73 6e 6f 77 …….w ww.isnow
0040 66 79 03 63 6f 6d 00 00 1c 00 01 c0 0c 00 05 00 fy.com.. ……..
0050 01 00 00 12 ab 00 02 c0 10 …….. .
其中DNS帧从3a8b开始,3a8b是ID,flag8180,问题数1,回答数1,然后绿色部分是域名,回答是棕色部分,域名是c00c用的前面说的压缩方式