c++ - header 结构中的 DNS 查询格式小-大端问题

标签 c++ c dns

我对 DNS 查询格式有疑问......

我知道这个结构是DNS查询头的结构......

typedef struct _DNS_HEADER {
    unsigned short id;       // identification number
    unsigned char qr :1;     // query/response flag
    unsigned char opcode :4; // purpose of message
    unsigned char aa :1;     // authoritative answer
    unsigned char tc :1;     // truncated message
    unsigned char rd :1;     // recursion desired
    unsigned char ra :1;     // recursion available
    unsigned char z :1;      // its z! reserved
    unsigned char ad :1;     // authenticated data
    unsigned char cd :1;     // checking disabled
    unsigned char rcode :4;  // response code
    unsigned short q_count;  // number of question entries
    unsigned short ans_count; // number of answer entries
    unsigned short auth_count; // number of authority entries
    unsigned short add_count; // number of resource entries
} DNS_HEADER;

+问题查询和...

但是这里有一个问题: 我创建了一个套接字 socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP) 并创建了一个查询请求:

id = htons(10000);
qr = 0;
opcode = 0
aa = 0
tc = 0
rd = 1
ra = 0
z = 0 
ad = 0
cd = 0
q_count = 1
ans_count = 0
auth_count = 0
add_count = 0

和我的问题 ->

3,'w','w','w',4,'s','i','t','e',3,'c','o','m',0

TYPE = htons(1)
CLASS = htons(1)

我将此请求发送到我的特殊 DNS 服务器(绑定(bind)),我认为存在问题。有时 DNS 服务器没有响应我,即使响应,它也不是真正的响应(一切都是 0,除了相同的 header (12 字节)之外没有收到任何内容)

我搜索了一下,发现我的 DNS header 有问题,而且一定是这样的 ->

typedef struct _DNS_HEADER {
    unsigned short id;       // identification number

    unsigned char rd :1;     // recursion desired
    unsigned char tc :1;     // truncated message
    unsigned char aa :1;     // authoritative answer
    unsigned char opcode :4; // purpose of message
    unsigned char qr :1;     // query/response flag

    unsigned char rcode :4;  // response code
    unsigned char cd :1;     // checking disabled
    unsigned char ad :1;     // authenticated data
    unsigned char z :1;      // its z! reserved
    unsigned char ra :1;     // recursion available

    unsigned short q_count;  // number of question entries
    unsigned short ans_count; // number of answer entries
    unsigned short auth_count; // number of authority entries
    unsigned short add_count; // number of resource entries
} DNS_HEADER;

关于小-大端的一些事情。我将我的结构更改为这个结构,然后发送请求并完成 - 一切正常,没有任何问题,但这是我的问题:我不明白这是什么。是的,我读了一点关于小-大端的内容,但我仍然不明白:

  1. 为什么其他教授 DNS 格式的网站没有提到这一点?他们用第一种结构进行教学。
  2. 这是什么?为什么要把第二个16位的高8位改成第二个16位的低8位?

最佳答案

Why haven't other websites that teaches about DNS format mentioned this? They teach with the first structure.

我不可能回答这个问题。我遇到的大多数网络文献都提到了网络字节顺序及其动机。

Why we must change the higher 8 bits of the second 16 bits to be the lower 8 bits of the second 16 bits?

其动机可在“[IEN-137] Cohen, D., “ON HOLY WARS AND A PLEA FOR PEACE”, IEN 137, USC/ISI, April 1980 中找到。互联网工程任务组草案中提到:Network Byte Order

Background and Motivation

The document "ON HOLY WARS AND A PLEA FOR PEACE" [IEN-137] written in 1980 argues that the industry should settle on a single byte order. Since then, the IETF has largely settled on a single byte order known as "Network Byte Order" and this memo is intended to record that rough concensus. Unfortunately, the "holy war" continues among CPU manufacturers.

最后一句话就是这句话的意思。

某些 CPU 型号使用 Big-Endian其他人则使用 Little-Endian。甚至还有一些使用混合的。

两个字节(二进制形式)代表 std::uint16_t :

大尾数:10000000 00000000表示 32768(十进制)。
小尾数:10000000 00000000表示 128(十进制)。

如果对于如何解释这两个字节没有达成一致,沟通将会非常困难。

关于c++ - header 结构中的 DNS 查询格式小-大端问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59594815/

相关文章:

c++ - 我们如何注册具有特定文件扩展名的 Shell 扩展

c++ - "delete this"在构造函数中

c - GTK+ - 刷新滚动窗口

c - Linux中限制进程读取 "/etc/resolv.conf"文件

c++ - 循环之间的 pthread_create 中重复的线程 ID?

c++ - C++ 数组大小的奇怪行为

将特定数组元素与 C 中具有 "if"的字符串进行比较?

c - 如何在 c 中创建灵活的占位符表达式 (%d %s %d)?

C#,为什么我不能将域用户添加到本地组?

linux - 在 weblogic 11g 中设置首选监听地址