1 /*
2 * testpkts. Data file parse for test packets, and query matching.
3 *
4 * Data storage for specially crafted replies for testing purposes.
5 *
6 * (c) NLnet Labs, 2005, 2006, 2007, 2008
7 * See the file LICENSE for the license
8 */
9
10 /**
11 * \file
12 * This is a debugging aid. It is not efficient, especially
13 * with a long config file, but it can give any reply to any query.
14 * This can help the developer pre-script replies for queries.
15 *
16 * You can specify a packet RR by RR with header flags to return.
17 *
18 * Missing features:
19 * - matching content different from reply content.
20 * - find way to adjust mangled packets?
21 */
22
23 #include "config.h"
24 #include <errno.h>
25 #include <stdarg.h>
26 #include <ctype.h>
27 #include "testcode/testpkts.h"
28 #include "util/net_help.h"
29 #include "sldns/sbuffer.h"
30 #include "sldns/rrdef.h"
31 #include "sldns/pkthdr.h"
32 #include "sldns/str2wire.h"
33 #include "sldns/wire2str.h"
34
35 /** max size of a packet */
36 #define MAX_PACKETLEN 65536
37 /** max line length */
38 #define MAX_LINE 10240
39 /** string to show in warnings and errors */
40 static const char* prog_name = "testpkts";
41
42 #ifndef UTIL_LOG_H
43 /** verbosity definition for compat */
44 enum verbosity_value { NO_VERBOSE=0 };
45 #endif
46 /** logging routine, provided by caller */
47 void verbose(enum verbosity_value lvl, const char* msg, ...) ATTR_FORMAT(printf, 2, 3);
48 static void error(const char* msg, ...) ATTR_NORETURN;
49
50 /** print error and exit */
error(const char * msg,...)51 static void error(const char* msg, ...)
52 {
53 va_list args;
54 va_start(args, msg);
55 fprintf(stderr, "%s error: ", prog_name);
56 vfprintf(stderr, msg, args);
57 fprintf(stderr, "\n");
58 fflush(stderr);
59 va_end(args);
60 exit(EXIT_FAILURE);
61 }
62
63 /** return if string is empty or comment */
isendline(char c)64 static int isendline(char c)
65 {
66 if(c == ';' || c == '#'
67 || c == '\n' || c == 0)
68 return 1;
69 return 0;
70 }
71
72 /** true if the string starts with the keyword given. Moves the str ahead.
73 * @param str: before keyword, afterwards after keyword and spaces.
74 * @param keyword: the keyword to match
75 * @return: true if keyword present. False otherwise, and str unchanged.
76 */
str_keyword(char ** str,const char * keyword)77 static int str_keyword(char** str, const char* keyword)
78 {
79 size_t len = strlen(keyword);
80 assert(str && keyword);
81 if(strncmp(*str, keyword, len) != 0)
82 return 0;
83 *str += len;
84 while(isspace((unsigned char)**str))
85 (*str)++;
86 return 1;
87 }
88
89 /** Add reply packet to entry */
90 static struct reply_packet*
entry_add_reply(struct entry * entry)91 entry_add_reply(struct entry* entry)
92 {
93 struct reply_packet* pkt = (struct reply_packet*)malloc(
94 sizeof(struct reply_packet));
95 struct reply_packet ** p = &entry->reply_list;
96 if(!pkt) error("out of memory");
97 pkt->next = NULL;
98 pkt->packet_sleep = 0;
99 pkt->reply_pkt = NULL;
100 pkt->reply_from_hex = NULL;
101 pkt->raw_ednsdata = NULL;
102 /* link at end */
103 while(*p)
104 p = &((*p)->next);
105 *p = pkt;
106 return pkt;
107 }
108
109 /** parse MATCH line */
matchline(char * line,struct entry * e)110 static void matchline(char* line, struct entry* e)
111 {
112 char* parse = line;
113 while(*parse) {
114 if(isendline(*parse))
115 return;
116 if(str_keyword(&parse, "opcode")) {
117 e->match_opcode = 1;
118 } else if(str_keyword(&parse, "qtype")) {
119 e->match_qtype = 1;
120 } else if(str_keyword(&parse, "qname")) {
121 e->match_qname = 1;
122 } else if(str_keyword(&parse, "rcode")) {
123 e->match_rcode = 1;
124 } else if(str_keyword(&parse, "question")) {
125 e->match_question = 1;
126 } else if(str_keyword(&parse, "answer")) {
127 e->match_answer = 1;
128 } else if(str_keyword(&parse, "subdomain")) {
129 e->match_subdomain = 1;
130 } else if(str_keyword(&parse, "all_noedns")) {
131 e->match_all_noedns = 1;
132 } else if(str_keyword(&parse, "all")) {
133 e->match_all = 1;
134 } else if(str_keyword(&parse, "ttl")) {
135 e->match_ttl = 1;
136 } else if(str_keyword(&parse, "DO")) {
137 e->match_do = 1;
138 } else if(str_keyword(&parse, "noedns")) {
139 e->match_noedns = 1;
140 } else if(str_keyword(&parse, "ednsdata")) {
141 e->match_ednsdata_raw = 1;
142 } else if(str_keyword(&parse, "client_cookie")) {
143 e->match_client_cookie = 1;
144 } else if(str_keyword(&parse, "server_cookie")) {
145 e->match_server_cookie = 1;
146 } else if(str_keyword(&parse, "UDP")) {
147 e->match_transport = transport_udp;
148 } else if(str_keyword(&parse, "TCP")) {
149 e->match_transport = transport_tcp;
150 } else if(str_keyword(&parse, "serial")) {
151 e->match_serial = 1;
152 if(*parse != '=' && *parse != ':')
153 error("expected = or : in MATCH: %s", line);
154 parse++;
155 e->ixfr_soa_serial = (uint32_t)strtol(parse, (char**)&parse, 10);
156 while(isspace((unsigned char)*parse))
157 parse++;
158 } else if(str_keyword(&parse, "ede")) {
159 e->match_ede = 1;
160 if(*parse != '=' && *parse != ':')
161 error("expected = or : in MATCH: %s", line);
162 parse++;
163 while(isspace((unsigned char)*parse))
164 parse++;
165 if(str_keyword(&parse, "any")) {
166 e->match_ede_any = 1;
167 } else {
168 e->ede_info_code = (uint16_t)strtol(parse,
169 (char**)&parse, 10);
170 }
171 while(isspace((unsigned char)*parse))
172 parse++;
173 } else {
174 error("could not parse MATCH: '%s'", parse);
175 }
176 }
177 }
178
179 /** parse REPLY line */
replyline(char * line,uint8_t * reply,size_t reply_len,int * do_flag)180 static void replyline(char* line, uint8_t* reply, size_t reply_len,
181 int* do_flag)
182 {
183 char* parse = line;
184 if(reply_len < LDNS_HEADER_SIZE) error("packet too short for header");
185 while(*parse) {
186 if(isendline(*parse))
187 return;
188 /* opcodes */
189 if(str_keyword(&parse, "QUERY")) {
190 LDNS_OPCODE_SET(reply, LDNS_PACKET_QUERY);
191 } else if(str_keyword(&parse, "IQUERY")) {
192 LDNS_OPCODE_SET(reply, LDNS_PACKET_IQUERY);
193 } else if(str_keyword(&parse, "STATUS")) {
194 LDNS_OPCODE_SET(reply, LDNS_PACKET_STATUS);
195 } else if(str_keyword(&parse, "NOTIFY")) {
196 LDNS_OPCODE_SET(reply, LDNS_PACKET_NOTIFY);
197 } else if(str_keyword(&parse, "UPDATE")) {
198 LDNS_OPCODE_SET(reply, LDNS_PACKET_UPDATE);
199 /* rcodes */
200 } else if(str_keyword(&parse, "NOERROR")) {
201 LDNS_RCODE_SET(reply, LDNS_RCODE_NOERROR);
202 } else if(str_keyword(&parse, "FORMERR")) {
203 LDNS_RCODE_SET(reply, LDNS_RCODE_FORMERR);
204 } else if(str_keyword(&parse, "SERVFAIL")) {
205 LDNS_RCODE_SET(reply, LDNS_RCODE_SERVFAIL);
206 } else if(str_keyword(&parse, "NXDOMAIN")) {
207 LDNS_RCODE_SET(reply, LDNS_RCODE_NXDOMAIN);
208 } else if(str_keyword(&parse, "NOTIMPL")) {
209 LDNS_RCODE_SET(reply, LDNS_RCODE_NOTIMPL);
210 } else if(str_keyword(&parse, "REFUSED")) {
211 LDNS_RCODE_SET(reply, LDNS_RCODE_REFUSED);
212 } else if(str_keyword(&parse, "YXDOMAIN")) {
213 LDNS_RCODE_SET(reply, LDNS_RCODE_YXDOMAIN);
214 } else if(str_keyword(&parse, "YXRRSET")) {
215 LDNS_RCODE_SET(reply, LDNS_RCODE_YXRRSET);
216 } else if(str_keyword(&parse, "NXRRSET")) {
217 LDNS_RCODE_SET(reply, LDNS_RCODE_NXRRSET);
218 } else if(str_keyword(&parse, "NOTAUTH")) {
219 LDNS_RCODE_SET(reply, LDNS_RCODE_NOTAUTH);
220 } else if(str_keyword(&parse, "NOTZONE")) {
221 LDNS_RCODE_SET(reply, LDNS_RCODE_NOTZONE);
222 /* flags */
223 } else if(str_keyword(&parse, "QR")) {
224 LDNS_QR_SET(reply);
225 } else if(str_keyword(&parse, "AA")) {
226 LDNS_AA_SET(reply);
227 } else if(str_keyword(&parse, "TC")) {
228 LDNS_TC_SET(reply);
229 } else if(str_keyword(&parse, "RD")) {
230 LDNS_RD_SET(reply);
231 } else if(str_keyword(&parse, "CD")) {
232 LDNS_CD_SET(reply);
233 } else if(str_keyword(&parse, "RA")) {
234 LDNS_RA_SET(reply);
235 } else if(str_keyword(&parse, "AD")) {
236 LDNS_AD_SET(reply);
237 } else if(str_keyword(&parse, "DO")) {
238 *do_flag = 1;
239 } else {
240 error("could not parse REPLY: '%s'", parse);
241 }
242 }
243 }
244
245 /** parse ADJUST line */
adjustline(char * line,struct entry * e,struct reply_packet * pkt)246 static void adjustline(char* line, struct entry* e,
247 struct reply_packet* pkt)
248 {
249 char* parse = line;
250 while(*parse) {
251 if(isendline(*parse))
252 return;
253 if(str_keyword(&parse, "copy_id")) {
254 e->copy_id = 1;
255 } else if(str_keyword(&parse, "copy_query")) {
256 e->copy_query = 1;
257 } else if(str_keyword(&parse, "copy_ednsdata_assume_clientsubnet")) {
258 e->copy_ednsdata_assume_clientsubnet = 1;
259 } else if(str_keyword(&parse, "increment_ecs_scope")) {
260 e->increment_ecs_scope = 1;
261 } else if(str_keyword(&parse, "sleep=")) {
262 e->sleeptime = (unsigned int) strtol(parse, (char**)&parse, 10);
263 while(isspace((unsigned char)*parse))
264 parse++;
265 } else if(str_keyword(&parse, "packet_sleep=")) {
266 pkt->packet_sleep = (unsigned int) strtol(parse, (char**)&parse, 10);
267 while(isspace((unsigned char)*parse))
268 parse++;
269 } else {
270 error("could not parse ADJUST: '%s'", parse);
271 }
272 }
273 }
274
275 /** create new entry */
new_entry(void)276 static struct entry* new_entry(void)
277 {
278 struct entry* e = (struct entry*)malloc(sizeof(struct entry));
279 if(!e) error("out of memory");
280 memset(e, 0, sizeof(*e));
281 e->match_opcode = 0;
282 e->match_qtype = 0;
283 e->match_qname = 0;
284 e->match_rcode = 0;
285 e->match_question = 0;
286 e->match_answer = 0;
287 e->match_subdomain = 0;
288 e->match_all = 0;
289 e->match_all_noedns = 0;
290 e->match_ttl = 0;
291 e->match_do = 0;
292 e->match_noedns = 0;
293 e->match_serial = 0;
294 e->ixfr_soa_serial = 0;
295 e->match_ede = 0;
296 e->match_ede_any = 0;
297 e->ede_info_code = -1;
298 e->match_transport = transport_any;
299 e->reply_list = NULL;
300 e->copy_id = 0;
301 e->copy_query = 0;
302 e->copy_ednsdata_assume_clientsubnet = 0;
303 e->increment_ecs_scope = 0;
304 e->sleeptime = 0;
305 e->next = NULL;
306 return e;
307 }
308
309 /**
310 * Converts a hex string to binary data
311 * @param hexstr: string of hex.
312 * @param len: is the length of the string
313 * @param buf: is the buffer to store the result in
314 * @param offset: is the starting position in the result buffer
315 * @param buf_len: is the length of buf.
316 * @return This function returns the length of the result
317 */
318 static size_t
hexstr2bin(char * hexstr,int len,uint8_t * buf,size_t offset,size_t buf_len)319 hexstr2bin(char *hexstr, int len, uint8_t *buf, size_t offset, size_t buf_len)
320 {
321 char c;
322 int i;
323 uint8_t int8 = 0;
324 int sec = 0;
325 size_t bufpos = 0;
326
327 if (len % 2 != 0) {
328 return 0;
329 }
330
331 for (i=0; i<len; i++) {
332 c = hexstr[i];
333
334 /* case insensitive, skip spaces */
335 if (c != ' ') {
336 if (c >= '0' && c <= '9') {
337 int8 += c & 0x0f;
338 } else if (c >= 'a' && c <= 'z') {
339 int8 += (c & 0x0f) + 9;
340 } else if (c >= 'A' && c <= 'Z') {
341 int8 += (c & 0x0f) + 9;
342 } else {
343 return 0;
344 }
345
346 if (sec == 0) {
347 int8 = int8 << 4;
348 sec = 1;
349 } else {
350 if (bufpos + offset + 1 <= buf_len) {
351 buf[bufpos+offset] = int8;
352 int8 = 0;
353 sec = 0;
354 bufpos++;
355 } else {
356 fprintf(stderr, "Buffer too small in hexstr2bin");
357 }
358 }
359 }
360 }
361 return bufpos;
362 }
363
364 /** convert hex buffer to binary buffer */
365 static sldns_buffer *
hex_buffer2wire(sldns_buffer * data_buffer)366 hex_buffer2wire(sldns_buffer *data_buffer)
367 {
368 sldns_buffer *wire_buffer = NULL;
369 int c;
370
371 /* stat hack
372 * 0 = normal
373 * 1 = comment (skip to end of line)
374 * 2 = unprintable character found, read binary data directly
375 */
376 size_t data_buf_pos = 0;
377 int state = 0;
378 uint8_t *hexbuf;
379 int hexbufpos = 0;
380 size_t wirelen;
381 uint8_t *data_wire = (uint8_t *) sldns_buffer_begin(data_buffer);
382 uint8_t *wire = (uint8_t*)malloc(MAX_PACKETLEN);
383 if(!wire) error("out of memory");
384
385 hexbuf = (uint8_t*)malloc(MAX_PACKETLEN);
386 if(!hexbuf) error("out of memory");
387 for (data_buf_pos = 0; data_buf_pos < sldns_buffer_position(data_buffer); data_buf_pos++) {
388 c = (int) data_wire[data_buf_pos];
389
390 if (state < 2 && !isascii((unsigned char)c)) {
391 /*verbose("non ascii character found in file: (%d) switching to raw mode\n", c);*/
392 state = 2;
393 }
394 switch (state) {
395 case 0:
396 if ( (c >= '0' && c <= '9') ||
397 (c >= 'a' && c <= 'f') ||
398 (c >= 'A' && c <= 'F') )
399 {
400 if (hexbufpos >= MAX_PACKETLEN) {
401 error("buffer overflow");
402 free(hexbuf);
403 return 0;
404
405 }
406 hexbuf[hexbufpos] = (uint8_t) c;
407 hexbufpos++;
408 } else if (c == ';') {
409 state = 1;
410 } else if (c == ' ' || c == '\t' || c == '\n') {
411 /* skip whitespace */
412 }
413 break;
414 case 1:
415 if (c == '\n' || c == EOF) {
416 state = 0;
417 }
418 break;
419 case 2:
420 if (hexbufpos >= MAX_PACKETLEN) {
421 error("buffer overflow");
422 free(hexbuf);
423 return 0;
424 }
425 hexbuf[hexbufpos] = (uint8_t) c;
426 hexbufpos++;
427 break;
428 }
429 }
430
431 if (hexbufpos >= MAX_PACKETLEN) {
432 /*verbose("packet size reached\n");*/
433 }
434
435 /* lenient mode: length must be multiple of 2 */
436 if (hexbufpos % 2 != 0) {
437 if (hexbufpos >= MAX_PACKETLEN) {
438 error("buffer overflow");
439 free(hexbuf);
440 return 0;
441 }
442 hexbuf[hexbufpos] = (uint8_t) '0';
443 hexbufpos++;
444 }
445
446 if (state < 2) {
447 wirelen = hexstr2bin((char *) hexbuf, hexbufpos, wire, 0, MAX_PACKETLEN);
448 wire_buffer = sldns_buffer_new(wirelen);
449 sldns_buffer_new_frm_data(wire_buffer, wire, wirelen);
450 } else {
451 error("Incomplete hex data, not at byte boundary\n");
452 }
453 free(wire);
454 free(hexbuf);
455 return wire_buffer;
456 }
457
458 /** parse ORIGIN */
459 static void
get_origin(const char * name,struct sldns_file_parse_state * pstate,char * parse)460 get_origin(const char* name, struct sldns_file_parse_state* pstate, char* parse)
461 {
462 /* snip off rest of the text so as to make the parse work in ldns */
463 char* end;
464 char store;
465 int status;
466
467 end=parse;
468 while(!isspace((unsigned char)*end) && !isendline(*end))
469 end++;
470 store = *end;
471 *end = 0;
472 verbose(3, "parsing '%s'\n", parse);
473 status = sldns_str2wire_dname_buf(parse, pstate->origin,
474 &pstate->origin_len);
475 *end = store;
476 if(status != 0)
477 error("%s line %d:\n\t%s: %s", name, pstate->lineno,
478 sldns_get_errorstr_parse(status), parse);
479 }
480
481 /** add RR to packet */
add_rr(char * rrstr,uint8_t * pktbuf,size_t pktsize,size_t * pktlen,struct sldns_file_parse_state * pstate,sldns_pkt_section add_section,const char * fname)482 static void add_rr(char* rrstr, uint8_t* pktbuf, size_t pktsize,
483 size_t* pktlen, struct sldns_file_parse_state* pstate,
484 sldns_pkt_section add_section, const char* fname)
485 {
486 /* it must be a RR, parse and add to packet. */
487 size_t rr_len = pktsize - *pktlen;
488 size_t dname_len = 0;
489 int status;
490 uint8_t* origin = pstate->origin_len?pstate->origin:0;
491 uint8_t* prev = pstate->prev_rr_len?pstate->prev_rr:0;
492 if(*pktlen > pktsize || *pktlen < LDNS_HEADER_SIZE)
493 error("packet overflow");
494
495 /* parse RR */
496 if(add_section == LDNS_SECTION_QUESTION)
497 status = sldns_str2wire_rr_question_buf(rrstr, pktbuf+*pktlen,
498 &rr_len, &dname_len, origin, pstate->origin_len,
499 prev, pstate->prev_rr_len);
500 else status = sldns_str2wire_rr_buf(rrstr, pktbuf+*pktlen, &rr_len,
501 &dname_len, pstate->default_ttl, origin,
502 pstate->origin_len, prev, pstate->prev_rr_len);
503 if(status != 0)
504 error("%s line %d:%d %s\n\t%s", fname, pstate->lineno,
505 LDNS_WIREPARSE_OFFSET(status),
506 sldns_get_errorstr_parse(status), rrstr);
507 *pktlen += rr_len;
508
509 /* increase RR count */
510 if(add_section == LDNS_SECTION_QUESTION)
511 sldns_write_uint16(pktbuf+4, LDNS_QDCOUNT(pktbuf)+1);
512 else if(add_section == LDNS_SECTION_ANSWER)
513 sldns_write_uint16(pktbuf+6, LDNS_ANCOUNT(pktbuf)+1);
514 else if(add_section == LDNS_SECTION_AUTHORITY)
515 sldns_write_uint16(pktbuf+8, LDNS_NSCOUNT(pktbuf)+1);
516 else if(add_section == LDNS_SECTION_ADDITIONAL)
517 sldns_write_uint16(pktbuf+10, LDNS_ARCOUNT(pktbuf)+1);
518 else error("internal error bad section %d", (int)add_section);
519 }
520
521 /* add EDNS 4096 opt record */
522 static void
add_edns(uint8_t * pktbuf,size_t pktsize,int do_flag,uint8_t * ednsdata,uint16_t ednslen,size_t * pktlen)523 add_edns(uint8_t* pktbuf, size_t pktsize, int do_flag, uint8_t *ednsdata,
524 uint16_t ednslen, size_t* pktlen)
525 {
526 uint8_t edns[] = {0x00, /* root label */
527 0x00, LDNS_RR_TYPE_OPT, /* type */
528 0x04, 0xD0, /* class is UDPSIZE 1232 */
529 0x00, /* TTL[0] is ext rcode */
530 0x00, /* TTL[1] is edns version */
531 (uint8_t)(do_flag?0x80:0x00), 0x00, /* TTL[2-3] is edns flags, DO */
532 (uint8_t)((ednslen >> 8) & 0xff),
533 (uint8_t)(ednslen & 0xff), /* rdatalength */
534 };
535 if(*pktlen < LDNS_HEADER_SIZE)
536 return;
537 if(*pktlen + sizeof(edns) + ednslen > pktsize)
538 error("not enough space for EDNS OPT record");
539 memmove(pktbuf+*pktlen, edns, sizeof(edns));
540 if(ednsdata && ednslen)
541 memmove(pktbuf+*pktlen+sizeof(edns), ednsdata, ednslen);
542 sldns_write_uint16(pktbuf+10, LDNS_ARCOUNT(pktbuf)+1);
543 *pktlen += (sizeof(edns) + ednslen);
544 }
545
546 /* Reads one entry from file. Returns entry or NULL on error. */
547 struct entry*
read_entry(FILE * in,const char * name,struct sldns_file_parse_state * pstate,int skip_whitespace)548 read_entry(FILE* in, const char* name, struct sldns_file_parse_state* pstate,
549 int skip_whitespace)
550 {
551 struct entry* current = NULL;
552 char line[MAX_LINE];
553 char* parse;
554 sldns_pkt_section add_section = LDNS_SECTION_QUESTION;
555 struct reply_packet *cur_reply = NULL;
556 int reading_hex = 0;
557 int reading_hex_ednsdata = 0;
558 sldns_buffer* hex_data_buffer = NULL;
559 sldns_buffer* hex_ednsdata_buffer = NULL;
560 uint8_t pktbuf[MAX_PACKETLEN];
561 size_t pktlen = LDNS_HEADER_SIZE;
562 int do_flag = 0; /* DO flag in EDNS */
563 memset(pktbuf, 0, pktlen); /* ID = 0, FLAGS="", and rr counts 0 */
564
565 while(fgets(line, (int)sizeof(line), in) != NULL) {
566 line[MAX_LINE-1] = 0;
567 parse = line;
568 pstate->lineno++;
569
570 while(isspace((unsigned char)*parse))
571 parse++;
572 /* test for keywords */
573 if(isendline(*parse))
574 continue; /* skip comment and empty lines */
575 if(str_keyword(&parse, "ENTRY_BEGIN")) {
576 if(current) {
577 error("%s line %d: previous entry does not ENTRY_END",
578 name, pstate->lineno);
579 }
580 current = new_entry();
581 current->lineno = pstate->lineno;
582 cur_reply = entry_add_reply(current);
583 continue;
584 } else if(str_keyword(&parse, "$ORIGIN")) {
585 get_origin(name, pstate, parse);
586 continue;
587 } else if(str_keyword(&parse, "$TTL")) {
588 pstate->default_ttl = (uint32_t)atoi(parse);
589 continue;
590 }
591
592 /* working inside an entry */
593 if(!current) {
594 error("%s line %d: expected ENTRY_BEGIN but got %s",
595 name, pstate->lineno, line);
596 }
597 if(str_keyword(&parse, "MATCH")) {
598 matchline(parse, current);
599 } else if(str_keyword(&parse, "REPLY")) {
600 replyline(parse, pktbuf, pktlen, &do_flag);
601 } else if(str_keyword(&parse, "ADJUST")) {
602 adjustline(parse, current, cur_reply);
603 } else if(str_keyword(&parse, "EXTRA_PACKET")) {
604 /* copy current packet into buffer */
605 cur_reply->reply_pkt = memdup(pktbuf, pktlen);
606 cur_reply->reply_len = pktlen;
607 if(!cur_reply->reply_pkt)
608 error("out of memory");
609 cur_reply = entry_add_reply(current);
610 /* clear for next packet */
611 pktlen = LDNS_HEADER_SIZE;
612 memset(pktbuf, 0, pktlen); /* ID = 0, FLAGS="", and rr counts 0 */
613 } else if(str_keyword(&parse, "SECTION")) {
614 if(str_keyword(&parse, "QUESTION"))
615 add_section = LDNS_SECTION_QUESTION;
616 else if(str_keyword(&parse, "ANSWER"))
617 add_section = LDNS_SECTION_ANSWER;
618 else if(str_keyword(&parse, "AUTHORITY"))
619 add_section = LDNS_SECTION_AUTHORITY;
620 else if(str_keyword(&parse, "ADDITIONAL"))
621 add_section = LDNS_SECTION_ADDITIONAL;
622 else error("%s line %d: bad section %s", name, pstate->lineno, parse);
623 } else if(str_keyword(&parse, "HEX_ANSWER_BEGIN")) {
624 hex_data_buffer = sldns_buffer_new(MAX_PACKETLEN);
625 reading_hex = 1;
626 } else if(str_keyword(&parse, "HEX_ANSWER_END")) {
627 if(!reading_hex) {
628 error("%s line %d: HEX_ANSWER_END read but no HEX_ANSWER_BEGIN keyword seen", name, pstate->lineno);
629 }
630 reading_hex = 0;
631 cur_reply->reply_from_hex = hex_buffer2wire(hex_data_buffer);
632 sldns_buffer_free(hex_data_buffer);
633 hex_data_buffer = NULL;
634 } else if(reading_hex) {
635 sldns_buffer_printf(hex_data_buffer, "%s", line);
636 } else if(str_keyword(&parse, "HEX_EDNSDATA_BEGIN")) {
637 hex_ednsdata_buffer = sldns_buffer_new(MAX_PACKETLEN);
638 reading_hex_ednsdata = 1;
639 } else if(str_keyword(&parse, "HEX_EDNSDATA_END")) {
640 if (!reading_hex_ednsdata) {
641 error("%s line %d: HEX_EDNSDATA_END read but no"
642 "HEX_EDNSDATA_BEGIN keyword seen", name, pstate->lineno);
643 }
644 reading_hex_ednsdata = 0;
645 cur_reply->raw_ednsdata = hex_buffer2wire(hex_ednsdata_buffer);
646 sldns_buffer_free(hex_ednsdata_buffer);
647 hex_ednsdata_buffer = NULL;
648 } else if(reading_hex_ednsdata) {
649 sldns_buffer_printf(hex_ednsdata_buffer, "%s", line);
650 } else if(str_keyword(&parse, "ENTRY_END")) {
651 if(hex_data_buffer)
652 sldns_buffer_free(hex_data_buffer);
653 if(hex_ednsdata_buffer)
654 sldns_buffer_free(hex_ednsdata_buffer);
655 if(pktlen != 0) {
656 if(do_flag || cur_reply->raw_ednsdata) {
657 if(cur_reply->raw_ednsdata &&
658 sldns_buffer_limit(cur_reply->raw_ednsdata))
659 add_edns(pktbuf, sizeof(pktbuf), do_flag,
660 sldns_buffer_begin(cur_reply->raw_ednsdata),
661 (uint16_t)sldns_buffer_limit(cur_reply->raw_ednsdata),
662 &pktlen);
663 else
664 add_edns(pktbuf, sizeof(pktbuf), do_flag,
665 NULL, 0, &pktlen);
666 }
667 cur_reply->reply_pkt = memdup(pktbuf, pktlen);
668 cur_reply->reply_len = pktlen;
669 if(!cur_reply->reply_pkt)
670 error("out of memory");
671 }
672 return current;
673 } else {
674 add_rr(skip_whitespace?parse:line, pktbuf,
675 sizeof(pktbuf), &pktlen, pstate, add_section,
676 name);
677 }
678
679 }
680 if(reading_hex) {
681 error("%s: End of file reached while still reading hex, "
682 "missing HEX_ANSWER_END\n", name);
683 }
684 if(reading_hex_ednsdata) {
685 error("%s: End of file reached while still reading edns data, "
686 "missing HEX_EDNSDATA_END\n", name);
687 }
688 if(current) {
689 error("%s: End of file reached while reading entry. "
690 "missing ENTRY_END\n", name);
691 }
692 return 0;
693 }
694
695 /* reads the canned reply file and returns a list of structs */
696 struct entry*
read_datafile(const char * name,int skip_whitespace)697 read_datafile(const char* name, int skip_whitespace)
698 {
699 struct entry* list = NULL;
700 struct entry* last = NULL;
701 struct entry* current = NULL;
702 FILE *in;
703 struct sldns_file_parse_state pstate;
704 int entry_num = 0;
705 memset(&pstate, 0, sizeof(pstate));
706
707 if((in=fopen(name, "r")) == NULL) {
708 error("could not open file %s: %s", name, strerror(errno));
709 }
710
711 while((current = read_entry(in, name, &pstate, skip_whitespace)))
712 {
713 if(last)
714 last->next = current;
715 else list = current;
716 last = current;
717 entry_num ++;
718 }
719 verbose(1, "%s: Read %d entries\n", prog_name, entry_num);
720
721 fclose(in);
722 return list;
723 }
724
725 /** get qtype from packet */
get_qtype(uint8_t * pkt,size_t pktlen)726 static sldns_rr_type get_qtype(uint8_t* pkt, size_t pktlen)
727 {
728 uint8_t* d;
729 size_t dl, sl=0;
730 char* snull = NULL;
731 int comprloop = 0;
732 if(pktlen < LDNS_HEADER_SIZE)
733 return 0;
734 if(LDNS_QDCOUNT(pkt) == 0)
735 return 0;
736 /* skip over dname with dname-scan routine */
737 d = pkt+LDNS_HEADER_SIZE;
738 dl = pktlen-LDNS_HEADER_SIZE;
739 (void)sldns_wire2str_dname_scan(&d, &dl, &snull, &sl, pkt, pktlen, &comprloop);
740 if(dl < 2)
741 return 0;
742 return sldns_read_uint16(d);
743 }
744
745 /** get qtype from packet */
get_qname_len(uint8_t * pkt,size_t pktlen)746 static size_t get_qname_len(uint8_t* pkt, size_t pktlen)
747 {
748 uint8_t* d;
749 size_t dl, sl=0;
750 char* snull = NULL;
751 int comprloop = 0;
752 if(pktlen < LDNS_HEADER_SIZE)
753 return 0;
754 if(LDNS_QDCOUNT(pkt) == 0)
755 return 0;
756 /* skip over dname with dname-scan routine */
757 d = pkt+LDNS_HEADER_SIZE;
758 dl = pktlen-LDNS_HEADER_SIZE;
759 (void)sldns_wire2str_dname_scan(&d, &dl, &snull, &sl, pkt, pktlen, &comprloop);
760 return pktlen-dl-LDNS_HEADER_SIZE;
761 }
762
763 /** returns owner from packet */
get_qname(uint8_t * pkt,size_t pktlen)764 static uint8_t* get_qname(uint8_t* pkt, size_t pktlen)
765 {
766 if(pktlen < LDNS_HEADER_SIZE)
767 return NULL;
768 if(LDNS_QDCOUNT(pkt) == 0)
769 return NULL;
770 return pkt+LDNS_HEADER_SIZE;
771 }
772
773 /** returns opcode from packet */
get_opcode(uint8_t * pkt,size_t pktlen)774 static int get_opcode(uint8_t* pkt, size_t pktlen)
775 {
776 if(pktlen < LDNS_HEADER_SIZE)
777 return 0;
778 return (int)LDNS_OPCODE_WIRE(pkt);
779 }
780
781 /** returns rcode from packet */
get_rcode(uint8_t * pkt,size_t pktlen)782 static int get_rcode(uint8_t* pkt, size_t pktlen)
783 {
784 if(pktlen < LDNS_HEADER_SIZE)
785 return 0;
786 return (int)LDNS_RCODE_WIRE(pkt);
787 }
788
789 /** get authority section SOA serial value */
get_serial(uint8_t * p,size_t plen)790 static uint32_t get_serial(uint8_t* p, size_t plen)
791 {
792 uint8_t* walk = p;
793 size_t walk_len = plen, sl=0;
794 char* snull = NULL;
795 uint16_t i;
796 int comprloop = 0;
797
798 if(walk_len < LDNS_HEADER_SIZE)
799 return 0;
800 walk += LDNS_HEADER_SIZE;
801 walk_len -= LDNS_HEADER_SIZE;
802
803 /* skip other records with wire2str_scan */
804 for(i=0; i < LDNS_QDCOUNT(p); i++)
805 (void)sldns_wire2str_rrquestion_scan(&walk, &walk_len,
806 &snull, &sl, p, plen, &comprloop);
807 for(i=0; i < LDNS_ANCOUNT(p); i++)
808 (void)sldns_wire2str_rr_scan(&walk, &walk_len, &snull, &sl,
809 p, plen, &comprloop);
810
811 /* walk through authority section */
812 for(i=0; i < LDNS_NSCOUNT(p); i++) {
813 /* if this is SOA then get serial, skip compressed dname */
814 uint8_t* dstart = walk;
815 size_t dlen = walk_len;
816 (void)sldns_wire2str_dname_scan(&dstart, &dlen, &snull, &sl,
817 p, plen, &comprloop);
818 if(dlen >= 2 && sldns_read_uint16(dstart) == LDNS_RR_TYPE_SOA) {
819 /* skip type, class, TTL, rdatalen */
820 if(dlen < 10)
821 return 0;
822 if(dlen < 10 + (size_t)sldns_read_uint16(dstart+8))
823 return 0;
824 dstart += 10;
825 dlen -= 10;
826 /* check third rdf */
827 (void)sldns_wire2str_dname_scan(&dstart, &dlen, &snull,
828 &sl, p, plen, &comprloop);
829 (void)sldns_wire2str_dname_scan(&dstart, &dlen, &snull,
830 &sl, p, plen, &comprloop);
831 if(dlen < 4)
832 return 0;
833 verbose(3, "found serial %u in msg. ",
834 (int)sldns_read_uint32(dstart));
835 return sldns_read_uint32(dstart);
836 }
837 /* move to next RR */
838 (void)sldns_wire2str_rr_scan(&walk, &walk_len, &snull, &sl,
839 p, plen, &comprloop);
840 }
841 return 0;
842 }
843
844 /** get ptr to EDNS OPT record (and remaining length); after the type u16 */
845 static int
pkt_find_edns_opt(uint8_t ** p,size_t * plen)846 pkt_find_edns_opt(uint8_t** p, size_t* plen)
847 {
848 /* walk over the packet with scan routines */
849 uint8_t* w = *p;
850 size_t wlen = *plen, sl=0;
851 char* snull = NULL;
852 uint16_t i;
853 int comprloop = 0;
854
855 if(wlen < LDNS_HEADER_SIZE)
856 return 0;
857 w += LDNS_HEADER_SIZE;
858 wlen -= LDNS_HEADER_SIZE;
859
860 /* skip other records with wire2str_scan */
861 for(i=0; i < LDNS_QDCOUNT(*p); i++)
862 (void)sldns_wire2str_rrquestion_scan(&w, &wlen, &snull, &sl,
863 *p, *plen, &comprloop);
864 for(i=0; i < LDNS_ANCOUNT(*p); i++)
865 (void)sldns_wire2str_rr_scan(&w, &wlen, &snull, &sl, *p, *plen, &comprloop);
866 for(i=0; i < LDNS_NSCOUNT(*p); i++)
867 (void)sldns_wire2str_rr_scan(&w, &wlen, &snull, &sl, *p, *plen, &comprloop);
868
869 /* walk through additional section */
870 for(i=0; i < LDNS_ARCOUNT(*p); i++) {
871 /* if this is OPT then done */
872 uint8_t* dstart = w;
873 size_t dlen = wlen;
874 (void)sldns_wire2str_dname_scan(&dstart, &dlen, &snull, &sl,
875 *p, *plen, &comprloop);
876 if(dlen >= 2 && sldns_read_uint16(dstart) == LDNS_RR_TYPE_OPT) {
877 *p = dstart+2;
878 *plen = dlen-2;
879 return 1;
880 }
881 /* move to next RR */
882 (void)sldns_wire2str_rr_scan(&w, &wlen, &snull, &sl, *p, *plen, &comprloop);
883 }
884 return 0;
885 }
886
887 /** return true if the packet has EDNS OPT record */
888 static int
get_has_edns(uint8_t * pkt,size_t len)889 get_has_edns(uint8_t* pkt, size_t len)
890 {
891 /* use arguments as temporary variables */
892 return pkt_find_edns_opt(&pkt, &len);
893 }
894
895 /** return true if the DO flag is set */
896 static int
get_do_flag(uint8_t * pkt,size_t len)897 get_do_flag(uint8_t* pkt, size_t len)
898 {
899 uint16_t edns_bits;
900 uint8_t* walk = pkt;
901 size_t walk_len = len;
902 if(!pkt_find_edns_opt(&walk, &walk_len)) {
903 return 0;
904 }
905 if(walk_len < 6)
906 return 0; /* malformed */
907 edns_bits = sldns_read_uint16(walk+4);
908 return (int)(edns_bits&LDNS_EDNS_MASK_DO_BIT);
909 }
910
911 /** Snips the specified EDNS option out of the OPT record and puts it in the
912 * provided buffer. The buffer should be able to hold any opt data ie 65535.
913 * Returns the length of the option written,
914 * or 0 if not found, else -1 on error. */
915 static int
pkt_snip_edns_option(uint8_t * pkt,size_t len,sldns_edns_option code,uint8_t * buf)916 pkt_snip_edns_option(uint8_t* pkt, size_t len, sldns_edns_option code,
917 uint8_t* buf)
918 {
919 uint8_t *rdata, *opt_position = pkt;
920 uint16_t rdlen, optlen;
921 size_t remaining = len;
922 if(!pkt_find_edns_opt(&opt_position, &remaining)) return 0;
923 if(remaining < 8) return -1; /* malformed */
924 rdlen = sldns_read_uint16(opt_position+6);
925 rdata = opt_position + 8;
926 while(rdlen > 0) {
927 if(rdlen < 4) return -1; /* malformed */
928 optlen = sldns_read_uint16(rdata+2);
929 if(sldns_read_uint16(rdata) == code) {
930 /* save data to buf for caller inspection */
931 memmove(buf, rdata+4, optlen);
932 /* snip option from packet; assumes len is correct */
933 memmove(rdata, rdata+4+optlen,
934 (pkt+len)-(rdata+4+optlen));
935 /* update OPT size */
936 sldns_write_uint16(opt_position+6,
937 sldns_read_uint16(opt_position+6)-(4+optlen));
938 return optlen;
939 }
940 rdlen -= 4 + optlen;
941 rdata += 4 + optlen;
942 }
943 return 0;
944 }
945
946 /** Snips the EDE option out of the OPT record and returns the EDNS EDE
947 * INFO-CODE if found, else -1 */
948 static int
extract_ede(uint8_t * pkt,size_t len)949 extract_ede(uint8_t* pkt, size_t len)
950 {
951 uint8_t buf[65535];
952 int buflen = pkt_snip_edns_option(pkt, len, LDNS_EDNS_EDE, buf);
953 if(buflen < 2 /*ede without text at minimum*/) return -1;
954 return sldns_read_uint16(buf);
955 }
956
957 /** Snips the DNS Cookie option out of the OPT record and puts it in the
958 * provided cookie buffer (should be at least 24 octets).
959 * Returns the length of the cookie if found, else -1. */
960 static int
extract_cookie(uint8_t * pkt,size_t len,uint8_t * cookie)961 extract_cookie(uint8_t* pkt, size_t len, uint8_t* cookie)
962 {
963 uint8_t buf[65535];
964 int buflen = pkt_snip_edns_option(pkt, len, LDNS_EDNS_COOKIE, buf);
965 if(buflen != 8 /*client cookie*/ &&
966 buflen != 8 + 16 /*server cookie*/) return -1;
967 memcpy(cookie, buf, buflen);
968 return buflen;
969 }
970
971 /** zero TTLs in packet */
972 static void
zerottls(uint8_t * pkt,size_t pktlen)973 zerottls(uint8_t* pkt, size_t pktlen)
974 {
975 uint8_t* walk = pkt;
976 size_t walk_len = pktlen, sl=0;
977 char* snull = NULL;
978 uint16_t i;
979 uint16_t num = LDNS_ANCOUNT(pkt)+LDNS_NSCOUNT(pkt)+LDNS_ARCOUNT(pkt);
980 int comprloop = 0;
981 if(walk_len < LDNS_HEADER_SIZE)
982 return;
983 walk += LDNS_HEADER_SIZE;
984 walk_len -= LDNS_HEADER_SIZE;
985 for(i=0; i < LDNS_QDCOUNT(pkt); i++)
986 (void)sldns_wire2str_rrquestion_scan(&walk, &walk_len,
987 &snull, &sl, pkt, pktlen, &comprloop);
988 for(i=0; i < num; i++) {
989 /* wipe TTL */
990 uint8_t* dstart = walk;
991 size_t dlen = walk_len;
992 (void)sldns_wire2str_dname_scan(&dstart, &dlen, &snull, &sl,
993 pkt, pktlen, &comprloop);
994 if(dlen < 8)
995 return;
996 sldns_write_uint32(dstart+4, 0);
997 /* go to next RR */
998 (void)sldns_wire2str_rr_scan(&walk, &walk_len, &snull, &sl,
999 pkt, pktlen, &comprloop);
1000 }
1001 }
1002
1003 /** get one line (\n) from a string, move next to after the \n, zero \n */
1004 static int
get_line(char ** s,char ** n)1005 get_line(char** s, char** n)
1006 {
1007 /* at end of string? end */
1008 if(*n == NULL || **n == 0)
1009 return 0;
1010 /* result starts at next string */
1011 *s = *n;
1012 /* find \n after that */
1013 *n = strchr(*s, '\n');
1014 if(*n && **n != 0) {
1015 /* terminate line */
1016 (*n)[0] = 0;
1017 (*n)++;
1018 }
1019 return 1;
1020 }
1021
1022 /** match two RR sections without ordering */
1023 static int
match_noloc_section(char ** q,char ** nq,char ** p,char ** np,uint16_t num)1024 match_noloc_section(char** q, char** nq, char** p, char** np, uint16_t num)
1025 {
1026 /* for max number of RRs in packet */
1027 const uint16_t numarray = 3000;
1028 char* qlines[numarray], *plines[numarray];
1029 uint16_t i, j, numq=0, nump=0;
1030 if(num > numarray) fatal_exit("too many RRs");
1031 /* gather lines */
1032 for(i=0; i<num; i++) {
1033 get_line(q, nq);
1034 get_line(p, np);
1035 qlines[numq++] = *q;
1036 plines[nump++] = *p;
1037 }
1038 /* see if they are all present in the other */
1039 for(i=0; i<num; i++) {
1040 int found = 0;
1041 for(j=0; j<num; j++) {
1042 if(strcmp(qlines[i], plines[j]) == 0) {
1043 found = 1;
1044 break;
1045 }
1046 }
1047 if(!found) {
1048 verbose(3, "comparenoloc: failed for %s", qlines[i]);
1049 return 0;
1050 }
1051 }
1052 return 1;
1053 }
1054
1055 /** match two strings for unordered equality of RRs and everything else */
1056 static int
match_noloc(char * q,char * p,uint8_t * q_pkt,size_t q_pkt_len,uint8_t * p_pkt,size_t p_pkt_len)1057 match_noloc(char* q, char* p, uint8_t* q_pkt, size_t q_pkt_len,
1058 uint8_t* p_pkt, size_t p_pkt_len)
1059 {
1060 char* nq = q, *np = p;
1061 /* if no header, compare bytes */
1062 if(p_pkt_len < LDNS_HEADER_SIZE || q_pkt_len < LDNS_HEADER_SIZE) {
1063 if(p_pkt_len != q_pkt_len) return 0;
1064 return memcmp(p, q, p_pkt_len);
1065 }
1066 /* compare RR counts */
1067 if(LDNS_QDCOUNT(p_pkt) != LDNS_QDCOUNT(q_pkt))
1068 return 0;
1069 if(LDNS_ANCOUNT(p_pkt) != LDNS_ANCOUNT(q_pkt))
1070 return 0;
1071 if(LDNS_NSCOUNT(p_pkt) != LDNS_NSCOUNT(q_pkt))
1072 return 0;
1073 if(LDNS_ARCOUNT(p_pkt) != LDNS_ARCOUNT(q_pkt))
1074 return 0;
1075 /* get a line from both; compare; at sections do section */
1076 get_line(&q, &nq);
1077 get_line(&p, &np);
1078 if(strcmp(q, p) != 0) {
1079 /* header line opcode, rcode, id */
1080 return 0;
1081 }
1082 get_line(&q, &nq);
1083 get_line(&p, &np);
1084 if(strcmp(q, p) != 0) {
1085 /* header flags, rr counts */
1086 return 0;
1087 }
1088 /* ;; QUESTION SECTION */
1089 get_line(&q, &nq);
1090 get_line(&p, &np);
1091 if(strcmp(q, p) != 0) return 0;
1092 if(!match_noloc_section(&q, &nq, &p, &np, LDNS_QDCOUNT(p_pkt)))
1093 return 0;
1094
1095 /* empty line and ;; ANSWER SECTION */
1096 get_line(&q, &nq);
1097 get_line(&p, &np);
1098 if(strcmp(q, p) != 0) return 0;
1099 get_line(&q, &nq);
1100 get_line(&p, &np);
1101 if(strcmp(q, p) != 0) return 0;
1102 if(!match_noloc_section(&q, &nq, &p, &np, LDNS_ANCOUNT(p_pkt)))
1103 return 0;
1104
1105 /* empty line and ;; AUTHORITY SECTION */
1106 get_line(&q, &nq);
1107 get_line(&p, &np);
1108 if(strcmp(q, p) != 0) return 0;
1109 get_line(&q, &nq);
1110 get_line(&p, &np);
1111 if(strcmp(q, p) != 0) return 0;
1112 if(!match_noloc_section(&q, &nq, &p, &np, LDNS_NSCOUNT(p_pkt)))
1113 return 0;
1114
1115 /* empty line and ;; ADDITIONAL SECTION */
1116 get_line(&q, &nq);
1117 get_line(&p, &np);
1118 if(strcmp(q, p) != 0) return 0;
1119 get_line(&q, &nq);
1120 get_line(&p, &np);
1121 if(strcmp(q, p) != 0) return 0;
1122 if(!match_noloc_section(&q, &nq, &p, &np, LDNS_ARCOUNT(p_pkt)))
1123 return 0;
1124
1125 return 1;
1126 }
1127
1128 /** lowercase domain name - does not follow compression pointers */
lowercase_dname(uint8_t ** p,size_t * remain)1129 static void lowercase_dname(uint8_t** p, size_t* remain)
1130 {
1131 unsigned i, llen;
1132 if(*remain == 0) return;
1133 while(**p != 0) {
1134 /* compressed? */
1135 if((**p & 0xc0) == 0xc0) {
1136 *p += 2;
1137 *remain -= 2;
1138 return;
1139 }
1140 llen = (unsigned int)**p;
1141 *p += 1;
1142 *remain -= 1;
1143 if(*remain < llen)
1144 llen = (unsigned int)*remain;
1145 for(i=0; i<llen; i++) {
1146 (*p)[i] = (uint8_t)tolower((int)(*p)[i]);
1147 }
1148 *p += llen;
1149 *remain -= llen;
1150 if(*remain == 0) return;
1151 }
1152 /* skip root label */
1153 *p += 1;
1154 *remain -= 1;
1155 }
1156
1157 /** lowercase rdata of type */
lowercase_rdata(uint8_t ** p,size_t * remain,uint16_t rdatalen,uint16_t t)1158 static void lowercase_rdata(uint8_t** p, size_t* remain,
1159 uint16_t rdatalen, uint16_t t)
1160 {
1161 const sldns_rr_descriptor *desc = sldns_rr_descript(t);
1162 uint8_t dname_count = 0;
1163 size_t i = 0;
1164 size_t rdataremain = rdatalen;
1165 if(!desc) {
1166 /* unknown type */
1167 *p += rdatalen;
1168 *remain -= rdatalen;
1169 return;
1170 }
1171 while(dname_count < desc->_dname_count) {
1172 sldns_rdf_type f = sldns_rr_descriptor_field_type(desc, i++);
1173 if(f == LDNS_RDF_TYPE_DNAME) {
1174 lowercase_dname(p, &rdataremain);
1175 dname_count++;
1176 } else if(f == LDNS_RDF_TYPE_STR) {
1177 uint8_t len;
1178 if(rdataremain == 0) return;
1179 len = **p;
1180 *p += len+1;
1181 rdataremain -= len+1;
1182 } else {
1183 int len = 0;
1184 switch(f) {
1185 case LDNS_RDF_TYPE_CLASS:
1186 case LDNS_RDF_TYPE_ALG:
1187 case LDNS_RDF_TYPE_INT8:
1188 len = 1;
1189 break;
1190 case LDNS_RDF_TYPE_INT16:
1191 case LDNS_RDF_TYPE_TYPE:
1192 case LDNS_RDF_TYPE_CERT_ALG:
1193 len = 2;
1194 break;
1195 case LDNS_RDF_TYPE_INT32:
1196 case LDNS_RDF_TYPE_TIME:
1197 case LDNS_RDF_TYPE_A:
1198 case LDNS_RDF_TYPE_PERIOD:
1199 len = 4;
1200 break;
1201 case LDNS_RDF_TYPE_TSIGTIME:
1202 len = 6;
1203 break;
1204 case LDNS_RDF_TYPE_AAAA:
1205 len = 16;
1206 break;
1207 default: error("bad rdf type in lowercase %d", (int)f);
1208 }
1209 *p += len;
1210 rdataremain -= len;
1211 }
1212 }
1213 /* skip remainder of rdata */
1214 *p += rdataremain;
1215 *remain -= rdatalen;
1216 }
1217
1218 /** lowercase all names in the message */
lowercase_pkt(uint8_t * pkt,size_t pktlen)1219 static void lowercase_pkt(uint8_t* pkt, size_t pktlen)
1220 {
1221 uint16_t i;
1222 uint8_t* p = pkt;
1223 size_t remain = pktlen;
1224 uint16_t t, rdatalen;
1225 if(pktlen < LDNS_HEADER_SIZE)
1226 return;
1227 p += LDNS_HEADER_SIZE;
1228 remain -= LDNS_HEADER_SIZE;
1229 for(i=0; i<LDNS_QDCOUNT(pkt); i++) {
1230 lowercase_dname(&p, &remain);
1231 if(remain < 4) return;
1232 p += 4;
1233 remain -= 4;
1234 }
1235 for(i=0; i<LDNS_ANCOUNT(pkt)+LDNS_NSCOUNT(pkt)+LDNS_ARCOUNT(pkt); i++) {
1236 lowercase_dname(&p, &remain);
1237 if(remain < 10) return;
1238 t = sldns_read_uint16(p);
1239 rdatalen = sldns_read_uint16(p+8);
1240 p += 10;
1241 remain -= 10;
1242 if(remain < rdatalen) return;
1243 lowercase_rdata(&p, &remain, rdatalen, t);
1244 }
1245 }
1246
1247 /** match question section of packet */
1248 static int
match_question(uint8_t * q,size_t qlen,uint8_t * p,size_t plen,int mttl)1249 match_question(uint8_t* q, size_t qlen, uint8_t* p, size_t plen, int mttl)
1250 {
1251 char* qstr, *pstr, *s, *qcmpstr, *pcmpstr;
1252 uint8_t* qb = q, *pb = p;
1253 int r;
1254 /* zero TTLs */
1255 qb = memdup(q, qlen);
1256 pb = memdup(p, plen);
1257 if(!qb || !pb) error("out of memory");
1258 if(!mttl) {
1259 zerottls(qb, qlen);
1260 zerottls(pb, plen);
1261 }
1262 lowercase_pkt(qb, qlen);
1263 lowercase_pkt(pb, plen);
1264 qstr = sldns_wire2str_pkt(qb, qlen);
1265 pstr = sldns_wire2str_pkt(pb, plen);
1266 if(!qstr || !pstr) error("cannot pkt2string");
1267
1268 /* remove before ;; QUESTION */
1269 s = strstr(qstr, ";; QUESTION SECTION");
1270 qcmpstr = s;
1271 s = strstr(pstr, ";; QUESTION SECTION");
1272 pcmpstr = s;
1273 if(!qcmpstr && !pcmpstr) {
1274 free(qstr);
1275 free(pstr);
1276 free(qb);
1277 free(pb);
1278 return 1;
1279 }
1280 if(!qcmpstr || !pcmpstr) {
1281 free(qstr);
1282 free(pstr);
1283 free(qb);
1284 free(pb);
1285 return 0;
1286 }
1287
1288 /* remove after answer section, (;; ANS, ;; AUTH, ;; ADD ..) */
1289 s = strstr(qcmpstr, ";; ANSWER SECTION");
1290 if(!s) s = strstr(qcmpstr, ";; AUTHORITY SECTION");
1291 if(!s) s = strstr(qcmpstr, ";; ADDITIONAL SECTION");
1292 if(!s) s = strstr(qcmpstr, ";; MSG SIZE");
1293 if(s) *s = 0;
1294 s = strstr(pcmpstr, ";; ANSWER SECTION");
1295 if(!s) s = strstr(pcmpstr, ";; AUTHORITY SECTION");
1296 if(!s) s = strstr(pcmpstr, ";; ADDITIONAL SECTION");
1297 if(!s) s = strstr(pcmpstr, ";; MSG SIZE");
1298 if(s) *s = 0;
1299
1300 r = (strcmp(qcmpstr, pcmpstr) == 0);
1301
1302 if(!r) {
1303 verbose(3, "mismatch question section '%s' and '%s'",
1304 qcmpstr, pcmpstr);
1305 }
1306
1307 free(qstr);
1308 free(pstr);
1309 free(qb);
1310 free(pb);
1311 return r;
1312 }
1313
1314 /** match answer section of packet */
1315 static int
match_answer(uint8_t * q,size_t qlen,uint8_t * p,size_t plen,int mttl)1316 match_answer(uint8_t* q, size_t qlen, uint8_t* p, size_t plen, int mttl)
1317 {
1318 char* qstr, *pstr, *s, *qcmpstr, *pcmpstr;
1319 uint8_t* qb = q, *pb = p;
1320 int r;
1321 /* zero TTLs */
1322 qb = memdup(q, qlen);
1323 pb = memdup(p, plen);
1324 if(!qb || !pb) error("out of memory");
1325 if(!mttl) {
1326 zerottls(qb, qlen);
1327 zerottls(pb, plen);
1328 }
1329 lowercase_pkt(qb, qlen);
1330 lowercase_pkt(pb, plen);
1331 qstr = sldns_wire2str_pkt(qb, qlen);
1332 pstr = sldns_wire2str_pkt(pb, plen);
1333 if(!qstr || !pstr) error("cannot pkt2string");
1334
1335 /* remove before ;; ANSWER */
1336 s = strstr(qstr, ";; ANSWER SECTION");
1337 qcmpstr = s;
1338 s = strstr(pstr, ";; ANSWER SECTION");
1339 pcmpstr = s;
1340 if(!qcmpstr && !pcmpstr) {
1341 free(qstr);
1342 free(pstr);
1343 free(qb);
1344 free(pb);
1345 return 1;
1346 }
1347 if(!qcmpstr || !pcmpstr) {
1348 free(qstr);
1349 free(pstr);
1350 free(qb);
1351 free(pb);
1352 return 0;
1353 }
1354
1355 /* remove after answer section, (;; AUTH, ;; ADD, ;; MSG size ..) */
1356 s = strstr(qcmpstr, ";; AUTHORITY SECTION");
1357 if(!s) s = strstr(qcmpstr, ";; ADDITIONAL SECTION");
1358 if(!s) s = strstr(qcmpstr, ";; MSG SIZE");
1359 if(s) *s = 0;
1360 s = strstr(pcmpstr, ";; AUTHORITY SECTION");
1361 if(!s) s = strstr(pcmpstr, ";; ADDITIONAL SECTION");
1362 if(!s) s = strstr(pcmpstr, ";; MSG SIZE");
1363 if(s) *s = 0;
1364
1365 r = (strcmp(qcmpstr, pcmpstr) == 0);
1366
1367 if(!r) {
1368 verbose(3, "mismatch answer section '%s' and '%s'",
1369 qcmpstr, pcmpstr);
1370 }
1371
1372 free(qstr);
1373 free(pstr);
1374 free(qb);
1375 free(pb);
1376 return r;
1377 }
1378
1379 /** ignore EDNS lines in the string by overwriting them with what's left or
1380 * zero out if at end of the string */
1381 static int
ignore_edns_lines(char * str)1382 ignore_edns_lines(char* str) {
1383 char* edns = str, *n;
1384 size_t str_len = strlen(str);
1385 while((edns = strstr(edns, "; EDNS"))) {
1386 n = strchr(edns, '\n');
1387 if(!n) {
1388 /* EDNS at end of string; zero */
1389 *edns = 0;
1390 break;
1391 }
1392 memmove(edns, n+1, str_len-(n-str));
1393 }
1394 return 1;
1395 }
1396
1397 /** match all of the packet */
1398 int
match_all(uint8_t * q,size_t qlen,uint8_t * p,size_t plen,int mttl,int noloc,int noedns)1399 match_all(uint8_t* q, size_t qlen, uint8_t* p, size_t plen, int mttl,
1400 int noloc, int noedns)
1401 {
1402 char* qstr, *pstr;
1403 uint8_t* qb = q, *pb = p;
1404 int r;
1405 qb = memdup(q, qlen);
1406 pb = memdup(p, plen);
1407 if(!qb || !pb) error("out of memory");
1408 /* zero TTLs */
1409 if(!mttl) {
1410 zerottls(qb, qlen);
1411 zerottls(pb, plen);
1412 }
1413 lowercase_pkt(qb, qlen);
1414 lowercase_pkt(pb, plen);
1415 qstr = sldns_wire2str_pkt(qb, qlen);
1416 pstr = sldns_wire2str_pkt(pb, plen);
1417 if(!qstr || !pstr) error("cannot pkt2string");
1418 /* should we ignore EDNS lines? */
1419 if(noedns) {
1420 ignore_edns_lines(qstr);
1421 ignore_edns_lines(pstr);
1422 }
1423 r = (strcmp(qstr, pstr) == 0);
1424 if(!r) {
1425 /* remove ;; MSG SIZE (at end of string) */
1426 char* s = strstr(qstr, ";; MSG SIZE");
1427 if(s) *s=0;
1428 s = strstr(pstr, ";; MSG SIZE");
1429 if(s) *s=0;
1430 r = (strcmp(qstr, pstr) == 0);
1431 if(!r && !noloc && !noedns) {
1432 /* we are going to fail, see if the cause is EDNS */
1433 char* a = strstr(qstr, "; EDNS");
1434 char* b = strstr(pstr, "; EDNS");
1435 if( (a&&!b) || (b&&!a) ) {
1436 verbose(3, "mismatch in EDNS\n");
1437 }
1438 }
1439 }
1440 if(!r && noloc) {
1441 /* check for reordered sections */
1442 r = match_noloc(qstr, pstr, q, qlen, p, plen);
1443 }
1444 if(!r) {
1445 verbose(3, "mismatch pkt '%s' and '%s'", qstr, pstr);
1446 }
1447 free(qstr);
1448 free(pstr);
1449 free(qb);
1450 free(pb);
1451 return r;
1452 }
1453
1454 /** see if domain names are equal */
equal_dname(uint8_t * q,size_t qlen,uint8_t * p,size_t plen)1455 static int equal_dname(uint8_t* q, size_t qlen, uint8_t* p, size_t plen)
1456 {
1457 uint8_t* qn = get_qname(q, qlen);
1458 uint8_t* pn = get_qname(p, plen);
1459 char qs[512], ps[512];
1460 size_t qslen = sizeof(qs), pslen = sizeof(ps);
1461 char* qss = qs, *pss = ps;
1462 int comprloop = 0;
1463 if(!qn || !pn)
1464 return 0;
1465 (void)sldns_wire2str_dname_scan(&qn, &qlen, &qss, &qslen, q, qlen, &comprloop);
1466 (void)sldns_wire2str_dname_scan(&pn, &plen, &pss, &pslen, p, plen, &comprloop);
1467 return (strcmp(qs, ps) == 0);
1468 }
1469
1470 /** see if domain names are subdomain q of p */
subdomain_dname(uint8_t * q,size_t qlen,uint8_t * p,size_t plen)1471 static int subdomain_dname(uint8_t* q, size_t qlen, uint8_t* p, size_t plen)
1472 {
1473 /* we use the tostring routines so as to test unbound's routines
1474 * with something else */
1475 uint8_t* qn = get_qname(q, qlen);
1476 uint8_t* pn = get_qname(p, plen);
1477 char qs[5120], ps[5120];
1478 size_t qslen = sizeof(qs), pslen = sizeof(ps);
1479 char* qss = qs, *pss = ps;
1480 int comprloop = 0;
1481 if(!qn || !pn)
1482 return 0;
1483 /* decompresses domain names */
1484 (void)sldns_wire2str_dname_scan(&qn, &qlen, &qss, &qslen, q, qlen, &comprloop);
1485 (void)sldns_wire2str_dname_scan(&pn, &plen, &pss, &pslen, p, plen, &comprloop);
1486 /* same: false, (strict subdomain check)??? */
1487 if(strcmp(qs, ps) == 0)
1488 return 1;
1489 /* qs must end in ps, at a dot, without \ in front */
1490 qslen = strlen(qs);
1491 pslen = strlen(ps);
1492 if(qslen > pslen && strcmp(qs + (qslen-pslen), ps) == 0 &&
1493 qslen + 2 >= pslen && /* space for label and dot */
1494 qs[qslen-pslen-1] == '.') {
1495 unsigned int slashcount = 0;
1496 size_t i = qslen-pslen-2;
1497 while(i>0 && qs[i]=='\\') {
1498 i++;
1499 slashcount++;
1500 }
1501 if(slashcount%1 == 1) return 0; /* . preceded by \ */
1502 return 1;
1503 }
1504 return 0;
1505 }
1506
1507 /** Match OPT RDATA (not the EDNS payload size or flags) */
1508 static int
match_ednsdata(uint8_t * q,size_t qlen,uint8_t * p,size_t plen)1509 match_ednsdata(uint8_t* q, size_t qlen, uint8_t* p, size_t plen)
1510 {
1511 uint8_t* walk_q = q;
1512 size_t walk_qlen = qlen;
1513 uint8_t* walk_p = p;
1514 size_t walk_plen = plen;
1515
1516 if(!pkt_find_edns_opt(&walk_q, &walk_qlen))
1517 walk_qlen = 0;
1518 if(!pkt_find_edns_opt(&walk_p, &walk_plen))
1519 walk_plen = 0;
1520
1521 /* class + ttl + rdlen = 8 */
1522 if(walk_qlen <= 8 && walk_plen <= 8) {
1523 verbose(3, "NO edns opt, move on");
1524 return 1;
1525 }
1526 if(walk_qlen != walk_plen)
1527 return 0;
1528
1529 return (memcmp(walk_p+8, walk_q+8, walk_qlen-8) == 0);
1530 }
1531
1532 /* finds entry in list, or returns NULL */
1533 struct entry*
find_match(struct entry * entries,uint8_t * query_pkt,size_t len,enum transport_type transport)1534 find_match(struct entry* entries, uint8_t* query_pkt, size_t len,
1535 enum transport_type transport)
1536 {
1537 struct entry* p = entries;
1538 uint8_t* reply, *query_pkt_orig;
1539 size_t rlen, query_pkt_orig_len;
1540 /* Keep the original packet; it may be modified */
1541 query_pkt_orig = memdup(query_pkt, len);
1542 query_pkt_orig_len = len;
1543 for(p=entries; p; p=p->next) {
1544 verbose(3, "comparepkt: ");
1545 reply = p->reply_list->reply_pkt;
1546 rlen = p->reply_list->reply_len;
1547 /* Restore the original packet for each entry */
1548 memcpy(query_pkt, query_pkt_orig, query_pkt_orig_len);
1549 /* EDE should be first since it may modify the query_pkt */
1550 if(p->match_ede) {
1551 int info_code = extract_ede(query_pkt, len);
1552 if(info_code == -1) {
1553 verbose(3, "bad EDE. Expected but not found\n");
1554 continue;
1555 } else if(!p->match_ede_any &&
1556 (uint16_t)info_code != p->ede_info_code) {
1557 verbose(3, "bad EDE INFO-CODE. Expected: %d, "
1558 "and got: %d\n", (int)p->ede_info_code,
1559 info_code);
1560 continue;
1561 }
1562 }
1563 /* Cookies could also modify the query_pkt; keep them early */
1564 if(p->match_client_cookie || p->match_server_cookie) {
1565 uint8_t cookie[24];
1566 int cookie_len = extract_cookie(query_pkt, len,
1567 cookie);
1568 if(cookie_len == -1) {
1569 verbose(3, "bad DNS Cookie. "
1570 "Expected but not found\n");
1571 continue;
1572 } else if(p->match_client_cookie &&
1573 cookie_len != 8) {
1574 verbose(3, "bad DNS Cookie. Expected client "
1575 "cookie of length 8.");
1576 continue;
1577 } else if((p->match_server_cookie) &&
1578 cookie_len != 24) {
1579 verbose(3, "bad DNS Cookie. Expected server "
1580 "cookie of length 24.");
1581 continue;
1582 }
1583 }
1584 if(p->match_opcode && get_opcode(query_pkt, len) !=
1585 get_opcode(reply, rlen)) {
1586 verbose(3, "bad opcode\n");
1587 continue;
1588 }
1589 if(p->match_qtype && get_qtype(query_pkt, len) !=
1590 get_qtype(reply, rlen)) {
1591 verbose(3, "bad qtype %d %d\n", get_qtype(query_pkt, len), get_qtype(reply, rlen));
1592 continue;
1593 }
1594 if(p->match_qname) {
1595 if(!equal_dname(query_pkt, len, reply, rlen)) {
1596 verbose(3, "bad qname\n");
1597 continue;
1598 }
1599 }
1600 if(p->match_rcode) {
1601 if(get_rcode(query_pkt, len) != get_rcode(reply, rlen)) {
1602 char *r1 = sldns_wire2str_rcode(get_rcode(query_pkt, len));
1603 char *r2 = sldns_wire2str_rcode(get_rcode(reply, rlen));
1604 verbose(3, "bad rcode %s instead of %s\n",
1605 r1, r2);
1606 free(r1);
1607 free(r2);
1608 continue;
1609 }
1610 }
1611 if(p->match_question) {
1612 if(!match_question(query_pkt, len, reply, rlen,
1613 (int)p->match_ttl)) {
1614 verbose(3, "bad question section\n");
1615 continue;
1616 }
1617 }
1618 if(p->match_answer) {
1619 if(!match_answer(query_pkt, len, reply, rlen,
1620 (int)p->match_ttl)) {
1621 verbose(3, "bad answer section\n");
1622 continue;
1623 }
1624 }
1625 if(p->match_subdomain) {
1626 if(!subdomain_dname(query_pkt, len, reply, rlen)) {
1627 verbose(3, "bad subdomain\n");
1628 continue;
1629 }
1630 }
1631 if(p->match_serial && get_serial(query_pkt, len) != p->ixfr_soa_serial) {
1632 verbose(3, "bad serial\n");
1633 continue;
1634 }
1635 if(p->match_do && !get_do_flag(query_pkt, len)) {
1636 verbose(3, "no DO bit set\n");
1637 continue;
1638 }
1639 if(p->match_noedns && get_has_edns(query_pkt, len)) {
1640 verbose(3, "bad; EDNS OPT present\n");
1641 continue;
1642 }
1643 if(p->match_ednsdata_raw &&
1644 !match_ednsdata(query_pkt, len, reply, rlen)) {
1645 verbose(3, "bad EDNS data match.\n");
1646 continue;
1647 }
1648 if(p->match_transport != transport_any && p->match_transport != transport) {
1649 verbose(3, "bad transport\n");
1650 continue;
1651 }
1652 if(p->match_all_noedns && !match_all(query_pkt, len, reply,
1653 rlen, (int)p->match_ttl, 0, 1)) {
1654 verbose(3, "bad all_noedns match\n");
1655 continue;
1656 }
1657 if(p->match_all && !match_all(query_pkt, len, reply, rlen,
1658 (int)p->match_ttl, 0, 0)) {
1659 verbose(3, "bad allmatch\n");
1660 continue;
1661 }
1662 verbose(3, "match!\n");
1663 /* Restore the original packet */
1664 memcpy(query_pkt, query_pkt_orig, query_pkt_orig_len);
1665 free(query_pkt_orig);
1666 return p;
1667 }
1668 /* Restore the original packet */
1669 memcpy(query_pkt, query_pkt_orig, query_pkt_orig_len);
1670 free(query_pkt_orig);
1671 return NULL;
1672 }
1673
1674 void
adjust_packet(struct entry * match,uint8_t ** answer_pkt,size_t * answer_len,uint8_t * query_pkt,size_t query_len)1675 adjust_packet(struct entry* match, uint8_t** answer_pkt, size_t *answer_len,
1676 uint8_t* query_pkt, size_t query_len)
1677 {
1678 uint8_t* orig = *answer_pkt;
1679 size_t origlen = *answer_len;
1680 uint8_t* res;
1681 size_t reslen;
1682
1683 /* perform the copy; if possible; must be uncompressed */
1684 if(match->copy_query && origlen >= LDNS_HEADER_SIZE &&
1685 query_len >= LDNS_HEADER_SIZE && LDNS_QDCOUNT(query_pkt)!=0
1686 && LDNS_QDCOUNT(orig)==0) {
1687 /* no qname in output packet, insert it */
1688 size_t dlen = get_qname_len(query_pkt, query_len);
1689 reslen = origlen + dlen + 4;
1690 res = (uint8_t*)malloc(reslen);
1691 if(!res) {
1692 verbose(1, "out of memory; send without adjust\n");
1693 return;
1694 }
1695 /* copy the header, query, remainder */
1696 memcpy(res, orig, LDNS_HEADER_SIZE);
1697 memmove(res+LDNS_HEADER_SIZE, query_pkt+LDNS_HEADER_SIZE,
1698 dlen+4);
1699 memmove(res+LDNS_HEADER_SIZE+dlen+4, orig+LDNS_HEADER_SIZE,
1700 reslen-(LDNS_HEADER_SIZE+dlen+4));
1701 /* set QDCOUNT */
1702 sldns_write_uint16(res+4, 1);
1703 } else if(match->copy_query && origlen >= LDNS_HEADER_SIZE &&
1704 query_len >= LDNS_HEADER_SIZE && LDNS_QDCOUNT(query_pkt)!=0
1705 && get_qname_len(orig, origlen) == 0) {
1706 /* QDCOUNT(orig)!=0 but qlen == 0, therefore, an error */
1707 verbose(1, "error: malformed qname; send without adjust\n");
1708 res = memdup(orig, origlen);
1709 reslen = origlen;
1710 } else if(match->copy_query && origlen >= LDNS_HEADER_SIZE &&
1711 query_len >= LDNS_HEADER_SIZE && LDNS_QDCOUNT(query_pkt)!=0
1712 && LDNS_QDCOUNT(orig)!=0) {
1713 /* in this case olen != 0 and QDCOUNT(orig)!=0 */
1714 /* copy query section */
1715 size_t dlen = get_qname_len(query_pkt, query_len);
1716 size_t olen = get_qname_len(orig, origlen);
1717 reslen = origlen + dlen - olen;
1718 res = (uint8_t*)malloc(reslen);
1719 if(!res) {
1720 verbose(1, "out of memory; send without adjust\n");
1721 return;
1722 }
1723 /* copy the header, query, remainder */
1724 memcpy(res, orig, LDNS_HEADER_SIZE);
1725 memmove(res+LDNS_HEADER_SIZE, query_pkt+LDNS_HEADER_SIZE,
1726 dlen+4);
1727 memmove(res+LDNS_HEADER_SIZE+dlen+4,
1728 orig+LDNS_HEADER_SIZE+olen+4,
1729 reslen-(LDNS_HEADER_SIZE+dlen+4));
1730 } else {
1731 res = memdup(orig, origlen);
1732 reslen = origlen;
1733 }
1734 if(!res) {
1735 verbose(1, "out of memory; send without adjust\n");
1736 return;
1737 }
1738 /* copy the ID */
1739 if(match->copy_id && reslen >= 2 && query_len >= 2)
1740 res[1] = query_pkt[1];
1741 if(match->copy_id && reslen >= 1 && query_len >= 1)
1742 res[0] = query_pkt[0];
1743
1744 if(match->copy_ednsdata_assume_clientsubnet) {
1745 /** Assume there is only one EDNS option, which is ECS.
1746 * Copy source mask from query to scope mask in reply. Assume
1747 * rest of ECS data in response (eg address) matches the query.
1748 */
1749 uint8_t* walk_q = orig;
1750 size_t walk_qlen = origlen;
1751 uint8_t* walk_p = res;
1752 size_t walk_plen = reslen;
1753
1754 if(!pkt_find_edns_opt(&walk_q, &walk_qlen)) {
1755 walk_qlen = 0;
1756 }
1757 if(!pkt_find_edns_opt(&walk_p, &walk_plen)) {
1758 walk_plen = 0;
1759 }
1760 /* class + ttl + rdlen + optcode + optlen + ecs fam + ecs source
1761 * + ecs scope = index 15 */
1762 if(walk_qlen >= 15 && walk_plen >= 15) {
1763 walk_p[15] = walk_q[14];
1764 }
1765 if(match->increment_ecs_scope) {
1766 walk_p[15]++;
1767 }
1768 }
1769
1770 if(match->sleeptime > 0) {
1771 verbose(3, "sleeping for %d seconds\n", match->sleeptime);
1772 #ifdef HAVE_SLEEP
1773 sleep(match->sleeptime);
1774 #else
1775 Sleep(match->sleeptime * 1000);
1776 #endif
1777 }
1778 *answer_pkt = res;
1779 *answer_len = reslen;
1780 }
1781
1782 /*
1783 * Parses data buffer to a query, finds the correct answer
1784 * and calls the given function for every packet to send.
1785 */
1786 void
handle_query(uint8_t * inbuf,ssize_t inlen,struct entry * entries,int * count,enum transport_type transport,void (* sendfunc)(uint8_t *,size_t,void *),void * userdata,FILE * verbose_out)1787 handle_query(uint8_t* inbuf, ssize_t inlen, struct entry* entries, int* count,
1788 enum transport_type transport, void (*sendfunc)(uint8_t*, size_t, void*),
1789 void* userdata, FILE* verbose_out)
1790 {
1791 struct reply_packet *p;
1792 uint8_t *outbuf = NULL;
1793 size_t outlen = 0;
1794 struct entry* entry = NULL;
1795
1796 verbose(1, "query %d: id %d: %s %d bytes: ", ++(*count),
1797 (int)(inlen>=2?LDNS_ID_WIRE(inbuf):0),
1798 (transport==transport_tcp)?"TCP":"UDP", (int)inlen);
1799 if(verbose_out) {
1800 char* out = sldns_wire2str_pkt(inbuf, (size_t)inlen);
1801 printf("%s\n", out);
1802 free(out);
1803 }
1804
1805 /* fill up answer packet */
1806 entry = find_match(entries, inbuf, (size_t)inlen, transport);
1807 if(!entry || !entry->reply_list) {
1808 verbose(1, "no answer packet for this query, no reply.\n");
1809 return;
1810 }
1811 for(p = entry->reply_list; p; p = p->next)
1812 {
1813 verbose(3, "Answer pkt:\n");
1814 if (p->reply_from_hex) {
1815 /* try to adjust the hex packet, if it can be
1816 * parsed, we can use adjust rules. if not,
1817 * send packet literally */
1818 /* still try to adjust ID if others fail */
1819 outlen = sldns_buffer_limit(p->reply_from_hex);
1820 outbuf = sldns_buffer_begin(p->reply_from_hex);
1821 } else {
1822 outbuf = p->reply_pkt;
1823 outlen = p->reply_len;
1824 }
1825 if(!outbuf) {
1826 verbose(1, "out of memory\n");
1827 return;
1828 }
1829 /* copies outbuf in memory allocation */
1830 adjust_packet(entry, &outbuf, &outlen, inbuf, (size_t)inlen);
1831 verbose(1, "Answer packet size: %u bytes.\n", (unsigned int)outlen);
1832 if(verbose_out) {
1833 char* out = sldns_wire2str_pkt(outbuf, outlen);
1834 printf("%s\n", out);
1835 free(out);
1836 }
1837 if(p->packet_sleep) {
1838 verbose(3, "sleeping for next packet %d secs\n",
1839 p->packet_sleep);
1840 #ifdef HAVE_SLEEP
1841 sleep(p->packet_sleep);
1842 #else
1843 Sleep(p->packet_sleep * 1000);
1844 #endif
1845 verbose(3, "wakeup for next packet "
1846 "(slept %d secs)\n", p->packet_sleep);
1847 }
1848 sendfunc(outbuf, outlen, userdata);
1849 free(outbuf);
1850 outbuf = NULL;
1851 outlen = 0;
1852 }
1853 }
1854
1855 /** delete the list of reply packets */
delete_replylist(struct reply_packet * replist)1856 void delete_replylist(struct reply_packet* replist)
1857 {
1858 struct reply_packet *p=replist, *np;
1859 while(p) {
1860 np = p->next;
1861 free(p->reply_pkt);
1862 sldns_buffer_free(p->reply_from_hex);
1863 sldns_buffer_free(p->raw_ednsdata);
1864 free(p);
1865 p=np;
1866 }
1867 }
1868
delete_entry(struct entry * list)1869 void delete_entry(struct entry* list)
1870 {
1871 struct entry *p=list, *np;
1872 while(p) {
1873 np = p->next;
1874 delete_replylist(p->reply_list);
1875 free(p);
1876 p = np;
1877 }
1878 }
1879