Home | History | Annotate | Line # | Download | only in testcode
testpkts.c revision 1.1.1.1.2.2
      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