我想创建一个DNS响应以发送到我的浏览器。我已经创建了一些结构,例如在 rfc 中:
//DNS header
struct DNS_HEADER
{
unsigned short id;
unsigned char rd :1;
unsigned char tc :1;
unsigned char aa :1;
unsigned char opcode :4;
unsigned char qr :1;
unsigned char rcode :4;
unsigned char cd :1;
unsigned char ad :1;
unsigned char z :1;
unsigned char ra :1;
unsigned short q_count;
unsigned short ans_count;
unsigned short auth_count;
unsigned short add_count;
};
#pragma pack(push, 1)
struct R_DATA
{
unsigned short type;
unsigned short _class;
unsigned int ttl;
unsigned short data_len;
};
#pragma pack(pop)
struct RES_RECORD
{
unsigned char *name;
struct R_DATA *resource;
unsigned char *rdata;
};
现在我正在尝试填写此结构,以便我可以发送有效的 DNS 响应。例如,我正在尝试使用 ipaddres 112.12.12.12 发送例如 www.google.com(只是为了好玩)。
这是我所拥有的:
dns = (DNS_HEADER*)malloc(sizeof(DNS_HEADER));
dns->id = (unsigned short) htons(GetCurrentProcessId()); // ID
dns->qr = 1; // We give a response, Volgens RFC: (= query (0), or a response (1).)
dns->opcode = 0; // default
dns->aa = 0; //Not Authoritative,RFC: (= Authoritative Answer - this bit is valid in responses, and specifies that the responding name server is an authority for the domain name in question section.)
dns->tc = 0; // Not truncated
dns->rd = 1; // Enable recursion
dns->ra = 0; // Nameserver supports recursion?
dns->z = 0; // RFC: (= Reserved for future use. Must be zero in all queries and responses.)
dns->rcode = 0; // No error condition
dns->q_count = 0; // No questions!
dns->ad = 0; // How man resource records?
dns->cd = 0; // !checking
dns->ans_count = 1; // We give 1 answer
dns->auth_count = 0; // How many authority entries?
dns->add_count = 0; // How many resource entries?
但正如你所看到的,我对填写什么有一些疑问。还有R_Data和res_record我无法通过 rfc 找到我所做的随机响应要填写什么......
有人可以帮助我吗?
你的方法从根本上是有缺陷的。您不能使用结构表示 DNS 数据包,因为 DNS 数据包中的字符串是可变长度的,即字符串后面的字段在数据包中将处于不同的偏移量,具体取决于前面字符串的长度。
结构具有字符指针代替每个字符串,每个指针通常是一个指向内存中其他位置的 32 位值。因此,当您尝试发送内存中表示的结构时,您将发送或多或少的随机 32 位值来代替字符串。
以下是DNS数据包应该是什么样子的相当说明性的指南:http://www.tcpipguide.com/free/t_DNSMessageProcessingandGeneralMessageFormat.htm
点一目了然:响应中的id
必须是您在查询中收到的 ID。 q_count
应该是 1 并重复您收到的查询(在您的示例中,例如 x03wwwx06googlex03comx00x00x01x00x01
为www.google.com IN A
)。RFC1035 第 3.4.1 节中解释了需要rdata
的内容(在您的示例中为 x70x0cx0cx0c
)。