DNS协议是互联网最重要的基础协议,也是应用最广泛的UDP协议之一。现在它还支持基于TCP的DNS和基于ssl的加密DNS协议。本文Bug用一个简单的例子带领大家学习DNS协议,实现了一个简单的DNS查询客户端。DNS协议非常简单。详情请参考IETF的rfc1035国际标准。
DNS查询协议由查询头和请求部分组成。
查询标题
DNS查询头结构如上所示。在本例中,我们需要设置的唯一字段是消息ID,它将被复制回服务器响应。RD,告诉DNS服务器在需要时递归查询;QDCOUNT,这意味着我们只需要查找一个域。
请求零件
在请求部分,需要设置的字段有:在QNAME中设置要查询的域名。不用直接放置域名,可以用“标签”把它拆分成几个部分。实例,我们的标签将是“www”,然后是“ijz”,然后是“me”。QNAME要求在每个标签前加上前缀长度,以0结尾。所以我们的QNAME将是:
3,w,w,w,3,I,j,z,2,m,e,0
请注意,QNAME必须以0结尾。
QTYPE和QCLASS都将被设置为1。
响应服务器
查询后,解析的IP地址将位于服务器响应中RDATA的最后4个字节。对于简单的处理,我们只需要获取这部分内容。
以下是C的全部代码源代码:
#包括
#包括
#包括
#包括
int main
{
int I;
uint 8 _ t RSP[512];
uint8_t qry[] = {
0xde,0xad,//ID
0x01,0x00,//RD设置
0x00,0x01,//QDCOUNT = 1
0x00,0x00,//ANCOUNT = 0
0x00,0x00,//NSCOUNT = 0
0x00,0x00,//ARCOUNT = 0
3,
' w ',' w ',' w ',
3,
I ',' j ',' z ',
2,
' m ',' e ',
0,
0x00,0x01,//QTYPE
0x00,0x01,//QCLASS
};
struct sockaddr _ in sv
socklen _ t len
int s = socket
sv.sin _ family = AF _ INET
sv.sin _ port = htons
SV . sin _ addr . s _ addr = inet _ addr;
sendto,0,sv,sizeof);
i = recvfromsv, len);
printf
关闭;
返回0;
}
编译和查询: