start pulling pack_dns_struct apart
This commit is contained in:
parent
21df49cc15
commit
acfc903a15
2 changed files with 88 additions and 47 deletions
|
|
@ -43,27 +43,6 @@ bool validate_dns(HParseResult *p) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct dns_qname get_qname(const HParsedToken *t) {
|
|
||||||
// The qname parser parses at least 1 length-value pair, then a NULL.
|
|
||||||
// So, t->seq->elements[0] is a sequence of at least 1 such pair,
|
|
||||||
// and t->seq->elements[1] is the null.
|
|
||||||
const HParsedToken *labels = t->seq->elements[0];
|
|
||||||
struct dns_qname ret = {
|
|
||||||
.qlen = labels->seq->used,
|
|
||||||
.labels = h_arena_malloc(t->seq->arena, sizeof(*ret.labels)*labels->seq->used)
|
|
||||||
};
|
|
||||||
// i is which label we're on
|
|
||||||
for (size_t i=0; i<labels->seq->used; ++i) {
|
|
||||||
ret.labels[i].len = labels->seq->elements[i]->seq->used;
|
|
||||||
ret.labels[i].label = h_arena_malloc(t->seq->arena, ret.labels[i].len + 1);
|
|
||||||
// j is which char of the label we're on
|
|
||||||
for (size_t j=0; j<ret.labels[i].len; ++j)
|
|
||||||
ret.labels[i].label[j] = labels->seq->elements[i]->seq->elements[j]->uint;
|
|
||||||
ret.labels[i].label[ret.labels[i].len] = 0;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
char* get_domain(const HParsedToken *t) {
|
char* get_domain(const HParsedToken *t) {
|
||||||
switch(t->token_type) {
|
switch(t->token_type) {
|
||||||
case TT_UINT:
|
case TT_UINT:
|
||||||
|
|
@ -313,6 +292,43 @@ const HParsedToken* act_header(const HParseResult *p) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const HParsedToken* act_label(const HParseResult *p) {
|
||||||
|
HParsedToken *ret = h_arena_malloc(p->arena, sizeof(HParsedToken));
|
||||||
|
ret->token_type = TT_dns_label;
|
||||||
|
ret->user = h_arena_malloc(p->arena, sizeof(dns_label_t));
|
||||||
|
dns_label_t *r = (dns_label_t *)ret->user;
|
||||||
|
|
||||||
|
r->len = p->ast->seq->used;
|
||||||
|
r->label = h_arena_malloc(p->arena, r->len + 1);
|
||||||
|
for (size_t i=0; i<r->len; ++i)
|
||||||
|
r->label[i] = p->ast->seq->elements[i]->uint;
|
||||||
|
r->label[r->len] = 0;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
const HParsedToken* act_question(const HParseResult *p) {
|
||||||
|
HParsedToken *ret = h_arena_malloc(p->arena, sizeof(HParsedToken));
|
||||||
|
ret->token_type = TT_dns_question;
|
||||||
|
ret->user = h_arena_malloc(p->arena, sizeof(dns_question_t));
|
||||||
|
|
||||||
|
dns_question_t *q = (dns_question_t *)ret->user;
|
||||||
|
HParsedToken **fields = p->ast->seq->elements;
|
||||||
|
|
||||||
|
// QNAME is a sequence of labels. Pack them into an array.
|
||||||
|
q->qname.qlen = fields[0]->seq->used;
|
||||||
|
q->qname.labels = h_arena_malloc(p->arena, sizeof(dns_label_t)*q->qname.qlen);
|
||||||
|
for(size_t i=0; i<fields[0]->seq->used; i++) {
|
||||||
|
assert(fields[0]->seq->elements[i]->token_type == (HTokenType)TT_dns_label);
|
||||||
|
q->qname.labels[i] = *(dns_label_t *)fields[0]->seq->elements[i]->user;
|
||||||
|
}
|
||||||
|
|
||||||
|
q->qtype = fields[1]->uint;
|
||||||
|
q->qclass = fields[2]->uint;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
const HParsedToken* act_message(const HParseResult *p) {
|
const HParsedToken* act_message(const HParseResult *p) {
|
||||||
h_pprint(stdout, p->ast, 0, 2);
|
h_pprint(stdout, p->ast, 0, 2);
|
||||||
HParsedToken *ret = h_arena_malloc(p->arena, sizeof(HParsedToken));
|
HParsedToken *ret = h_arena_malloc(p->arena, sizeof(HParsedToken));
|
||||||
|
|
@ -328,11 +344,8 @@ const HParsedToken* act_message(const HParseResult *p) {
|
||||||
struct dns_question *questions = h_arena_malloc(p->arena,
|
struct dns_question *questions = h_arena_malloc(p->arena,
|
||||||
sizeof(struct dns_question)*(header->question_count));
|
sizeof(struct dns_question)*(header->question_count));
|
||||||
for (size_t i=0; i<header->question_count; ++i) {
|
for (size_t i=0; i<header->question_count; ++i) {
|
||||||
// QNAME is a sequence of labels. In the parser, it's defined as
|
assert(qs->seq->elements[i]->token_type == (HTokenType)TT_dns_question);
|
||||||
// sequence(many1(length_value(...)), ch('\x00'), NULL).
|
questions[i] = *(dns_question_t *)qs->seq->elements[i]->user;
|
||||||
questions[i].qname = get_qname(qs->seq->elements[i]->seq->elements[0]);
|
|
||||||
questions[i].qtype = qs->seq->elements[i]->seq->elements[1]->uint;
|
|
||||||
questions[i].qclass = qs->seq->elements[i]->seq->elements[2]->uint;
|
|
||||||
}
|
}
|
||||||
msg->questions = questions;
|
msg->questions = questions;
|
||||||
|
|
||||||
|
|
@ -383,7 +396,32 @@ const HParsedToken *act_ignore(const HParseResult *p)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Helper to build HAction's that pick one index out of a sequence.
|
||||||
|
const HParsedToken *act_index(int i, const HParseResult *p)
|
||||||
|
{
|
||||||
|
if(!p) return NULL;
|
||||||
|
|
||||||
|
const HParsedToken *tok = p->ast;
|
||||||
|
|
||||||
|
if(!tok || tok->token_type != TT_SEQUENCE)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
const HCountedArray *seq = tok->seq;
|
||||||
|
size_t n = seq->used;
|
||||||
|
|
||||||
|
if(i<0 || (size_t)i>=n)
|
||||||
|
return NULL;
|
||||||
|
else
|
||||||
|
return tok->seq->elements[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
const HParsedToken *act_index0(const HParseResult *p)
|
||||||
|
{
|
||||||
|
return act_index(0, p);
|
||||||
|
}
|
||||||
|
|
||||||
#define act_hdzero act_ignore
|
#define act_hdzero act_ignore
|
||||||
|
#define act_qname act_index0
|
||||||
|
|
||||||
const HParser* init_parser() {
|
const HParser* init_parser() {
|
||||||
static const HParser *ret = NULL;
|
static const HParser *ret = NULL;
|
||||||
|
|
@ -415,11 +453,11 @@ const HParser* init_parser() {
|
||||||
h_int_range(h_uint16(), 255, 255),
|
h_int_range(h_uint16(), 255, 255),
|
||||||
NULL));
|
NULL));
|
||||||
H_RULE (len, h_int_range(h_uint8(), 1, 255));
|
H_RULE (len, h_int_range(h_uint8(), 1, 255));
|
||||||
H_RULE (label, h_length_value(len, h_uint8()));
|
H_ARULE(label, h_length_value(len, h_uint8()));
|
||||||
H_RULE (qname, h_sequence(h_many1(label),
|
H_ARULE(qname, h_sequence(h_many1(label),
|
||||||
h_ch('\x00'),
|
h_ch('\x00'),
|
||||||
NULL));
|
NULL));
|
||||||
H_RULE (question, h_sequence(qname, qtype, qclass, NULL));
|
H_ARULE(question, h_sequence(qname, qtype, qclass, NULL));
|
||||||
H_RULE (rdata, h_length_value(h_uint16(), h_uint8()));
|
H_RULE (rdata, h_length_value(h_uint16(), h_uint8()));
|
||||||
H_RULE (rr, h_sequence(domain, // NAME
|
H_RULE (rr, h_sequence(domain, // NAME
|
||||||
type, // TYPE
|
type, // TYPE
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
enum DNSTokenType_ {
|
enum DNSTokenType_ {
|
||||||
TT_dns_message = TT_USER,
|
TT_dns_message = TT_USER,
|
||||||
TT_dns_header,
|
TT_dns_header,
|
||||||
|
TT_dns_label,
|
||||||
TT_dns_qname,
|
TT_dns_qname,
|
||||||
TT_dns_question,
|
TT_dns_question,
|
||||||
TT_dns_rr
|
TT_dns_rr
|
||||||
|
|
@ -18,21 +19,23 @@ typedef struct dns_header {
|
||||||
size_t additional_count;
|
size_t additional_count;
|
||||||
} dns_header_t;
|
} dns_header_t;
|
||||||
|
|
||||||
struct dns_qname {
|
typedef struct dns_label {
|
||||||
size_t qlen;
|
|
||||||
struct {
|
|
||||||
size_t len;
|
size_t len;
|
||||||
uint8_t *label;
|
uint8_t *label;
|
||||||
} *labels;
|
} dns_label_t;
|
||||||
};
|
|
||||||
|
|
||||||
struct dns_question {
|
typedef struct dns_qname {
|
||||||
struct dns_qname qname;
|
size_t qlen;
|
||||||
|
dns_label_t *labels;
|
||||||
|
} dns_qname_t;
|
||||||
|
|
||||||
|
typedef struct dns_question {
|
||||||
|
dns_qname_t qname;
|
||||||
uint16_t qtype;
|
uint16_t qtype;
|
||||||
uint16_t qclass;
|
uint16_t qclass;
|
||||||
};
|
} dns_question_t;
|
||||||
|
|
||||||
struct dns_rr {
|
typedef struct dns_rr {
|
||||||
char* name;
|
char* name;
|
||||||
uint16_t type;
|
uint16_t type;
|
||||||
uint16_t class;
|
uint16_t class;
|
||||||
|
|
@ -81,12 +84,12 @@ struct dns_rr {
|
||||||
uint8_t* bit_map;
|
uint8_t* bit_map;
|
||||||
} wks;
|
} wks;
|
||||||
};
|
};
|
||||||
};
|
} dns_rr_t;
|
||||||
|
|
||||||
typedef struct dns_message {
|
typedef struct dns_message {
|
||||||
struct dns_header header;
|
dns_header_t header;
|
||||||
struct dns_question *questions;
|
dns_question_t *questions;
|
||||||
struct dns_rr *answers;
|
dns_rr_t *answers;
|
||||||
struct dns_rr *authority;
|
dns_rr_t *authority;
|
||||||
struct dns_rr *additional;
|
dns_rr_t *additional;
|
||||||
} dns_message_t;
|
} dns_message_t;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue