xref: /netbsd-src/external/bsd/unbound/dist/testcode/testpkts.c (revision f21b7d7f2cbdd5c14b3882c4e8a3d43580d460a6)
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 struct sockaddr_storage;
25 #include <errno.h>
26 #include <stdarg.h>
27 #include <ctype.h>
28 #include "testcode/testpkts.h"
29 #include "util/net_help.h"
30 #include "sldns/sbuffer.h"
31 #include "sldns/rrdef.h"
32 #include "sldns/pkthdr.h"
33 #include "sldns/str2wire.h"
34 #include "sldns/wire2str.h"
35 
36 /** max size of a packet */
37 #define MAX_PACKETLEN 65536
38 /** max line length */
39 #define MAX_LINE   10240
40 /** string to show in warnings and errors */
41 static const char* prog_name = "testpkts";
42 
43 #ifndef UTIL_LOG_H
44 /** verbosity definition for compat */
45 enum verbosity_value { NO_VERBOSE=0 };
46 #endif
47 /** logging routine, provided by caller */
48 void verbose(enum verbosity_value lvl, const char* msg, ...) ATTR_FORMAT(printf, 2, 3);
49 
50 /** print error and exit */
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 */
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 */
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*
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 	/* link at end */
102 	while(*p)
103 		p = &((*p)->next);
104 	*p = pkt;
105 	return pkt;
106 }
107 
108 /** parse MATCH line */
109 static void matchline(char* line, struct entry* e)
110 {
111 	char* parse = line;
112 	while(*parse) {
113 		if(isendline(*parse))
114 			return;
115 		if(str_keyword(&parse, "opcode")) {
116 			e->match_opcode = 1;
117 		} else if(str_keyword(&parse, "qtype")) {
118 			e->match_qtype = 1;
119 		} else if(str_keyword(&parse, "qname")) {
120 			e->match_qname = 1;
121 		} else if(str_keyword(&parse, "subdomain")) {
122 			e->match_subdomain = 1;
123 		} else if(str_keyword(&parse, "all")) {
124 			e->match_all = 1;
125 		} else if(str_keyword(&parse, "ttl")) {
126 			e->match_ttl = 1;
127 		} else if(str_keyword(&parse, "DO")) {
128 			e->match_do = 1;
129 		} else if(str_keyword(&parse, "noedns")) {
130 			e->match_noedns = 1;
131 		} else if(str_keyword(&parse, "UDP")) {
132 			e->match_transport = transport_udp;
133 		} else if(str_keyword(&parse, "TCP")) {
134 			e->match_transport = transport_tcp;
135 		} else if(str_keyword(&parse, "serial")) {
136 			e->match_serial = 1;
137 			if(*parse != '=' && *parse != ':')
138 				error("expected = or : in MATCH: %s", line);
139 			parse++;
140 			e->ixfr_soa_serial = (uint32_t)strtol(parse, (char**)&parse, 10);
141 			while(isspace((unsigned char)*parse))
142 				parse++;
143 		} else {
144 			error("could not parse MATCH: '%s'", parse);
145 		}
146 	}
147 }
148 
149 /** parse REPLY line */
150 static void replyline(char* line, uint8_t* reply, size_t reply_len,
151 	int* do_flag)
152 {
153 	char* parse = line;
154 	if(reply_len < LDNS_HEADER_SIZE) error("packet too short for header");
155 	while(*parse) {
156 		if(isendline(*parse))
157 			return;
158 			/* opcodes */
159 		if(str_keyword(&parse, "QUERY")) {
160 			LDNS_OPCODE_SET(reply, LDNS_PACKET_QUERY);
161 		} else if(str_keyword(&parse, "IQUERY")) {
162 			LDNS_OPCODE_SET(reply, LDNS_PACKET_IQUERY);
163 		} else if(str_keyword(&parse, "STATUS")) {
164 			LDNS_OPCODE_SET(reply, LDNS_PACKET_STATUS);
165 		} else if(str_keyword(&parse, "NOTIFY")) {
166 			LDNS_OPCODE_SET(reply, LDNS_PACKET_NOTIFY);
167 		} else if(str_keyword(&parse, "UPDATE")) {
168 			LDNS_OPCODE_SET(reply, LDNS_PACKET_UPDATE);
169 			/* rcodes */
170 		} else if(str_keyword(&parse, "NOERROR")) {
171 			LDNS_RCODE_SET(reply, LDNS_RCODE_NOERROR);
172 		} else if(str_keyword(&parse, "FORMERR")) {
173 			LDNS_RCODE_SET(reply, LDNS_RCODE_FORMERR);
174 		} else if(str_keyword(&parse, "SERVFAIL")) {
175 			LDNS_RCODE_SET(reply, LDNS_RCODE_SERVFAIL);
176 		} else if(str_keyword(&parse, "NXDOMAIN")) {
177 			LDNS_RCODE_SET(reply, LDNS_RCODE_NXDOMAIN);
178 		} else if(str_keyword(&parse, "NOTIMPL")) {
179 			LDNS_RCODE_SET(reply, LDNS_RCODE_NOTIMPL);
180 		} else if(str_keyword(&parse, "REFUSED")) {
181 			LDNS_RCODE_SET(reply, LDNS_RCODE_REFUSED);
182 		} else if(str_keyword(&parse, "YXDOMAIN")) {
183 			LDNS_RCODE_SET(reply, LDNS_RCODE_YXDOMAIN);
184 		} else if(str_keyword(&parse, "YXRRSET")) {
185 			LDNS_RCODE_SET(reply, LDNS_RCODE_YXRRSET);
186 		} else if(str_keyword(&parse, "NXRRSET")) {
187 			LDNS_RCODE_SET(reply, LDNS_RCODE_NXRRSET);
188 		} else if(str_keyword(&parse, "NOTAUTH")) {
189 			LDNS_RCODE_SET(reply, LDNS_RCODE_NOTAUTH);
190 		} else if(str_keyword(&parse, "NOTZONE")) {
191 			LDNS_RCODE_SET(reply, LDNS_RCODE_NOTZONE);
192 			/* flags */
193 		} else if(str_keyword(&parse, "QR")) {
194 			LDNS_QR_SET(reply);
195 		} else if(str_keyword(&parse, "AA")) {
196 			LDNS_AA_SET(reply);
197 		} else if(str_keyword(&parse, "TC")) {
198 			LDNS_TC_SET(reply);
199 		} else if(str_keyword(&parse, "RD")) {
200 			LDNS_RD_SET(reply);
201 		} else if(str_keyword(&parse, "CD")) {
202 			LDNS_CD_SET(reply);
203 		} else if(str_keyword(&parse, "RA")) {
204 			LDNS_RA_SET(reply);
205 		} else if(str_keyword(&parse, "AD")) {
206 			LDNS_AD_SET(reply);
207 		} else if(str_keyword(&parse, "DO")) {
208 			*do_flag = 1;
209 		} else {
210 			error("could not parse REPLY: '%s'", parse);
211 		}
212 	}
213 }
214 
215 /** parse ADJUST line */
216 static void adjustline(char* line, struct entry* e,
217 	struct reply_packet* pkt)
218 {
219 	char* parse = line;
220 	while(*parse) {
221 		if(isendline(*parse))
222 			return;
223 		if(str_keyword(&parse, "copy_id")) {
224 			e->copy_id = 1;
225 		} else if(str_keyword(&parse, "copy_query")) {
226 			e->copy_query = 1;
227 		} else if(str_keyword(&parse, "sleep=")) {
228 			e->sleeptime = (unsigned int) strtol(parse, (char**)&parse, 10);
229 			while(isspace((unsigned char)*parse))
230 				parse++;
231 		} else if(str_keyword(&parse, "packet_sleep=")) {
232 			pkt->packet_sleep = (unsigned int) strtol(parse, (char**)&parse, 10);
233 			while(isspace((unsigned char)*parse))
234 				parse++;
235 		} else {
236 			error("could not parse ADJUST: '%s'", parse);
237 		}
238 	}
239 }
240 
241 /** create new entry */
242 static struct entry* new_entry()
243 {
244 	struct entry* e = (struct entry*)malloc(sizeof(struct entry));
245 	if(!e) error("out of memory");
246 	memset(e, 0, sizeof(*e));
247 	e->match_opcode = 0;
248 	e->match_qtype = 0;
249 	e->match_qname = 0;
250 	e->match_subdomain = 0;
251 	e->match_all = 0;
252 	e->match_ttl = 0;
253 	e->match_do = 0;
254 	e->match_noedns = 0;
255 	e->match_serial = 0;
256 	e->ixfr_soa_serial = 0;
257 	e->match_transport = transport_any;
258 	e->reply_list = NULL;
259 	e->copy_id = 0;
260 	e->copy_query = 0;
261 	e->sleeptime = 0;
262 	e->next = NULL;
263 	return e;
264 }
265 
266 /**
267  * Converts a hex string to binary data
268  * @param hexstr: string of hex.
269  * @param len: is the length of the string
270  * @param buf: is the buffer to store the result in
271  * @param offset: is the starting position in the result buffer
272  * @param buf_len: is the length of buf.
273  * @return This function returns the length of the result
274  */
275 static size_t
276 hexstr2bin(char *hexstr, int len, uint8_t *buf, size_t offset, size_t buf_len)
277 {
278 	char c;
279 	int i;
280 	uint8_t int8 = 0;
281 	int sec = 0;
282 	size_t bufpos = 0;
283 
284 	if (len % 2 != 0) {
285 		return 0;
286 	}
287 
288 	for (i=0; i<len; i++) {
289 		c = hexstr[i];
290 
291 		/* case insensitive, skip spaces */
292 		if (c != ' ') {
293 			if (c >= '0' && c <= '9') {
294 				int8 += c & 0x0f;
295 			} else if (c >= 'a' && c <= 'z') {
296 				int8 += (c & 0x0f) + 9;
297 			} else if (c >= 'A' && c <= 'Z') {
298 				int8 += (c & 0x0f) + 9;
299 			} else {
300 				return 0;
301 			}
302 
303 			if (sec == 0) {
304 				int8 = int8 << 4;
305 				sec = 1;
306 			} else {
307 				if (bufpos + offset + 1 <= buf_len) {
308 					buf[bufpos+offset] = int8;
309 					int8 = 0;
310 					sec = 0;
311 					bufpos++;
312 				} else {
313 					fprintf(stderr, "Buffer too small in hexstr2bin");
314 				}
315 			}
316 		}
317         }
318         return bufpos;
319 }
320 
321 /** convert hex buffer to binary buffer */
322 static sldns_buffer *
323 hex_buffer2wire(sldns_buffer *data_buffer)
324 {
325 	sldns_buffer *wire_buffer = NULL;
326 	int c;
327 
328 	/* stat hack
329 	 * 0 = normal
330 	 * 1 = comment (skip to end of line)
331 	 * 2 = unprintable character found, read binary data directly
332 	 */
333 	size_t data_buf_pos = 0;
334 	int state = 0;
335 	uint8_t *hexbuf;
336 	int hexbufpos = 0;
337 	size_t wirelen;
338 	uint8_t *data_wire = (uint8_t *) sldns_buffer_begin(data_buffer);
339 	uint8_t *wire = (uint8_t*)malloc(MAX_PACKETLEN);
340 	if(!wire) error("out of memory");
341 
342 	hexbuf = (uint8_t*)malloc(MAX_PACKETLEN);
343 	if(!hexbuf) error("out of memory");
344 	for (data_buf_pos = 0; data_buf_pos < sldns_buffer_position(data_buffer); data_buf_pos++) {
345 		c = (int) data_wire[data_buf_pos];
346 
347 		if (state < 2 && !isascii((unsigned char)c)) {
348 			/*verbose("non ascii character found in file: (%d) switching to raw mode\n", c);*/
349 			state = 2;
350 		}
351 		switch (state) {
352 			case 0:
353 				if (	(c >= '0' && c <= '9') ||
354 					(c >= 'a' && c <= 'f') ||
355 					(c >= 'A' && c <= 'F') )
356 				{
357 					if (hexbufpos >= MAX_PACKETLEN) {
358 						error("buffer overflow");
359 						free(hexbuf);
360 						return 0;
361 
362 					}
363 					hexbuf[hexbufpos] = (uint8_t) c;
364 					hexbufpos++;
365 				} else if (c == ';') {
366 					state = 1;
367 				} else if (c == ' ' || c == '\t' || c == '\n') {
368 					/* skip whitespace */
369 				}
370 				break;
371 			case 1:
372 				if (c == '\n' || c == EOF) {
373 					state = 0;
374 				}
375 				break;
376 			case 2:
377 				if (hexbufpos >= MAX_PACKETLEN) {
378 					error("buffer overflow");
379 					free(hexbuf);
380 					return 0;
381 				}
382 				hexbuf[hexbufpos] = (uint8_t) c;
383 				hexbufpos++;
384 				break;
385 		}
386 	}
387 
388 	if (hexbufpos >= MAX_PACKETLEN) {
389 		/*verbose("packet size reached\n");*/
390 	}
391 
392 	/* lenient mode: length must be multiple of 2 */
393 	if (hexbufpos % 2 != 0) {
394 		if (hexbufpos >= MAX_PACKETLEN) {
395 			error("buffer overflow");
396 			free(hexbuf);
397 			return 0;
398 		}
399 		hexbuf[hexbufpos] = (uint8_t) '0';
400 		hexbufpos++;
401 	}
402 
403 	if (state < 2) {
404 		wirelen = hexstr2bin((char *) hexbuf, hexbufpos, wire, 0, MAX_PACKETLEN);
405 		wire_buffer = sldns_buffer_new(wirelen);
406 		sldns_buffer_new_frm_data(wire_buffer, wire, wirelen);
407 	} else {
408 		error("Incomplete hex data, not at byte boundary\n");
409 	}
410 	free(wire);
411 	free(hexbuf);
412 	return wire_buffer;
413 }
414 
415 /** parse ORIGIN */
416 static void
417 get_origin(const char* name, struct sldns_file_parse_state* pstate, char* parse)
418 {
419 	/* snip off rest of the text so as to make the parse work in ldns */
420 	char* end;
421 	char store;
422 	int status;
423 
424 	end=parse;
425 	while(!isspace((unsigned char)*end) && !isendline(*end))
426 		end++;
427 	store = *end;
428 	*end = 0;
429 	verbose(3, "parsing '%s'\n", parse);
430 	status = sldns_str2wire_dname_buf(parse, pstate->origin,
431 		&pstate->origin_len);
432 	*end = store;
433 	if(status != 0)
434 		error("%s line %d:\n\t%s: %s", name, pstate->lineno,
435 			sldns_get_errorstr_parse(status), parse);
436 }
437 
438 /** add RR to packet */
439 static void add_rr(char* rrstr, uint8_t* pktbuf, size_t pktsize,
440 	size_t* pktlen, struct sldns_file_parse_state* pstate,
441 	sldns_pkt_section add_section, const char* fname)
442 {
443 	/* it must be a RR, parse and add to packet. */
444 	size_t rr_len = pktsize - *pktlen;
445 	size_t dname_len = 0;
446 	int status;
447 	uint8_t* origin = pstate->origin_len?pstate->origin:0;
448 	uint8_t* prev = pstate->prev_rr_len?pstate->prev_rr:0;
449 	if(*pktlen > pktsize || *pktlen < LDNS_HEADER_SIZE)
450 		error("packet overflow");
451 
452 	/* parse RR */
453 	if(add_section == LDNS_SECTION_QUESTION)
454 		status = sldns_str2wire_rr_question_buf(rrstr, pktbuf+*pktlen,
455 			&rr_len, &dname_len, origin, pstate->origin_len,
456 			prev, pstate->prev_rr_len);
457 	else status = sldns_str2wire_rr_buf(rrstr, pktbuf+*pktlen, &rr_len,
458 			&dname_len, pstate->default_ttl, origin,
459 			pstate->origin_len, prev, pstate->prev_rr_len);
460 	if(status != 0)
461 		error("%s line %d:%d %s\n\t%s", fname, pstate->lineno,
462 			LDNS_WIREPARSE_OFFSET(status),
463 			sldns_get_errorstr_parse(status), rrstr);
464 	*pktlen += rr_len;
465 
466 	/* increase RR count */
467 	if(add_section == LDNS_SECTION_QUESTION)
468 		sldns_write_uint16(pktbuf+4, LDNS_QDCOUNT(pktbuf)+1);
469 	else if(add_section == LDNS_SECTION_ANSWER)
470 		sldns_write_uint16(pktbuf+6, LDNS_ANCOUNT(pktbuf)+1);
471 	else if(add_section == LDNS_SECTION_AUTHORITY)
472 		sldns_write_uint16(pktbuf+8, LDNS_NSCOUNT(pktbuf)+1);
473 	else if(add_section == LDNS_SECTION_ADDITIONAL)
474 		sldns_write_uint16(pktbuf+10, LDNS_ARCOUNT(pktbuf)+1);
475 	else error("internal error bad section %d", (int)add_section);
476 }
477 
478 /* add EDNS 4096 DO opt record */
479 static void
480 add_do_flag(uint8_t* pktbuf, size_t pktsize, size_t* pktlen)
481 {
482 	uint8_t edns[] = {0x00, /* root label */
483 		0x00, LDNS_RR_TYPE_OPT, /* type */
484 		0x10, 0x00, /* class is UDPSIZE 4096 */
485 		0x00, /* TTL[0] is ext rcode */
486 		0x00, /* TTL[1] is edns version */
487 		0x80, 0x00, /* TTL[2-3] is edns flags, DO */
488 		0x00, 0x00 /* rdatalength (0 options) */
489 	};
490 	if(*pktlen < LDNS_HEADER_SIZE)
491 		return;
492 	if(*pktlen + sizeof(edns) > pktsize)
493 		error("not enough space for EDNS OPT record");
494 	memmove(pktbuf+*pktlen, edns, sizeof(edns));
495 	sldns_write_uint16(pktbuf+10, LDNS_ARCOUNT(pktbuf)+1);
496 	*pktlen += sizeof(edns);
497 }
498 
499 /* Reads one entry from file. Returns entry or NULL on error. */
500 struct entry*
501 read_entry(FILE* in, const char* name, struct sldns_file_parse_state* pstate,
502 	int skip_whitespace)
503 {
504 	struct entry* current = NULL;
505 	char line[MAX_LINE];
506 	char* parse;
507 	sldns_pkt_section add_section = LDNS_SECTION_QUESTION;
508 	struct reply_packet *cur_reply = NULL;
509 	int reading_hex = 0;
510 	sldns_buffer* hex_data_buffer = NULL;
511 	uint8_t pktbuf[MAX_PACKETLEN];
512 	size_t pktlen = LDNS_HEADER_SIZE;
513 	int do_flag = 0; /* DO flag in EDNS */
514 	memset(pktbuf, 0, pktlen); /* ID = 0, FLAGS="", and rr counts 0 */
515 
516 	while(fgets(line, (int)sizeof(line), in) != NULL) {
517 		line[MAX_LINE-1] = 0;
518 		parse = line;
519 		pstate->lineno++;
520 
521 		while(isspace((unsigned char)*parse))
522 			parse++;
523 		/* test for keywords */
524 		if(isendline(*parse))
525 			continue; /* skip comment and empty lines */
526 		if(str_keyword(&parse, "ENTRY_BEGIN")) {
527 			if(current) {
528 				error("%s line %d: previous entry does not ENTRY_END",
529 					name, pstate->lineno);
530 			}
531 			current = new_entry();
532 			current->lineno = pstate->lineno;
533 			cur_reply = entry_add_reply(current);
534 			continue;
535 		} else if(str_keyword(&parse, "$ORIGIN")) {
536 			get_origin(name, pstate, parse);
537 			continue;
538 		} else if(str_keyword(&parse, "$TTL")) {
539 			pstate->default_ttl = (uint32_t)atoi(parse);
540 			continue;
541 		}
542 
543 		/* working inside an entry */
544 		if(!current) {
545 			error("%s line %d: expected ENTRY_BEGIN but got %s",
546 				name, pstate->lineno, line);
547 		}
548 		if(str_keyword(&parse, "MATCH")) {
549 			matchline(parse, current);
550 		} else if(str_keyword(&parse, "REPLY")) {
551 			replyline(parse, pktbuf, pktlen, &do_flag);
552 		} else if(str_keyword(&parse, "ADJUST")) {
553 			adjustline(parse, current, cur_reply);
554 		} else if(str_keyword(&parse, "EXTRA_PACKET")) {
555 			cur_reply = entry_add_reply(current);
556 		} else if(str_keyword(&parse, "SECTION")) {
557 			if(str_keyword(&parse, "QUESTION"))
558 				add_section = LDNS_SECTION_QUESTION;
559 			else if(str_keyword(&parse, "ANSWER"))
560 				add_section = LDNS_SECTION_ANSWER;
561 			else if(str_keyword(&parse, "AUTHORITY"))
562 				add_section = LDNS_SECTION_AUTHORITY;
563 			else if(str_keyword(&parse, "ADDITIONAL"))
564 				add_section = LDNS_SECTION_ADDITIONAL;
565 			else error("%s line %d: bad section %s", name, pstate->lineno, parse);
566 		} else if(str_keyword(&parse, "HEX_ANSWER_BEGIN")) {
567 			hex_data_buffer = sldns_buffer_new(MAX_PACKETLEN);
568 			reading_hex = 1;
569 		} else if(str_keyword(&parse, "HEX_ANSWER_END")) {
570 			if(!reading_hex) {
571 				error("%s line %d: HEX_ANSWER_END read but no HEX_ANSWER_BEGIN keyword seen", name, pstate->lineno);
572 			}
573 			reading_hex = 0;
574 			cur_reply->reply_from_hex = hex_buffer2wire(hex_data_buffer);
575 			sldns_buffer_free(hex_data_buffer);
576 			hex_data_buffer = NULL;
577 		} else if(str_keyword(&parse, "ENTRY_END")) {
578 			if(hex_data_buffer)
579 				sldns_buffer_free(hex_data_buffer);
580 			if(pktlen != 0) {
581 				if(do_flag)
582 					add_do_flag(pktbuf, sizeof(pktbuf),
583 						&pktlen);
584 				cur_reply->reply_pkt = memdup(pktbuf, pktlen);
585 				cur_reply->reply_len = pktlen;
586 				if(!cur_reply->reply_pkt)
587 					error("out of memory");
588 			}
589 			return current;
590 		} else if(reading_hex) {
591 			sldns_buffer_printf(hex_data_buffer, "%s", line);
592 		} else {
593 			add_rr(skip_whitespace?parse:line, pktbuf,
594 				sizeof(pktbuf), &pktlen, pstate, add_section,
595 				name);
596 		}
597 
598 	}
599 	if (reading_hex) {
600 		error("%s: End of file reached while still reading hex, "
601 			"missing HEX_ANSWER_END\n", name);
602 	}
603 	if(current) {
604 		error("%s: End of file reached while reading entry. "
605 			"missing ENTRY_END\n", name);
606 	}
607 	return 0;
608 }
609 
610 /* reads the canned reply file and returns a list of structs */
611 struct entry*
612 read_datafile(const char* name, int skip_whitespace)
613 {
614 	struct entry* list = NULL;
615 	struct entry* last = NULL;
616 	struct entry* current = NULL;
617 	FILE *in;
618 	struct sldns_file_parse_state pstate;
619 	int entry_num = 0;
620 	memset(&pstate, 0, sizeof(pstate));
621 
622 	if((in=fopen(name, "r")) == NULL) {
623 		error("could not open file %s: %s", name, strerror(errno));
624 	}
625 
626 	while((current = read_entry(in, name, &pstate, skip_whitespace)))
627 	{
628 		if(last)
629 			last->next = current;
630 		else	list = current;
631 		last = current;
632 		entry_num ++;
633 	}
634 	verbose(1, "%s: Read %d entries\n", prog_name, entry_num);
635 
636 	fclose(in);
637 	return list;
638 }
639 
640 /** get qtype from packet */
641 static sldns_rr_type get_qtype(uint8_t* pkt, size_t pktlen)
642 {
643 	uint8_t* d;
644 	size_t dl, sl=0;
645 	char* snull = NULL;
646 	if(pktlen < LDNS_HEADER_SIZE)
647 		return 0;
648 	if(LDNS_QDCOUNT(pkt) == 0)
649 		return 0;
650 	/* skip over dname with dname-scan routine */
651 	d = pkt+LDNS_HEADER_SIZE;
652 	dl = pktlen-LDNS_HEADER_SIZE;
653 	(void)sldns_wire2str_dname_scan(&d, &dl, &snull, &sl, pkt, pktlen);
654 	if(dl < 2)
655 		return 0;
656 	return sldns_read_uint16(d);
657 }
658 
659 /** get qtype from packet */
660 static size_t get_qname_len(uint8_t* pkt, size_t pktlen)
661 {
662 	uint8_t* d;
663 	size_t dl, sl=0;
664 	char* snull = NULL;
665 	if(pktlen < LDNS_HEADER_SIZE)
666 		return 0;
667 	if(LDNS_QDCOUNT(pkt) == 0)
668 		return 0;
669 	/* skip over dname with dname-scan routine */
670 	d = pkt+LDNS_HEADER_SIZE;
671 	dl = pktlen-LDNS_HEADER_SIZE;
672 	(void)sldns_wire2str_dname_scan(&d, &dl, &snull, &sl, pkt, pktlen);
673 	return pktlen-dl-LDNS_HEADER_SIZE;
674 }
675 
676 /** returns owner from packet */
677 static uint8_t* get_qname(uint8_t* pkt, size_t pktlen)
678 {
679 	if(pktlen < LDNS_HEADER_SIZE)
680 		return NULL;
681 	if(LDNS_QDCOUNT(pkt) == 0)
682 		return NULL;
683 	return pkt+LDNS_HEADER_SIZE;
684 }
685 
686 /** returns opcode from packet */
687 static int get_opcode(uint8_t* pkt, size_t pktlen)
688 {
689 	if(pktlen < LDNS_HEADER_SIZE)
690 		return 0;
691 	return (int)LDNS_OPCODE_WIRE(pkt);
692 }
693 
694 /** get authority section SOA serial value */
695 static uint32_t get_serial(uint8_t* p, size_t plen)
696 {
697 	uint8_t* walk = p;
698 	size_t walk_len = plen, sl=0;
699 	char* snull = NULL;
700 	uint16_t i;
701 
702 	if(walk_len < LDNS_HEADER_SIZE)
703 		return 0;
704 	walk += LDNS_HEADER_SIZE;
705 	walk_len -= LDNS_HEADER_SIZE;
706 
707 	/* skip other records with wire2str_scan */
708 	for(i=0; i < LDNS_QDCOUNT(p); i++)
709 		(void)sldns_wire2str_rrquestion_scan(&walk, &walk_len,
710 			&snull, &sl, p, plen);
711 	for(i=0; i < LDNS_ANCOUNT(p); i++)
712 		(void)sldns_wire2str_rr_scan(&walk, &walk_len, &snull, &sl,
713 			p, plen);
714 
715 	/* walk through authority section */
716 	for(i=0; i < LDNS_NSCOUNT(p); i++) {
717 		/* if this is SOA then get serial, skip compressed dname */
718 		uint8_t* dstart = walk;
719 		size_t dlen = walk_len;
720 		(void)sldns_wire2str_dname_scan(&dstart, &dlen, &snull, &sl,
721 			p, plen);
722 		if(dlen >= 2 && sldns_read_uint16(dstart) == LDNS_RR_TYPE_SOA) {
723 			/* skip type, class, TTL, rdatalen */
724 			if(dlen < 10)
725 				return 0;
726 			if(dlen < 10 + (size_t)sldns_read_uint16(dstart+8))
727 				return 0;
728 			dstart += 10;
729 			dlen -= 10;
730 			/* check third rdf */
731 			(void)sldns_wire2str_dname_scan(&dstart, &dlen, &snull,
732 				&sl, p, plen);
733 			(void)sldns_wire2str_dname_scan(&dstart, &dlen, &snull,
734 				&sl, p, plen);
735 			if(dlen < 4)
736 				return 0;
737 			verbose(3, "found serial %u in msg. ",
738 				(int)sldns_read_uint32(dstart));
739 			return sldns_read_uint32(dstart);
740 		}
741 		/* move to next RR */
742 		(void)sldns_wire2str_rr_scan(&walk, &walk_len, &snull, &sl,
743 			p, plen);
744 	}
745 	return 0;
746 }
747 
748 /** get ptr to EDNS OPT record (and remaining length); behind the type u16 */
749 static int
750 pkt_find_edns_opt(uint8_t** p, size_t* plen)
751 {
752 	/* walk over the packet with scan routines */
753 	uint8_t* w = *p;
754 	size_t wlen = *plen, sl=0;
755 	char* snull = NULL;
756 	uint16_t i;
757 
758 	if(wlen < LDNS_HEADER_SIZE)
759 		return 0;
760 	w += LDNS_HEADER_SIZE;
761 	wlen -= LDNS_HEADER_SIZE;
762 
763 	/* skip other records with wire2str_scan */
764 	for(i=0; i < LDNS_QDCOUNT(p); i++)
765 		(void)sldns_wire2str_rrquestion_scan(&w, &wlen, &snull, &sl,
766 			*p, *plen);
767 	for(i=0; i < LDNS_ANCOUNT(p); i++)
768 		(void)sldns_wire2str_rr_scan(&w, &wlen, &snull, &sl, *p, *plen);
769 	for(i=0; i < LDNS_NSCOUNT(p); i++)
770 		(void)sldns_wire2str_rr_scan(&w, &wlen, &snull, &sl, *p, *plen);
771 
772 	/* walk through additional section */
773 	for(i=0; i < LDNS_ARCOUNT(p); i++) {
774 		/* if this is OPT then done */
775 		uint8_t* dstart = w;
776 		size_t dlen = wlen;
777 		(void)sldns_wire2str_dname_scan(&dstart, &dlen, &snull, &sl,
778 			*p, *plen);
779 		if(dlen >= 2 && sldns_read_uint16(dstart) == LDNS_RR_TYPE_OPT) {
780 			*p = dstart+2;
781 			*plen = dlen-2;
782 			return 1;
783 		}
784 		/* move to next RR */
785 		(void)sldns_wire2str_rr_scan(&w, &wlen, &snull, &sl, *p, *plen);
786 	}
787 	return 0;
788 }
789 
790 /** return true if the packet has EDNS OPT record */
791 static int
792 get_has_edns(uint8_t* pkt, size_t len)
793 {
794 	/* use arguments as temporary variables */
795 	return pkt_find_edns_opt(&pkt, &len);
796 }
797 
798 /** return true if the DO flag is set */
799 static int
800 get_do_flag(uint8_t* pkt, size_t len)
801 {
802 	uint16_t edns_bits;
803 	uint8_t* walk = pkt;
804 	size_t walk_len = len;
805 	if(pkt_find_edns_opt(&walk, &walk_len)) {
806 		return 1;
807 	}
808 	if(walk_len < 6)
809 		return 0; /* malformed */
810 	edns_bits = sldns_read_uint16(walk+4);
811 	return (int)(edns_bits&LDNS_EDNS_MASK_DO_BIT);
812 }
813 
814 /** zero TTLs in packet */
815 static void
816 zerottls(uint8_t* pkt, size_t pktlen)
817 {
818 	uint8_t* walk = pkt;
819 	size_t walk_len = pktlen, sl=0;
820 	char* snull = NULL;
821 	uint16_t i;
822 	uint16_t num = LDNS_ANCOUNT(pkt)+LDNS_NSCOUNT(pkt)+LDNS_ARCOUNT(pkt);
823 	if(walk_len < LDNS_HEADER_SIZE)
824 		return;
825 	walk += LDNS_HEADER_SIZE;
826 	walk_len -= LDNS_HEADER_SIZE;
827 	for(i=0; i < LDNS_QDCOUNT(pkt); i++)
828 		(void)sldns_wire2str_rrquestion_scan(&walk, &walk_len,
829 			&snull, &sl, pkt, pktlen);
830 	for(i=0; i < num; i++) {
831 		/* wipe TTL */
832 		uint8_t* dstart = walk;
833 		size_t dlen = walk_len;
834 		(void)sldns_wire2str_dname_scan(&dstart, &dlen, &snull, &sl,
835 			pkt, pktlen);
836 		if(dlen < 8)
837 			return;
838 		sldns_write_uint32(dstart+4, 0);
839 		/* go to next RR */
840 		(void)sldns_wire2str_rr_scan(&walk, &walk_len, &snull, &sl,
841 			pkt, pktlen);
842 	}
843 }
844 
845 /** get one line (\n) from a string, move next to after the \n, zero \n */
846 static int
847 get_line(char** s, char** n)
848 {
849 	/* at end of string? end */
850 	if(*n == NULL || **n == 0)
851 		return 0;
852 	/* result starts at next string */
853 	*s = *n;
854 	/* find \n after that */
855 	*n = strchr(*s, '\n');
856 	if(*n && **n != 0) {
857 		/* terminate line */
858 		(*n)[0] = 0;
859 		(*n)++;
860 	}
861 	return 1;
862 }
863 
864 /** match two RR sections without ordering */
865 static int
866 match_noloc_section(char** q, char** nq, char** p, char** np, uint16_t num)
867 {
868 	/* for max number of RRs in packet */
869 	const uint16_t numarray = 3000;
870 	char* qlines[numarray], *plines[numarray];
871 	uint16_t i, j, numq=0, nump=0;
872 	if(num > numarray) fatal_exit("too many RRs");
873 	/* gather lines */
874 	for(i=0; i<num; i++) {
875 		get_line(q, nq);
876 		get_line(p, np);
877 		qlines[numq++] = *q;
878 		plines[nump++] = *p;
879 	}
880 	/* see if they are all present in the other */
881 	for(i=0; i<num; i++) {
882 		int found = 0;
883 		for(j=0; j<num; j++) {
884 			if(strcmp(qlines[i], plines[j]) == 0) {
885 				found = 1;
886 				break;
887 			}
888 		}
889 		if(!found) {
890 			verbose(3, "comparenoloc: failed for %s", qlines[i]);
891 			return 0;
892 		}
893 	}
894 	return 1;
895 }
896 
897 /** match two strings for unordered equality of RRs and everything else */
898 static int
899 match_noloc(char* q, char* p, uint8_t* q_pkt, size_t q_pkt_len,
900 	uint8_t* p_pkt, size_t p_pkt_len)
901 {
902 	char* nq = q, *np = p;
903 	/* if no header, compare bytes */
904 	if(p_pkt_len < LDNS_HEADER_SIZE || q_pkt_len < LDNS_HEADER_SIZE) {
905 		if(p_pkt_len != q_pkt_len) return 0;
906 		return memcmp(p, q, p_pkt_len);
907 	}
908 	/* compare RR counts */
909 	if(LDNS_QDCOUNT(p_pkt) != LDNS_QDCOUNT(q_pkt))
910 		return 0;
911 	if(LDNS_ANCOUNT(p_pkt) != LDNS_ANCOUNT(q_pkt))
912 		return 0;
913 	if(LDNS_NSCOUNT(p_pkt) != LDNS_NSCOUNT(q_pkt))
914 		return 0;
915 	if(LDNS_ARCOUNT(p_pkt) != LDNS_ARCOUNT(q_pkt))
916 		return 0;
917 	/* get a line from both; compare; at sections do section */
918 	get_line(&q, &nq);
919 	get_line(&p, &np);
920 	if(strcmp(q, p) != 0) {
921 		/* header line opcode, rcode, id */
922 		return 0;
923 	}
924 	get_line(&q, &nq);
925 	get_line(&p, &np);
926 	if(strcmp(q, p) != 0) {
927 		/* header flags, rr counts */
928 		return 0;
929 	}
930 	/* ;; QUESTION SECTION */
931 	get_line(&q, &nq);
932 	get_line(&p, &np);
933 	if(strcmp(q, p) != 0) return 0;
934 	if(!match_noloc_section(&q, &nq, &p, &np, LDNS_QDCOUNT(p_pkt)))
935 		return 0;
936 
937 	/* empty line and ;; ANSWER SECTION */
938 	get_line(&q, &nq);
939 	get_line(&p, &np);
940 	if(strcmp(q, p) != 0) return 0;
941 	get_line(&q, &nq);
942 	get_line(&p, &np);
943 	if(strcmp(q, p) != 0) return 0;
944 	if(!match_noloc_section(&q, &nq, &p, &np, LDNS_ANCOUNT(p_pkt)))
945 		return 0;
946 
947 	/* empty line and ;; AUTHORITY SECTION */
948 	get_line(&q, &nq);
949 	get_line(&p, &np);
950 	if(strcmp(q, p) != 0) return 0;
951 	get_line(&q, &nq);
952 	get_line(&p, &np);
953 	if(strcmp(q, p) != 0) return 0;
954 	if(!match_noloc_section(&q, &nq, &p, &np, LDNS_NSCOUNT(p_pkt)))
955 		return 0;
956 
957 	/* empty line and ;; ADDITIONAL SECTION */
958 	get_line(&q, &nq);
959 	get_line(&p, &np);
960 	if(strcmp(q, p) != 0) return 0;
961 	get_line(&q, &nq);
962 	get_line(&p, &np);
963 	if(strcmp(q, p) != 0) return 0;
964 	if(!match_noloc_section(&q, &nq, &p, &np, LDNS_ARCOUNT(p_pkt)))
965 		return 0;
966 
967 	return 1;
968 }
969 
970 /** lowercase domain name - does not follow compression pointers */
971 static void lowercase_dname(uint8_t** p, size_t* remain)
972 {
973 	unsigned i, llen;
974 	if(*remain == 0) return;
975 	while(**p != 0) {
976 		/* compressed? */
977 		if((**p & 0xc0) == 0xc0) {
978 			*p += 2;
979 			*remain -= 2;
980 			return;
981 		}
982 		llen = (unsigned int)**p;
983 		*p += 1;
984 		*remain -= 1;
985 		if(*remain < llen)
986 			llen = (unsigned int)*remain;
987 		for(i=0; i<llen; i++) {
988 			(*p)[i] = (uint8_t)tolower((int)(*p)[i]);
989 		}
990 		*p += llen;
991 		*remain -= llen;
992 		if(*remain == 0) return;
993 	}
994 	/* skip root label */
995 	*p += 1;
996 	*remain -= 1;
997 }
998 
999 /** lowercase rdata of type */
1000 static void lowercase_rdata(uint8_t** p, size_t* remain,
1001 	uint16_t rdatalen, uint16_t t)
1002 {
1003 	const sldns_rr_descriptor *desc = sldns_rr_descript(t);
1004 	uint8_t dname_count = 0;
1005 	size_t i = 0;
1006 	size_t rdataremain = rdatalen;
1007 	if(!desc) {
1008 		/* unknown type */
1009 		*p += rdatalen;
1010 		*remain -= rdatalen;
1011 		return;
1012 	}
1013 	while(dname_count < desc->_dname_count) {
1014 		sldns_rdf_type f = sldns_rr_descriptor_field_type(desc, i++);
1015 		if(f == LDNS_RDF_TYPE_DNAME) {
1016 			lowercase_dname(p, &rdataremain);
1017 			dname_count++;
1018 		} else if(f == LDNS_RDF_TYPE_STR) {
1019 			uint8_t len;
1020 			if(rdataremain == 0) return;
1021 			len = **p;
1022 			*p += len+1;
1023 			rdataremain -= len+1;
1024 		} else {
1025 			int len = 0;
1026 			switch(f) {
1027 			case LDNS_RDF_TYPE_CLASS:
1028 			case LDNS_RDF_TYPE_ALG:
1029 			case LDNS_RDF_TYPE_INT8:
1030 				len = 1;
1031 				break;
1032 			case LDNS_RDF_TYPE_INT16:
1033 			case LDNS_RDF_TYPE_TYPE:
1034 			case LDNS_RDF_TYPE_CERT_ALG:
1035 				len = 2;
1036 				break;
1037 			case LDNS_RDF_TYPE_INT32:
1038 			case LDNS_RDF_TYPE_TIME:
1039 			case LDNS_RDF_TYPE_A:
1040 			case LDNS_RDF_TYPE_PERIOD:
1041 				len = 4;
1042 				break;
1043 			case LDNS_RDF_TYPE_TSIGTIME:
1044 				len = 6;
1045 				break;
1046 			case LDNS_RDF_TYPE_AAAA:
1047 				len = 16;
1048 				break;
1049 			default: error("bad rdf type in lowercase %d", (int)f);
1050 			}
1051 			*p += len;
1052 			rdataremain -= len;
1053 		}
1054 	}
1055 	/* skip remainder of rdata */
1056 	*p += rdataremain;
1057 	*remain -= rdatalen;
1058 }
1059 
1060 /** lowercase all names in the message */
1061 static void lowercase_pkt(uint8_t* pkt, size_t pktlen)
1062 {
1063 	uint16_t i;
1064 	uint8_t* p = pkt;
1065 	size_t remain = pktlen;
1066 	uint16_t t, rdatalen;
1067 	if(pktlen < LDNS_HEADER_SIZE)
1068 		return;
1069 	p += LDNS_HEADER_SIZE;
1070 	remain -= LDNS_HEADER_SIZE;
1071 	for(i=0; i<LDNS_QDCOUNT(pkt); i++) {
1072 		lowercase_dname(&p, &remain);
1073 		if(remain < 4) return;
1074 		p += 4;
1075 		remain -= 4;
1076 	}
1077 	for(i=0; i<LDNS_ANCOUNT(pkt)+LDNS_NSCOUNT(pkt)+LDNS_ARCOUNT(pkt); i++) {
1078 		lowercase_dname(&p, &remain);
1079 		if(remain < 10) return;
1080 		t = sldns_read_uint16(p);
1081 		rdatalen = sldns_read_uint16(p+8);
1082 		p += 10;
1083 		remain -= 10;
1084 		if(remain < rdatalen) return;
1085 		lowercase_rdata(&p, &remain, rdatalen, t);
1086 	}
1087 }
1088 
1089 /** match all of the packet */
1090 int
1091 match_all(uint8_t* q, size_t qlen, uint8_t* p, size_t plen, int mttl,
1092 	int noloc)
1093 {
1094 	char* qstr, *pstr;
1095 	uint8_t* qb = q, *pb = p;
1096 	int r;
1097 	/* zero TTLs */
1098 	qb = memdup(q, qlen);
1099 	pb = memdup(p, plen);
1100 	if(!qb || !pb) error("out of memory");
1101 	if(!mttl) {
1102 		zerottls(qb, qlen);
1103 		zerottls(pb, plen);
1104 	}
1105 	lowercase_pkt(qb, qlen);
1106 	lowercase_pkt(pb, plen);
1107 	qstr = sldns_wire2str_pkt(qb, qlen);
1108 	pstr = sldns_wire2str_pkt(pb, plen);
1109 	if(!qstr || !pstr) error("cannot pkt2string");
1110 	r = (strcmp(qstr, pstr) == 0);
1111 	if(!r) {
1112 		/* remove ;; MSG SIZE (at end of string) */
1113 		char* s = strstr(qstr, ";; MSG SIZE");
1114 		if(s) *s=0;
1115 		s = strstr(pstr, ";; MSG SIZE");
1116 		if(s) *s=0;
1117 		r = (strcmp(qstr, pstr) == 0);
1118 		if(!r && !noloc) {
1119 			/* we are going to fail see if it is because of EDNS */
1120 			char* a = strstr(qstr, "; EDNS");
1121 			char* b = strstr(pstr, "; EDNS");
1122 			if( (a&&!b) || (b&&!a) ) {
1123 				verbose(3, "mismatch in EDNS\n");
1124 			}
1125 		}
1126 	}
1127 	if(!r && noloc) {
1128 		/* check for reordered sections */
1129 		r = match_noloc(qstr, pstr, q, qlen, p, plen);
1130 	}
1131 	free(qstr);
1132 	free(pstr);
1133 	free(qb);
1134 	free(pb);
1135 	return r;
1136 }
1137 
1138 /** see if domain names are equal */
1139 static int equal_dname(uint8_t* q, size_t qlen, uint8_t* p, size_t plen)
1140 {
1141 	uint8_t* qn = get_qname(q, qlen);
1142 	uint8_t* pn = get_qname(p, plen);
1143 	char qs[512], ps[512];
1144 	size_t qslen = sizeof(qs), pslen = sizeof(ps);
1145 	char* qss = qs, *pss = ps;
1146 	if(!qn || !pn)
1147 		return 0;
1148 	(void)sldns_wire2str_dname_scan(&qn, &qlen, &qss, &qslen, q, qlen);
1149 	(void)sldns_wire2str_dname_scan(&pn, &plen, &pss, &pslen, p, plen);
1150 	return (strcmp(qs, ps) == 0);
1151 }
1152 
1153 /** see if domain names are subdomain q of p */
1154 static int subdomain_dname(uint8_t* q, size_t qlen, uint8_t* p, size_t plen)
1155 {
1156 	/* we use the tostring routines so as to test unbound's routines
1157 	 * with something else */
1158 	uint8_t* qn = get_qname(q, qlen);
1159 	uint8_t* pn = get_qname(p, plen);
1160 	char qs[5120], ps[5120];
1161 	size_t qslen = sizeof(qs), pslen = sizeof(ps);
1162 	char* qss = qs, *pss = ps;
1163 	if(!qn || !pn)
1164 		return 0;
1165 	/* decompresses domain names */
1166 	(void)sldns_wire2str_dname_scan(&qn, &qlen, &qss, &qslen, q, qlen);
1167 	(void)sldns_wire2str_dname_scan(&pn, &plen, &pss, &pslen, p, plen);
1168 	/* same: false, (strict subdomain check)??? */
1169 	if(strcmp(qs, ps) == 0)
1170 		return 1;
1171 	/* qs must end in ps, at a dot, without \ in front */
1172 	qslen = strlen(qs);
1173 	pslen = strlen(ps);
1174 	if(qslen > pslen && strcmp(qs + (qslen-pslen), ps) == 0 &&
1175 		qslen + 2 >= pslen && /* space for label and dot */
1176 		qs[qslen-pslen-1] == '.') {
1177 		unsigned int slashcount = 0;
1178 		size_t i = qslen-pslen-2;
1179 		while(i>0 && qs[i]=='\\') {
1180 			i++;
1181 			slashcount++;
1182 		}
1183 		if(slashcount%1 == 1) return 0; /* . preceded by \ */
1184 		return 1;
1185 	}
1186 	return 0;
1187 }
1188 
1189 /* finds entry in list, or returns NULL */
1190 struct entry*
1191 find_match(struct entry* entries, uint8_t* query_pkt, size_t len,
1192 	enum transport_type transport)
1193 {
1194 	struct entry* p = entries;
1195 	uint8_t* reply;
1196 	size_t rlen;
1197 	for(p=entries; p; p=p->next) {
1198 		verbose(3, "comparepkt: ");
1199 		reply = p->reply_list->reply_pkt;
1200 		rlen = p->reply_list->reply_len;
1201 		if(p->match_opcode && get_opcode(query_pkt, len) !=
1202 			get_opcode(reply, rlen)) {
1203 			verbose(3, "bad opcode\n");
1204 			continue;
1205 		}
1206 		if(p->match_qtype && get_qtype(query_pkt, len) !=
1207 			get_qtype(reply, rlen)) {
1208 			verbose(3, "bad qtype %d %d\n", get_qtype(query_pkt, len), get_qtype(reply, rlen));
1209 			continue;
1210 		}
1211 		if(p->match_qname) {
1212 			if(!equal_dname(query_pkt, len, reply, rlen)) {
1213 				verbose(3, "bad qname\n");
1214 				continue;
1215 			}
1216 		}
1217 		if(p->match_subdomain) {
1218 			if(!subdomain_dname(query_pkt, len, reply, rlen)) {
1219 				verbose(3, "bad subdomain\n");
1220 				continue;
1221 			}
1222 		}
1223 		if(p->match_serial && get_serial(query_pkt, len) != p->ixfr_soa_serial) {
1224 				verbose(3, "bad serial\n");
1225 				continue;
1226 		}
1227 		if(p->match_do && !get_do_flag(query_pkt, len)) {
1228 			verbose(3, "no DO bit set\n");
1229 			continue;
1230 		}
1231 		if(p->match_noedns && get_has_edns(query_pkt, len)) {
1232 			verbose(3, "bad; EDNS OPT present\n");
1233 			continue;
1234 		}
1235 		if(p->match_transport != transport_any && p->match_transport != transport) {
1236 			verbose(3, "bad transport\n");
1237 			continue;
1238 		}
1239 		if(p->match_all && !match_all(query_pkt, len, reply, rlen,
1240 			(int)p->match_ttl, 0)) {
1241 			verbose(3, "bad allmatch\n");
1242 			continue;
1243 		}
1244 		verbose(3, "match!\n");
1245 		return p;
1246 	}
1247 	return NULL;
1248 }
1249 
1250 void
1251 adjust_packet(struct entry* match, uint8_t** answer_pkt, size_t *answer_len,
1252 	uint8_t* query_pkt, size_t query_len)
1253 {
1254 	uint8_t* orig = *answer_pkt;
1255 	size_t origlen = *answer_len;
1256 	uint8_t* res;
1257 	size_t reslen;
1258 
1259 	/* perform the copy; if possible; must be uncompressed */
1260 	if(match->copy_query && origlen >= LDNS_HEADER_SIZE &&
1261 		query_len >= LDNS_HEADER_SIZE && LDNS_QDCOUNT(query_pkt)!=0
1262 		&& LDNS_QDCOUNT(orig)==0) {
1263 		/* no qname in output packet, insert it */
1264 		size_t dlen = get_qname_len(query_pkt, query_len);
1265 		reslen = origlen + dlen + 4;
1266 		res = (uint8_t*)malloc(reslen);
1267 		if(!res) {
1268 			verbose(1, "out of memory; send without adjust\n");
1269 			return;
1270 		}
1271 		/* copy the header, query, remainder */
1272 		memcpy(res, orig, LDNS_HEADER_SIZE);
1273 		memmove(res+LDNS_HEADER_SIZE, query_pkt+LDNS_HEADER_SIZE,
1274 			dlen+4);
1275 		memmove(res+LDNS_HEADER_SIZE+dlen+4, orig+LDNS_HEADER_SIZE,
1276 			reslen-(LDNS_HEADER_SIZE+dlen+4));
1277 		/* set QDCOUNT */
1278 		sldns_write_uint16(res+4, 1);
1279 	} else if(match->copy_query && origlen >= LDNS_HEADER_SIZE &&
1280 		query_len >= LDNS_HEADER_SIZE && LDNS_QDCOUNT(query_pkt)!=0
1281 		&& get_qname_len(orig, origlen) == 0) {
1282 		/* QDCOUNT(orig)!=0 but qlen == 0, therefore, an error */
1283 		verbose(1, "error: malformed qname; send without adjust\n");
1284 		res = memdup(orig, origlen);
1285 		reslen = origlen;
1286 	} else if(match->copy_query && origlen >= LDNS_HEADER_SIZE &&
1287 		query_len >= LDNS_HEADER_SIZE && LDNS_QDCOUNT(query_pkt)!=0
1288 		&& LDNS_QDCOUNT(orig)!=0) {
1289 		/* in this case olen != 0 and QDCOUNT(orig)!=0 */
1290 		/* copy query section */
1291 		size_t dlen = get_qname_len(query_pkt, query_len);
1292 		size_t olen = get_qname_len(orig, origlen);
1293 		reslen = origlen + dlen - olen;
1294 		res = (uint8_t*)malloc(reslen);
1295 		if(!res) {
1296 			verbose(1, "out of memory; send without adjust\n");
1297 			return;
1298 		}
1299 		/* copy the header, query, remainder */
1300 		memcpy(res, orig, LDNS_HEADER_SIZE);
1301 		memmove(res+LDNS_HEADER_SIZE, query_pkt+LDNS_HEADER_SIZE,
1302 			dlen+4);
1303 		memmove(res+LDNS_HEADER_SIZE+dlen+4,
1304 			orig+LDNS_HEADER_SIZE+olen+4,
1305 			reslen-(LDNS_HEADER_SIZE+dlen+4));
1306 	} else {
1307 		res = memdup(orig, origlen);
1308 		reslen = origlen;
1309 	}
1310 	if(!res) {
1311 		verbose(1, "out of memory; send without adjust\n");
1312 		return;
1313 	}
1314 	/* copy the ID */
1315 	if(match->copy_id && reslen >= 2)
1316 		res[1] = orig[1];
1317 	if(match->copy_id && reslen >= 1)
1318 		res[0] = orig[0];
1319 
1320 	if(match->sleeptime > 0) {
1321 		verbose(3, "sleeping for %d seconds\n", match->sleeptime);
1322 #ifdef HAVE_SLEEP
1323 		sleep(match->sleeptime);
1324 #else
1325 		Sleep(match->sleeptime * 1000);
1326 #endif
1327 	}
1328 	*answer_pkt = res;
1329 	*answer_len = reslen;
1330 }
1331 
1332 /*
1333  * Parses data buffer to a query, finds the correct answer
1334  * and calls the given function for every packet to send.
1335  */
1336 void
1337 handle_query(uint8_t* inbuf, ssize_t inlen, struct entry* entries, int* count,
1338 	enum transport_type transport, void (*sendfunc)(uint8_t*, size_t, void*),
1339 	void* userdata, FILE* verbose_out)
1340 {
1341 	struct reply_packet *p;
1342 	uint8_t *outbuf = NULL;
1343 	size_t outlen = 0;
1344 	struct entry* entry = NULL;
1345 
1346 	verbose(1, "query %d: id %d: %s %d bytes: ", ++(*count),
1347 		(int)(inlen>=2?LDNS_ID_WIRE(inbuf):0),
1348 		(transport==transport_tcp)?"TCP":"UDP", (int)inlen);
1349 	if(verbose_out) {
1350 		char* out = sldns_wire2str_pkt(inbuf, (size_t)inlen);
1351 		printf("%s\n", out);
1352 		free(out);
1353 	}
1354 
1355 	/* fill up answer packet */
1356 	entry = find_match(entries, inbuf, (size_t)inlen, transport);
1357 	if(!entry || !entry->reply_list) {
1358 		verbose(1, "no answer packet for this query, no reply.\n");
1359 		return;
1360 	}
1361 	for(p = entry->reply_list; p; p = p->next)
1362 	{
1363 		verbose(3, "Answer pkt:\n");
1364 		if (p->reply_from_hex) {
1365 			/* try to adjust the hex packet, if it can be
1366 			 * parsed, we can use adjust rules. if not,
1367 			 * send packet literally */
1368 			/* still try to adjust ID if others fail */
1369 			outlen = sldns_buffer_limit(p->reply_from_hex);
1370 			outbuf = sldns_buffer_begin(p->reply_from_hex);
1371 		} else {
1372 			outbuf = p->reply_pkt;
1373 			outlen = p->reply_len;
1374 		}
1375 		if(!outbuf) {
1376 			verbose(1, "out of memory\n");
1377 			return;
1378 		}
1379 		/* copies outbuf in memory allocation */
1380 		adjust_packet(entry, &outbuf, &outlen, inbuf, (size_t)inlen);
1381 		verbose(1, "Answer packet size: %u bytes.\n", (unsigned int)outlen);
1382 		if(verbose_out) {
1383 			char* out = sldns_wire2str_pkt(outbuf, outlen);
1384 			printf("%s\n", out);
1385 			free(out);
1386 		}
1387 		if(p->packet_sleep) {
1388 			verbose(3, "sleeping for next packet %d secs\n",
1389 				p->packet_sleep);
1390 #ifdef HAVE_SLEEP
1391 			sleep(p->packet_sleep);
1392 #else
1393 			Sleep(p->packet_sleep * 1000);
1394 #endif
1395 			verbose(3, "wakeup for next packet "
1396 				"(slept %d secs)\n", p->packet_sleep);
1397 		}
1398 		sendfunc(outbuf, outlen, userdata);
1399 		free(outbuf);
1400 		outbuf = NULL;
1401 		outlen = 0;
1402 	}
1403 }
1404 
1405 /** delete the list of reply packets */
1406 void delete_replylist(struct reply_packet* replist)
1407 {
1408 	struct reply_packet *p=replist, *np;
1409 	while(p) {
1410 		np = p->next;
1411 		free(p->reply_pkt);
1412 		sldns_buffer_free(p->reply_from_hex);
1413 		free(p);
1414 		p=np;
1415 	}
1416 }
1417 
1418 void delete_entry(struct entry* list)
1419 {
1420 	struct entry *p=list, *np;
1421 	while(p) {
1422 		np = p->next;
1423 		delete_replylist(p->reply_list);
1424 		free(p);
1425 		p = np;
1426 	}
1427 }
1428