做实验环境的时候,发现一堆特别烦人的dns要求,就想着一直撸一个dns的服务器…

报文格式:

报文由 头部数据部分 组成,无论是在查询包还是返回包中,头部字段始终存在且长度和格式都不变,数据部分是否存在及其大小则由头部数据决定

注意: 1字节(byte)=8比特(bit)*

报文头部

长度 名称
2字节 会话标识
2字节 标志
8字节 数据部分数量

报文数据部分

报文数据部分的大小是可变的,没有固定长度
报文数据部分按照顺序排列有以下4个区域,每个区域都有可能有多份数据(例如,一个包里可能查询了2个问题,那么,问题区域将包含两个问题的数据)服务端会根据报文头部”数据部分数量”的数据来依次读取报文数据部分的内容

每一个DNS请求都有唯一的会话标识,该标识由客户端(查询发起端)发送查询数据包时生成,服务器返回响应包时的会话标识应与对应的查询包一致

标志

标志记录了该请求包的各个参数,具体如下
注意,各个参数的顺序即按下表的顺序从上至下

长度 名称 详细
1比特 QR 查询/响应标志,0为查询,1为响应
4比特 opcode 0表示标准查询,1表示反向查询,2表示服务器状态请求
1比特 AA 是否为授权回答
1比特 TC 是否是可截断的
1比特 RD 是否期望递归
1比特 RA 是否可用递归
4比特 rcode 返回码(0=没有差错,2=服务器错误,3=域名差错)

数据部分数量

该部分8个字节,每两字节记录一个数字,每一个数字记录了4个报文数据部分的数据数量

报文数据>问题区域

问题区域由以下字段构成

名称 长度
要查询的域名 不固定
查询类型 2字节
查询类 2字节

要查询的域名区域…..上一张自制的图好了,例如”smyhw.online”这个域名
[图片丢失]
注意:一个字符为一个字节!!!

查询类型:
查询类型有如下的选项,”标识”就是填入该区域的2字节int

名称 标识 描述
A 1 域名查IPv4地址
CNAME 5 查别名
PTR 12 指针记录
HINFO 13 主机信息
MX 15 邮件交换记录
AXFR 252 对区域转换的请求
ANY 255 对所有记录的请求

查询类:目前常用的选项只有一个,就是数字1,表示internet请求
附:其他的类型(我也不清楚是干啥用的….)

报文数据>其他区域

其他区域包含了问题区域的所有内容,并附加了一些区域,如下表:

名称 长度
要查询的域名 不固定
查询类型 2字节
查询类 2字节
生存时间 4字节
资源字段长度 2字节
资源字段 由上一行决定

在问题区域段落已经解释过的字段不再解释

生存时间:标识客户端拿到这个数据之后,可以在客户端本地保存多久,在这个时间内,客户端再需要这条信息时,会从其本地缓存中读取,而不是再发送一次询问请求

资源字段长度:定义下一段数据的长度

资源字段:记录该请求的实际数据,例如:如果请求的是域名转IP地址,那么这里就是服务器返回的IP地址,如果请求的是别名记录(CNAME),那么这里就是返回的域名

注意事项: