]> git.ipfire.org Git - thirdparty/ldns.git/commitdiff
compare edns payload to raw bytes
authorYuri Schaeffer <yuri@NLnetLabs.nl>
Fri, 18 Jan 2013 15:03:49 +0000 (15:03 +0000)
committerYuri Schaeffer <yuri@NLnetLabs.nl>
Fri, 18 Jan 2013 15:03:49 +0000 (15:03 +0000)
examples/ldns-testpkts.c

index be94eb2fe43859d2efd466a6b60c6d0f718378cf..81fb1b36f6f56aee92e63a836bf8b08b2d73806f 100644 (file)
@@ -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")) {
@@ -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,40 @@ match_all(ldns_pkt* q, ldns_pkt* p, bool mttl)
        return 1;
 }
 
+/** Convert to hexstring and call verbose(), prepend with header */
+void
+verbose_hex(int lvl, uint8_t *data, size_t datalen, char *header)
+{
+       size_t i;
+       char errmsg[strlen(header) + datalen*3];
+       strcpy(errmsg, header);
+       for(i = 0; i < datalen; i++)
+               sprintf(errmsg + strlen(header) + i*3, "%02x ", data[i]);
+       errmsg[strlen(header) + datalen*3 - 1] = 0;
+       verbose(lvl, errmsg);
+}
+
+/** 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 +776,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;