我有以下代码检查DNS响应中的查询类型,然后进一步进行相应打印。我需要一种使用给定参数解析CNAME和NS的方法,但无法这样做。这里的tmp
是一个变量,定义为tmp = (u_char *)(dpkt->payload + 12);
,而dns_label_to_str
是一个函数,用于将字符串形式的DNS名称转换为:*dns_label_to_str(u_char **label, u_char *dest,size_t dest_size,const u_char *payload,const u_char *end)
代码:
switch (qtype) {
case 1: /* A */
data = inet_ntop(AF_INET, tmp, dbuf, BUFSIZ);
break;
case 2: /* NS */
case 5: /* CNAME */
case 12: /* PTR */
data = (char *)dns_label_to_str(
&tmp, (u_char *)dbuf, BUFSIZ,
dpkt->payload, tmp + len
);
break;
case 10: /* NULL */
data = "NULL";
break;
case 15: /* MX (16-bit priority / label) */
i = snprintf(dbuf, 7, "%u ", ntohs(*(uint16_t *)tmp));
tmp += 2;
data = (char *)dns_label_to_str(
&tmp, (u_char *)(dbuf + i), BUFSIZ - i,
dpkt->payload, tmp + len - 2
);
data = dbuf;
break;
case 16: /* TXT (1 byte text length / text) */
if (*tmp <= len && tmp + len < end) {
memcpy(dbuf, tmp+1, *tmp);
dbuf[*tmp+1] = '\0';
} else *dbuf = '\0';
data = dbuf;
break;
case 17: /* AAAA */
data = inet_ntop(AF_INET6, tmp, dbuf, BUFSIZ);
break;
default:
/* Ignore unhandled RR types */
*dbuf = '\0';
data = dbuf;
}
/* Print the output. */
printf("%ld %-5s %-30s %s\n", hdr->ts.tv_sec,
dns_types[qtype], label, data);
ret:
return 0;
}
如果在qtype == 5
时有人可以帮助我获取CNAME会有所帮助。预先感谢。
答案 0 :(得分:1)
我尚不完全清楚dns_label_to_str
函数的作用,但是参数最可能的含义是:
label
:指向指针的指针。 *label
最初指向数据包中名称的开头,并更新为指向数据包中名称之后的下一个字节。dest
:目标缓冲区的地址。 (这可以是字符串(文本格式)或未压缩的名称(有线格式)。dest
:目标缓冲区的长度。根据函数的输出格式,此值应至少为256(有线格式)或至少1024(文本格式,由于转义)。当然,目标缓冲区必须足够大。payload
:指向整个 DNS数据包开始的指针(不是当前资源记录的数据!) 。end
:指向整个DNS数据包中最后一个字节之后的指针。之类的dns_label_to_str
之类的功能需要引用整个数据包的原因是DNS标签压缩:名称可以包含一个压缩引用,该引用指向数据包中的另一个较早的位置,从而在数据包中重用另一个名称的结尾。包,以较小的偏移量。这些引用绝不会指向资源记录数据,因为对于CNAME记录,它仅包含一个名称:如果使用压缩,则名称tail必须来自其他位置。
编辑在有关前向压缩指针的评论中,我们存在一些争论。 BIND 9拒绝了它们,但是其他许多实现也接受了它们。
答案 1 :(得分:1)
dpkt->payload + 12
处的数据是问题部分,即原始请求中内容的副本,并将包含一个(未压缩的)标签,称为QNAME
,后跟16位QTYPE
和QCLASS
字段。
此后,您才开始查找响应数据,其每个记录都遵循RFC 1035,第4节的结构,强烈建议您先阅读以下内容:
1 1 1 1 1 1
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| |
/ /
/ NAME /
| |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| TYPE |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| CLASS |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| TTL |
| |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| RDLENGTH |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--|
/ RDATA /
/ /
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
请注意,“问题”部分中的数据结构与上面的前三个字段相同。