From 0c324adaa6d594407074baf25c2ce70a44e88a3c Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" <clonearmy@gmail.com> Date: Sat, 26 May 2012 15:50:39 +0200 Subject: [PATCH] Nearly done with RR parsing, need to write two helpers for this. --- examples/dns.c | 201 +++++++++++++++++++++++++++++++++++++++++++++++-- examples/dns.h | 5 +- 2 files changed, 198 insertions(+), 8 deletions(-) diff --git a/examples/dns.c b/examples/dns.c index faf9124..ae43594 100644 --- a/examples/dns.c +++ b/examples/dns.c @@ -1,6 +1,7 @@ #include "../src/hammer.h" #include "dns_common.h" #include "dns.h" +#include "rr.h" #define false 0 #define true 1 @@ -40,7 +41,7 @@ struct dns_qname get_qname(const HParsedToken *t) { 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)*ret.qlen) + .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) { @@ -60,16 +61,204 @@ char* get_domain(const HParsedToken *t) { case TT_SEQUENCE: { // 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: return NULL; } - } 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) { @@ -113,7 +302,7 @@ const HParsedToken* pack_dns_struct(const HParseResult *p) { for (size_t i=0; i<header.answer_count; ++i) { 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[2]->uint; + answers[i].class = rrs[i].seq->elements[2]->uint; answers[i].ttl = rrs[i].seq->elements[3]->uint; answers[i].rdlength = rrs[i].seq->elements[4]->seq->used; 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) { 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[2]->uint; + authority[i].class = rrs[j].seq->elements[2]->uint; authority[i].ttl = rrs[j].seq->elements[3]->uint; authority[i].rdlength = rrs[j].seq->elements[4]->seq->used; 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) { 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[2]->uint; + additional[i].class = rrs[j].seq->elements[2]->uint; additional[i].ttl = rrs[j].seq->elements[3]->uint; additional[i].rdlength = rrs[j].seq->elements[4]->seq->used; set_rr(additional[i], rrs[j].seq->elements[4]->seq); diff --git a/examples/dns.h b/examples/dns.h index 1d36103..151c46e 100644 --- a/examples/dns.h +++ b/examples/dns.h @@ -1,4 +1,5 @@ -typedef int bool; +#include "../src/hammer.h" + struct dns_header { uint16_t id; bool qr, aa, tc, rd, ra; @@ -66,7 +67,7 @@ struct dns_rr { uint32_t address; uint8_t protocol; size_t len; - uint8_t** bit_map; + uint8_t* bit_map; } wks; }; }; -- GitLab