Nearly done with RR parsing, need to write two helpers for this.

This commit is contained in:
Meredith L. Patterson 2012-05-26 15:50:39 +02:00
parent 6feb0ac547
commit 0c324adaa6
2 changed files with 198 additions and 8 deletions

View file

@ -1,6 +1,7 @@
#include "../src/hammer.h" #include "../src/hammer.h"
#include "dns_common.h" #include "dns_common.h"
#include "dns.h" #include "dns.h"
#include "rr.h"
#define false 0 #define false 0
#define true 1 #define true 1
@ -40,7 +41,7 @@ struct dns_qname get_qname(const HParsedToken *t) {
const HParsedToken *labels = t->seq->elements[0]; const HParsedToken *labels = t->seq->elements[0];
struct dns_qname ret = { struct dns_qname ret = {
.qlen = labels->seq->used, .qlen = labels->seq->used,
.labels = h_arena_malloc(t->seq->arena, sizeof(ret.labels)*ret.qlen) .labels = h_arena_malloc(t->seq->arena, sizeof(ret.labels)*labels->seq->used)
}; };
// i is which label we're on // i is which label we're on
for (size_t i=0; i<labels->seq->used; ++i) { for (size_t i=0; i<labels->seq->used; ++i) {
@ -60,16 +61,204 @@ char* get_domain(const HParsedToken *t) {
case TT_SEQUENCE: case TT_SEQUENCE:
{ {
// Sequence of subdomains separated by "." // Sequence of subdomains separated by "."
return NULL; // Each subdomain is a label, which can be no more than 63 chars.
char *ret = h_arena_malloc(t->seq->arena, 64*t->seq->used);
size_t count = 0;
for (size_t i=0; i<t->seq->used; ++i) {
HParsedToken *tmp = t->seq->elements[i];
for (size_t j=0; j<tmp->seq->used; ++j) {
ret[count] = tmp->seq->elements[i]->uint;
++count;
}
ret[count] = '.';
++count;
}
ret[count-1] = '\x00';
return ret;
} }
default: default:
return NULL; return NULL;
} }
} }
void set_rr(struct dns_rr rr, HCountedArray *rdata) { void set_rr(struct dns_rr rr, HCountedArray *rdata) {
uint8_t *data = h_arena_malloc(rdata->arena, sizeof(uint8_t)*rdata->used);
for (size_t i=0; i<rdata->used; ++i)
data[i] = rdata->elements[i]->uint;
// If the RR doesn't parse, set its type to 0.
switch(rr.type) {
case 1: // A
{
const HParseResult *r = h_parse(init_a(), (const uint8_t*)data, rdata->used);
if (!r)
rr.type = 0;
else
rr.a = r->ast->seq->elements[0]->uint;
break;
}
case 2: // NS
{
const HParseResult *r = h_parse(init_ns(), (const uint8_t*)data, rdata->used);
if (!r)
rr.type = 0;
else
rr.ns = get_domain(r->ast->seq->elements[0]);
break;
}
case 3: // MD
{
const HParseResult *r = h_parse(init_md(), (const uint8_t*)data, rdata->used);
if (!r)
rr.type = 0;
else
rr.md = get_domain(r->ast->seq->elements[0]);
break;
}
case 4: // MF
{
const HParseResult *r = h_parse(init_mf(), (const uint8_t*)data, rdata->used);
if (!r)
rr.type = 0;
else
rr.md = get_domain(r->ast->seq->elements[0]);
break;
}
case 5: // CNAME
{
const HParseResult *r = h_parse(init_cname(), (const uint8_t*)data, rdata->used);
if (!r)
rr.type = 0;
else
rr.cname = get_domain(r->ast->seq->elements[0]);
break;
}
case 6: // SOA
{
const HParseResult *r = h_parse(init_soa(), (const uint8_t*)data, rdata->used);
if (!r)
rr.type = 0;
else {
rr.soa.mname = get_domain(r->ast->seq->elements[0]);
rr.soa.rname = get_domain(r->ast->seq->elements[1]);
rr.soa.serial = r->ast->seq->elements[2]->uint;
rr.soa.refresh = r->ast->seq->elements[3]->uint;
rr.soa.retry = r->ast->seq->elements[4]->uint;
rr.soa.expire = r->ast->seq->elements[5]->uint;
rr.soa.minimum = r->ast->seq->elements[6]->uint;
}
break;
}
case 7: // MB
{
const HParseResult *r = h_parse(init_mb(), (const uint8_t*)data, rdata->used);
if (!r)
rr.type = 0;
else
rr.mb = get_domain(r->ast->seq->elements[0]);
break;
}
case 8: // MG
{
const HParseResult *r = h_parse(init_mg(), (const uint8_t*)data, rdata->used);
if (!r)
rr.type = 0;
else
rr.mg = get_domain(r->ast->seq->elements[0]);
break;
}
case 9: // MR
{
const HParseResult *r = h_parse(init_mr(), (const uint8_t*)data, rdata->used);
if (!r)
rr.type = 0;
else
rr.mr = get_domain(r->ast->seq->elements[0]);
break;
}
case 10: // NULL
{
const HParseResult *r = h_parse(init_null(), (const uint8_t*)data, rdata->used);
if (!r)
rr.type = 0;
else {
rr.null = h_arena_malloc(rdata->arena, sizeof(uint8_t)*r->ast->seq->used);
for (size_t i=0; i<r->ast->seq->used; ++i)
rr.null[i] = r->ast->seq->elements[i]->uint;
}
break;
}
case 11: // WKS
{
const HParseResult *r = h_parse(init_wks(), (const uint8_t*)data, rdata->used);
if (!r)
rr.type = 0;
else {
rr.wks.address = r->ast->seq->elements[0]->uint;
rr.wks.protocol = r->ast->seq->elements[1]->uint;
rr.wks.len = r->ast->seq->elements[2]->seq->used;
rr.wks.bit_map = h_arena_malloc(rdata->arena, sizeof(uint8_t)*r->ast->seq->elements[2]->seq->used);
for (size_t i=0; i<rr.wks.len; ++i)
rr.wks.bit_map[i] = r->ast->seq->elements[2]->seq->elements[i]->uint;
}
break;
}
case 12: // PTR
{
const HParseResult *r = h_parse(init_ptr(), (const uint8_t*)data, rdata->used);
if (!r)
rr.type = 0;
else
rr.ptr = get_domain(r->ast->seq->elements[0]);
break;
}
case 13: // HINFO
{
const HParseResult *r = h_parse(init_hinfo(), (const uint8_t*)data, rdata->used);
if (!r)
rr.type = 0;
else {
rr.hinfo.cpu = get_cs(r->ast->seq->elements[0]);
rr.hinfo.os = get_cs(r->ast->seq->elements[1]);
}
break;
}
case 14: // MINFO
{
const HParseResult *r = h_parse(init_minfo(), (const uint8_t*)data, rdata->used);
if (!r)
rr.type = 0;
else {
rr.minfo.rmailbx = get_domain(r->ast->seq->elements[0]);
rr.minfo.emailbx = get_domain(r->ast->seq->elements[1]);
}
break;
}
case 15: // MX
{
const HParseResult *r = h_parse(init_mx(), (const uint8_t*)data, rdata->used);
if (!r)
rr.type = 0;
else {
rr.mx.preference = r->ast->seq->elements[0]->uint;
rr.mx.exchange = get_domain(r->ast->seq->elements[1]);
}
break;
}
case 16: // TXT
{
const HParseResult *r = h_parse(init_txt(), (const uint8_t*)data, rdata->used);
if (!r)
rr.type = 0;
else {
rr.txt.count = r->ast->seq->elements[0]->seq->used;
rr.txt.txt_data = get_txt(r->ast->seq->elements[0]);
}
break;
}
default:
break;
}
} }
const HParsedToken* pack_dns_struct(const HParseResult *p) { const HParsedToken* pack_dns_struct(const HParseResult *p) {
@ -113,7 +302,7 @@ const HParsedToken* pack_dns_struct(const HParseResult *p) {
for (size_t i=0; i<header.answer_count; ++i) { for (size_t i=0; i<header.answer_count; ++i) {
answers[i].name = get_domain(rrs[i].seq->elements[0]); answers[i].name = get_domain(rrs[i].seq->elements[0]);
answers[i].type = rrs[i].seq->elements[1]->uint; answers[i].type = rrs[i].seq->elements[1]->uint;
answers[i].type = rrs[i].seq->elements[2]->uint; answers[i].class = rrs[i].seq->elements[2]->uint;
answers[i].ttl = rrs[i].seq->elements[3]->uint; answers[i].ttl = rrs[i].seq->elements[3]->uint;
answers[i].rdlength = rrs[i].seq->elements[4]->seq->used; answers[i].rdlength = rrs[i].seq->elements[4]->seq->used;
set_rr(answers[i], rrs[i].seq->elements[4]->seq); set_rr(answers[i], rrs[i].seq->elements[4]->seq);
@ -125,7 +314,7 @@ const HParsedToken* pack_dns_struct(const HParseResult *p) {
for (size_t i=0, j=header.answer_count; i<header.authority_count; ++i, ++j) { for (size_t i=0, j=header.answer_count; i<header.authority_count; ++i, ++j) {
authority[i].name = get_domain(rrs[j].seq->elements[0]); authority[i].name = get_domain(rrs[j].seq->elements[0]);
authority[i].type = rrs[j].seq->elements[1]->uint; authority[i].type = rrs[j].seq->elements[1]->uint;
authority[i].type = rrs[j].seq->elements[2]->uint; authority[i].class = rrs[j].seq->elements[2]->uint;
authority[i].ttl = rrs[j].seq->elements[3]->uint; authority[i].ttl = rrs[j].seq->elements[3]->uint;
authority[i].rdlength = rrs[j].seq->elements[4]->seq->used; authority[i].rdlength = rrs[j].seq->elements[4]->seq->used;
set_rr(authority[i], rrs[j].seq->elements[4]->seq); set_rr(authority[i], rrs[j].seq->elements[4]->seq);
@ -137,7 +326,7 @@ const HParsedToken* pack_dns_struct(const HParseResult *p) {
for (size_t i=0, j=header.answer_count+header.authority_count; i<header.additional_count; ++i, ++j) { for (size_t i=0, j=header.answer_count+header.authority_count; i<header.additional_count; ++i, ++j) {
additional[i].name = get_domain(rrs[j].seq->elements[0]); additional[i].name = get_domain(rrs[j].seq->elements[0]);
additional[i].type = rrs[j].seq->elements[1]->uint; additional[i].type = rrs[j].seq->elements[1]->uint;
additional[i].type = rrs[j].seq->elements[2]->uint; additional[i].class = rrs[j].seq->elements[2]->uint;
additional[i].ttl = rrs[j].seq->elements[3]->uint; additional[i].ttl = rrs[j].seq->elements[3]->uint;
additional[i].rdlength = rrs[j].seq->elements[4]->seq->used; additional[i].rdlength = rrs[j].seq->elements[4]->seq->used;
set_rr(additional[i], rrs[j].seq->elements[4]->seq); set_rr(additional[i], rrs[j].seq->elements[4]->seq);

View file

@ -1,4 +1,5 @@
typedef int bool; #include "../src/hammer.h"
struct dns_header { struct dns_header {
uint16_t id; uint16_t id;
bool qr, aa, tc, rd, ra; bool qr, aa, tc, rd, ra;
@ -66,7 +67,7 @@ struct dns_rr {
uint32_t address; uint32_t address;
uint8_t protocol; uint8_t protocol;
size_t len; size_t len;
uint8_t** bit_map; uint8_t* bit_map;
} wks; } wks;
}; };
}; };