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