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