diff options
Diffstat (limited to 'examples/ldns-testpkts.c')
-rw-r--r-- | examples/ldns-testpkts.c | 61 |
1 files changed, 58 insertions, 3 deletions
diff --git a/examples/ldns-testpkts.c b/examples/ldns-testpkts.c index be94eb2fe4385..ed26285c1f23f 100644 --- a/examples/ldns-testpkts.c +++ b/examples/ldns-testpkts.c @@ -118,6 +118,8 @@ static void matchline(char* line, struct entry* e) e->match_do = true; } else if(str_keyword(&parse, "noedns")) { e->match_noedns = true; + } else if(str_keyword(&parse, "ednsdata")) { + e->match_ednsdata_raw = true; } else if(str_keyword(&parse, "UDP")) { e->match_transport = transport_udp; } else if(str_keyword(&parse, "TCP")) { @@ -228,7 +230,7 @@ static void adjustline(char* line, struct entry* e, } /** create new entry */ -static struct entry* new_entry() +static struct entry* new_entry(void) { struct entry* e = LDNS_MALLOC(struct entry); memset(e, 0, sizeof(*e)); @@ -434,7 +436,9 @@ read_entry(FILE* in, const char* name, int *lineno, uint32_t* default_ttl, ldns_pkt_section add_section = LDNS_SECTION_QUESTION; struct reply_packet *cur_reply = NULL; bool reading_hex = false; + bool reading_hex_ednsdata = false; ldns_buffer* hex_data_buffer = NULL; + ldns_buffer* hex_ednsdata_buffer = NULL; while(fgets(line, (int)sizeof(line), in) != NULL) { line[MAX_LINE-1] = 0; @@ -497,12 +501,26 @@ read_entry(FILE* in, const char* name, int *lineno, uint32_t* default_ttl, cur_reply->reply_from_hex = data_buffer2wire(hex_data_buffer); ldns_buffer_free(hex_data_buffer); hex_data_buffer = NULL; + } else if(reading_hex) { + ldns_buffer_printf(hex_data_buffer, line); + } else if(str_keyword(&parse, "HEX_EDNSDATA_BEGIN")) { + hex_ednsdata_buffer = ldns_buffer_new(LDNS_MAX_PACKETLEN); + reading_hex_ednsdata = true; + } else if(str_keyword(&parse, "HEX_EDNSDATA_END")) { + if (!reading_hex_ednsdata) { + error("%s line %d: HEX_EDNSDATA_END read but no" + "HEX_EDNSDATA_BEGIN keyword seen", name, *lineno); + } + reading_hex_ednsdata = false; + cur_reply->raw_ednsdata = data_buffer2wire(hex_ednsdata_buffer); + ldns_buffer_free(hex_ednsdata_buffer); + hex_ednsdata_buffer = NULL; + } else if(reading_hex_ednsdata) { + ldns_buffer_printf(hex_ednsdata_buffer, line); } else if(str_keyword(&parse, "ENTRY_END")) { if (hex_data_buffer) ldns_buffer_free(hex_data_buffer); return current; - } else if(reading_hex) { - ldns_buffer_printf(hex_data_buffer, line); } else { /* it must be a RR, parse and add to packet. */ ldns_rr* n = NULL; @@ -674,6 +692,38 @@ match_all(ldns_pkt* q, ldns_pkt* p, bool mttl) return 1; } +/** Convert to hexstring and call verbose(), prepend with header */ +static void +verbose_hex(int lvl, uint8_t *data, size_t datalen, const char *header) +{ + verbose(lvl, "%s", header); + while (datalen-- > 0) { + verbose(lvl, " %02x", (unsigned int)*data++); + } + verbose(lvl, "\n"); +} + +/** Match q edns data to p raw edns data */ +static int +match_ednsdata(ldns_pkt* q, struct reply_packet* p) +{ + size_t qdlen, pdlen; + uint8_t *qd, *pd; + if(!ldns_pkt_edns(q) || !ldns_pkt_edns_data(q)) { + verbose(3, "No EDNS data\n"); + return 0; + } + qdlen = ldns_rdf_size(ldns_pkt_edns_data(q)); + pdlen = ldns_buffer_limit(p->raw_ednsdata); + qd = ldns_rdf_data(ldns_pkt_edns_data(q)); + pd = ldns_buffer_begin(p->raw_ednsdata); + if( qdlen == pdlen && 0 == memcmp(qd, pd, qdlen) ) return 1; + verbose(3, "EDNS data does not match.\n"); + verbose_hex(3, qd, qdlen, "q:"); + verbose_hex(3, pd, pdlen, "p:"); + return 0; +} + /* finds entry in list, or returns NULL */ struct entry* find_match(struct entry* entries, ldns_pkt* query_pkt, @@ -724,6 +774,11 @@ find_match(struct entry* entries, ldns_pkt* query_pkt, verbose(3, "bad; EDNS OPT present\n"); continue; } + if(p->match_ednsdata_raw && + !match_ednsdata(query_pkt, p->reply_list)) { + verbose(3, "bad EDNS data match.\n"); + continue; + } if(p->match_transport != transport_any && p->match_transport != transport) { verbose(3, "bad transport\n"); continue; |