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