|
|
@ -661,101 +661,103 @@ static int __dns_parser_parse_record(int idx, dns_parser_t *parser)
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
static int __dns_parser_parse_question(dns_parser_t *parser)
|
|
|
|
static int __dns_parser_parse_question(dns_parser_t *parser)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
uint16_t qtype;
|
|
|
|
uint16_t qtype;
|
|
|
|
uint16_t qclass;
|
|
|
|
uint16_t qclass;
|
|
|
|
const char *msgend;
|
|
|
|
const char *msgend;
|
|
|
|
const char **cur;
|
|
|
|
const char **cur;
|
|
|
|
int ret;
|
|
|
|
int ret;
|
|
|
|
char host[DNS_NAMES_MAX + 2];
|
|
|
|
char host[DNS_NAMES_MAX + 2];
|
|
|
|
|
|
|
|
|
|
|
|
msgend = (const char *)parser->msgbuf + parser->msgsize;
|
|
|
|
msgend = (const char *)parser->msgbuf + parser->msgsize;
|
|
|
|
cur = &(parser->cur);
|
|
|
|
cur = &(parser->cur);
|
|
|
|
|
|
|
|
|
|
|
|
// question count != 1 is an error
|
|
|
|
// question count != 1 is an error
|
|
|
|
if (parser->header.qdcount != 1)
|
|
|
|
if (parser->header.qdcount != 1)
|
|
|
|
return -2;
|
|
|
|
return -2;
|
|
|
|
|
|
|
|
|
|
|
|
// parse qname
|
|
|
|
// parse qname
|
|
|
|
ret = __dns_parser_parse_host(host, parser);
|
|
|
|
ret = __dns_parser_parse_host(host, parser);
|
|
|
|
if (ret < 0)
|
|
|
|
if (ret < 0)
|
|
|
|
return ret;
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
|
|
|
|
// parse qtype and qclass
|
|
|
|
// parse qtype and qclass
|
|
|
|
if (*cur + 4 > msgend)
|
|
|
|
if (*cur + 4 > msgend)
|
|
|
|
return -2;
|
|
|
|
return -2;
|
|
|
|
|
|
|
|
|
|
|
|
qtype = __dns_parser_uint16(*cur);
|
|
|
|
qtype = __dns_parser_uint16(*cur);
|
|
|
|
qclass = __dns_parser_uint16(*cur + 2);
|
|
|
|
qclass = __dns_parser_uint16(*cur + 2);
|
|
|
|
*cur += 4;
|
|
|
|
*cur += 4;
|
|
|
|
|
|
|
|
|
|
|
|
if (parser->question.qname)
|
|
|
|
if (parser->question.qname)
|
|
|
|
free(parser->question.qname);
|
|
|
|
free(parser->question.qname);
|
|
|
|
|
|
|
|
|
|
|
|
parser->question.qname = strdup(host);
|
|
|
|
parser->question.qname = strdup(host);
|
|
|
|
if (parser->question.qname == NULL)
|
|
|
|
if (parser->question.qname == NULL)
|
|
|
|
return -1;
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
|
|
|
|
parser->question.qtype = qtype;
|
|
|
|
parser->question.qtype = qtype;
|
|
|
|
parser->question.qclass = qclass;
|
|
|
|
parser->question.qclass = qclass;
|
|
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void dns_parser_init(dns_parser_t *parser)
|
|
|
|
void dns_parser_init(dns_parser_t *parser)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
parser->msgbuf = NULL;
|
|
|
|
// 初始化解析器结构体,包括分配内存、设置指针、初始化计数器和列表头
|
|
|
|
parser->msgbase = NULL;
|
|
|
|
parser->msgbuf = NULL;
|
|
|
|
parser->cur = NULL;
|
|
|
|
parser->msgbase = NULL;
|
|
|
|
parser->msgsize = 0;
|
|
|
|
parser->cur = NULL;
|
|
|
|
parser->bufsize = 0;
|
|
|
|
parser->msgsize = 0;
|
|
|
|
parser->complete = 0;
|
|
|
|
parser->bufsize = 0;
|
|
|
|
parser->single_packet = 0;
|
|
|
|
parser->complete = 0;
|
|
|
|
memset(&parser->header, 0, sizeof (struct dns_header));
|
|
|
|
parser->single_packet = 0;
|
|
|
|
memset(&parser->question, 0, sizeof (struct dns_question));
|
|
|
|
memset(&parser->header, 0, sizeof (struct dns_header));
|
|
|
|
INIT_LIST_HEAD(&parser->answer_list);
|
|
|
|
memset(&parser->question, 0, sizeof (struct dns_question));
|
|
|
|
INIT_LIST_HEAD(&parser->authority_list);
|
|
|
|
INIT_LIST_HEAD(&parser->answer_list);
|
|
|
|
INIT_LIST_HEAD(&parser->additional_list);
|
|
|
|
INIT_LIST_HEAD(&parser->authority_list);
|
|
|
|
|
|
|
|
INIT_LIST_HEAD(&parser->additional_list);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int dns_parser_set_question(const char *name,
|
|
|
|
int dns_parser_set_question(const char *name,
|
|
|
|
uint16_t qtype,
|
|
|
|
uint16_t qtype,
|
|
|
|
uint16_t qclass,
|
|
|
|
uint16_t qclass,
|
|
|
|
dns_parser_t *parser)
|
|
|
|
dns_parser_t *parser)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
|
|
|
|
ret = dns_parser_set_question_name(name, parser);
|
|
|
|
// 设置DNS查询的问题部分,包括域名、查询类型和查询类
|
|
|
|
if (ret < 0)
|
|
|
|
ret = dns_parser_set_question_name(name, parser);
|
|
|
|
return ret;
|
|
|
|
if (ret < 0)
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
parser->question.qtype = qtype;
|
|
|
|
|
|
|
|
parser->question.qclass = qclass;
|
|
|
|
parser->question.qtype = qtype;
|
|
|
|
parser->header.qdcount = 1;
|
|
|
|
parser->question.qclass = qclass;
|
|
|
|
|
|
|
|
parser->header.qdcount = 1;
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int dns_parser_set_question_name(const char *name, dns_parser_t *parser)
|
|
|
|
int dns_parser_set_question_name(const char *name, dns_parser_t *parser)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
char *newname;
|
|
|
|
char *newname;
|
|
|
|
size_t len;
|
|
|
|
size_t len;
|
|
|
|
|
|
|
|
|
|
|
|
len = strlen(name);
|
|
|
|
len = strlen(name);
|
|
|
|
newname = (char *)malloc(len + 1);
|
|
|
|
newname = (char *)malloc(len + 1);
|
|
|
|
|
|
|
|
|
|
|
|
if (!newname)
|
|
|
|
if (!newname)
|
|
|
|
return -1;
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
|
|
|
|
memcpy(newname, name, len + 1);
|
|
|
|
memcpy(newname, name, len + 1);
|
|
|
|
// Remove trailing dot, except name is "."
|
|
|
|
// Remove trailing dot, except name is "."
|
|
|
|
if (len > 1 && newname[len - 1] == '.')
|
|
|
|
if (len > 1 && newname[len - 1] == '.')
|
|
|
|
newname[len - 1] = '\0';
|
|
|
|
newname[len - 1] = '\0';
|
|
|
|
|
|
|
|
|
|
|
|
if (parser->question.qname)
|
|
|
|
if (parser->question.qname)
|
|
|
|
free(parser->question.qname);
|
|
|
|
free(parser->question.qname);
|
|
|
|
parser->question.qname = newname;
|
|
|
|
parser->question.qname = newname;
|
|
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void dns_parser_set_id(uint16_t id, dns_parser_t *parser)
|
|
|
|
void dns_parser_set_id(uint16_t id, dns_parser_t *parser)
|
|
|
|