DNS报文格式及抓包解析
报文结构
DNS的报文结构如下,其中黄色为基础部分,绿色为问题部分,蓝色为资源记录部分。资源记录部分只在响应包中出现。
基础部分
1.事务ID
16bit,DNS报文的标识,请求报文和对应的响应报文的事务ID应该相同。
2. 标志
16bit,分为8个字段:
字段 | 长度/bit | 作用 |
---|---|---|
QR | 1 | 查询报文为0,响应报文为1 |
Opcode | 4 | 标准查询为0,反向查询为2,请求服务器状态为2 |
AA | 1 | 授权应答,在响应报文中有效 1表示名称服务器是权威服务器 0表示不是权威服务器 |
TC | 1 | 是否被接断 1表示响应超过512个字节,只返回前512个字节 |
RD | 1 | 期望递归,在查询报文中设置 1表示递归查询 0表示迭代查询 |
RA | 1 | 可用递归,用于响应RD 1表示服务器支持递归查询 |
zero | 3 | 保留字段,全为0 |
rcode | 4 | 返回码 0表示没有错误 1表示请求报文格式错误 2表示域名服务器失败 3表示解析的域名不存在 4表示查询类型不支持 5表示拒绝应答 |
3. 问题计数
16bit,DNS查询请求的数量
4. 回答资源记录数
16bit,DNS响应的数量
5. 权威名称服务器计数
16bit,权威名称服务器的数量
6. 附加资源记录数
16bit,额外的记录数目(权威服务器对应的Ip地址)
问题部分
问题部分由三个字段组成:查询名,查询类型,查询类
1. 查询名
要查询的域名。长度不固定,由一段或多段标识符组成,首字节表示随后标识符的长度,单位为字节;每个域名结尾用一个0字节表示。例如baidu.com:
5 | b | a | i | d | u | 3 | c | o | m | 0 |
---|---|---|---|---|---|---|---|---|---|---|
计数 | 计数 | 结尾 |
2. 查询类型
16bit,表示要查询的类型,常见的有:
值 | 助记符 | 说明 |
---|---|---|
1 | A | 由域名获得IPv4地址 |
28 | AAAA | 由域名获得IPv6地址 |
12 | PTR | 由IP地址获得域名 |
3. 查询类
16bit,表示地址类型,常用的是IN(值为1),表示互联网地址。
资源记录部分
资源记录部分包含回答问题区域、权威名称服务器区域、附加信息区域。这三部分的格式都为域名+类型+类+生存时间+资源数据长度+资源数据。
1. 域名
长度可变,DNS请求的域名。当此域名与前文重复时,为减小报文的长度可以将此域名压缩为16bit的指针,指向前文中已经出现过的域名,方法为:
16bit指针的最高两位均置1,剩余14位的值表示前文中的域名相对于DNS报文头的偏移字节数。如:
在上图中,回答问题区域的域名与问题部分的域名重复,因此使用了指针c0 0c。去掉最高两位后,指针表示重复域名距离DNS的报文头偏移了0c个字节。从图中可以看到,第十三个字节开始被蓝色框住的部分,即为问题部分的域名数据。
2. 类型
16bit,与问题部分的查询类型相同。
3. 类
16bit,与问题部分的查询类相同。
4. 生存时间
32bit,表示资源记录可以缓存的时间,单位为秒。
5. 资源数据长度
16bit,资源数据的长度。
6. 资源数据
按要求返回的资源数据。