sia*_*sia 0 sockets dns networking network-programming rfc1035
我正在编写一个程序来接收dns消息并回复一个适当的答案(一个只回复A记录的简单dns服务器).
但是当我收到消息时,它与1035 RFC中描述的格式不同.
例如,这是nslookup生成的dns查询:
'\xe1\x0c\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\x06google\x03com\x00\x00\x01\x00\x01'
Run Code Online (Sandbox Code Playgroud)
我知道1035 RFC中定义的dns头和位,但为什么它应该是十六进制?
我应该将它们视为十六进制数或它们的utf-8等价物吗?
我的回答是否也应该有这种格式?
它以十六进制形式出现,因为它是一个原始二进制请求,但您可能会尝试将其打印为字符串.这显然是如何通过你用来打印出来的不可打印字符来显示的; 它以十六进制序列的形式逃脱它们.
你根本不把它解释为"hex"或UTF-8; 您需要解释RFC描述的二进制格式.如果你提到你正在使用的语言,我(或其他人)可能会向你描述如何处理像这样的二进制格式的数据.
那么,让我们看看RFC 1035,看看如何手动解释您的查询:
The header contains the following fields:
1 1 1 1 1 1
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| ID |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|QR| Opcode |AA|TC|RD|RA| Z | RCODE |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| QDCOUNT |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| ANCOUNT |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| NSCOUNT |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| ARCOUNT |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
Run Code Online (Sandbox Code Playgroud)
每行有16位,所以这是12个字节.让我们把前12个字节填入那里:
1 1 1 1 1 1
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| ID = e10c | \xe1 \x0c
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| 0| Opcode=0 | 0| 0| 1| 0| Z=0 | RCODE=0 | \x01 \x00
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| QDCOUNT = 1 | \x00 \x01
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| ANCOUNT = 0 | \x00 \x00
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| NSCOUNT = 0 | \x00 \x00
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| ARCOUNT = 0 | \x00 \x00
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
Run Code Online (Sandbox Code Playgroud)
所以.我们有一个ID为=的查询e10c(只是一个任意数字,所以客户端可以将查询与响应匹配),QR = 0表示它是一个查询,opcode = 0表示它是一个标准查询,AA和TC用于响应,RD = 1表示需要递归(我们正在对本地名称服务器进行递归查询).Z保留供将来使用,RCODE是响应的响应代码.QDCOUNT = 1表示我们有1个问题,其余的都是响应中不同类型记录的数量.
现在我们来问问题.每种都有以下格式:
1 1 1 1 1 1
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| |
/ QNAME /
/ /
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| QTYPE |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| QCLASS |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
Run Code Online (Sandbox Code Playgroud)
QNAME是查询的名称.格式为一个八位字节,表示标签的长度,后跟标签,以0长度的标签终止.
所以我们有:
1 1 1 1 1 1
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| LEN = 6 | g | \x06 g
| o | o | o o
| g | l | g l
| e | LEN = 3 | e \x03
| c | o | c o
| m | LEN = 0 | m \x00
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| QTYPE = 1 | \x00 \x01
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| QCLASS = 1 | \x00 \x01
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
Run Code Online (Sandbox Code Playgroud)
这表明我们正在查找的名称是google.com(有时写成google.com.,最后的空标签是明确的).QTYPE = 1是A(IPv4地址)记录.QCLASS = 1是IN(互联网)查询.所以这是要求google.com的IPv4地址.
| 归档时间: |
|
| 查看次数: |
1588 次 |
| 最近记录: |