1 /* dnsmasq is Copyright (c) 2000-2009 Simon Kelley 2 3 This program is free software; you can redistribute it and/or modify 4 it under the terms of the GNU General Public License as published by 5 the Free Software Foundation; version 2 dated June, 1991, or 6 (at your option) version 3 dated 29 June, 2007. 7 8 This program is distributed in the hope that it will be useful, 9 but WITHOUT ANY WARRANTY; without even the implied warranty of 10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 GNU General Public License for more details. 12 13 You should have received a copy of the GNU General Public License 14 along with this program. If not, see <http://www.gnu.org/licenses/>. 15 */ 16 17 #include "dnsmasq.h" 18 19 static int add_resource_record(HEADER *header, char *limit, int *truncp, 20 unsigned int nameoffset, unsigned char **pp, 21 unsigned long ttl, unsigned int *offset, unsigned short type, 22 unsigned short class, char *format, ...); 23 24 #define CHECK_LEN(header, pp, plen, len) \ 25 ((size_t)((pp) - (unsigned char *)(header) + (len)) <= (plen)) 26 27 #define ADD_RDLEN(header, pp, plen, len) \ 28 (!CHECK_LEN(header, pp, plen, len) ? 0 : (long)((pp) += (len)), 1) 29 30 static int extract_name(HEADER *header, size_t plen, unsigned char **pp, 31 char *name, int isExtract, int extrabytes) 32 { 33 unsigned char *cp = (unsigned char *)name, *p = *pp, *p1 = NULL; 34 unsigned int j, l, hops = 0; 35 int retvalue = 1; 36 37 if (isExtract) 38 *cp = 0; 39 40 while (1) 41 { 42 unsigned int label_type; 43 44 if (!CHECK_LEN(header, p, plen, 1)) 45 return 0; 46 47 if ((l = *p++) == 0) 48 /* end marker */ 49 { 50 /* check that there are the correct no of bytes after the name */ 51 if (!CHECK_LEN(header, p, plen, extrabytes)) 52 return 0; 53 54 if (isExtract) 55 { 56 if (cp != (unsigned char *)name) 57 cp--; 58 *cp = 0; /* terminate: lose final period */ 59 } 60 else if (*cp != 0) 61 retvalue = 2; 62 63 if (p1) /* we jumped via compression */ 64 *pp = p1; 65 else 66 *pp = p; 67 68 return retvalue; 69 } 70 71 label_type = l & 0xc0; 72 73 if (label_type == 0xc0) /* pointer */ 74 { 75 if (!CHECK_LEN(header, p, plen, 1)) 76 return 0; 77 78 /* get offset */ 79 l = (l&0x3f) << 8; 80 l |= *p++; 81 82 if (!p1) /* first jump, save location to go back to */ 83 p1 = p; 84 85 hops++; /* break malicious infinite loops */ 86 if (hops > 255) 87 return 0; 88 89 p = l + (unsigned char *)header; 90 } 91 else if (label_type == 0x80) 92 return 0; /* reserved */ 93 else if (label_type == 0x40) 94 { /* ELT */ 95 unsigned int count, digs; 96 97 if ((l & 0x3f) != 1) 98 return 0; /* we only understand bitstrings */ 99 100 if (!isExtract) 101 return 0; /* Cannot compare bitsrings */ 102 103 count = *p++; 104 if (count == 0) 105 count = 256; 106 digs = ((count-1)>>2)+1; 107 108 /* output is \[x<hex>/siz]. which is digs+9 chars */ 109 if (cp - (unsigned char *)name + digs + 9 >= MAXDNAME) 110 return 0; 111 if (!CHECK_LEN(header, p, plen, (count-1)>>3)) 112 return 0; 113 114 *cp++ = '\\'; 115 *cp++ = '['; 116 *cp++ = 'x'; 117 for (j=0; j<digs; j++) 118 { 119 unsigned int dig; 120 if (j%2 == 0) 121 dig = *p >> 4; 122 else 123 dig = *p++ & 0x0f; 124 125 *cp++ = dig < 10 ? dig + '0' : dig + 'A' - 10; 126 } 127 cp += sprintf((char *)cp, "/%d]", count); 128 /* do this here to overwrite the zero char from sprintf */ 129 *cp++ = '.'; 130 } 131 else 132 { /* label_type = 0 -> label. */ 133 if (cp - (unsigned char *)name + l + 1 >= MAXDNAME) 134 return 0; 135 if (!CHECK_LEN(header, p, plen, l)) 136 return 0; 137 138 for(j=0; j<l; j++, p++) 139 if (isExtract) 140 { 141 unsigned char c = *p; 142 if (isascii(c) && !iscntrl(c) && c != '.') 143 *cp++ = *p; 144 else 145 return 0; 146 } 147 else 148 { 149 unsigned char c1 = *cp, c2 = *p; 150 151 if (c1 == 0) 152 retvalue = 2; 153 else 154 { 155 cp++; 156 if (c1 >= 'A' && c1 <= 'Z') 157 c1 += 'a' - 'A'; 158 if (c2 >= 'A' && c2 <= 'Z') 159 c2 += 'a' - 'A'; 160 161 if (c1 != c2) 162 retvalue = 2; 163 } 164 } 165 166 if (isExtract) 167 *cp++ = '.'; 168 else if (*cp != 0 && *cp++ != '.') 169 retvalue = 2; 170 } 171 } 172 } 173 174 /* Max size of input string (for IPv6) is 75 chars.) */ 175 #define MAXARPANAME 75 176 static int in_arpa_name_2_addr(char *namein, struct all_addr *addrp) 177 { 178 int j; 179 char name[MAXARPANAME+1], *cp1; 180 unsigned char *addr = (unsigned char *)addrp; 181 char *lastchunk = NULL, *penchunk = NULL; 182 183 if (strlen(namein) > MAXARPANAME) 184 return 0; 185 186 memset(addrp, 0, sizeof(struct all_addr)); 187 188 /* turn name into a series of asciiz strings */ 189 /* j counts no of labels */ 190 for(j = 1,cp1 = name; *namein; cp1++, namein++) 191 if (*namein == '.') 192 { 193 penchunk = lastchunk; 194 lastchunk = cp1 + 1; 195 *cp1 = 0; 196 j++; 197 } 198 else 199 *cp1 = *namein; 200 201 *cp1 = 0; 202 203 if (j<3) 204 return 0; 205 206 if (hostname_isequal(lastchunk, "arpa") && hostname_isequal(penchunk, "in-addr")) 207 { 208 /* IP v4 */ 209 /* address arives as a name of the form 210 www.xxx.yyy.zzz.in-addr.arpa 211 some of the low order address octets might be missing 212 and should be set to zero. */ 213 for (cp1 = name; cp1 != penchunk; cp1 += strlen(cp1)+1) 214 { 215 /* check for digits only (weeds out things like 216 50.0/24.67.28.64.in-addr.arpa which are used 217 as CNAME targets according to RFC 2317 */ 218 char *cp; 219 for (cp = cp1; *cp; cp++) 220 if (!isdigit((int)*cp)) 221 return 0; 222 223 addr[3] = addr[2]; 224 addr[2] = addr[1]; 225 addr[1] = addr[0]; 226 addr[0] = atoi(cp1); 227 } 228 229 return F_IPV4; 230 } 231 #ifdef HAVE_IPV6 232 else if (hostname_isequal(penchunk, "ip6") && 233 (hostname_isequal(lastchunk, "int") || hostname_isequal(lastchunk, "arpa"))) 234 { 235 /* IP v6: 236 Address arrives as 0.1.2.3.4.5.6.7.8.9.a.b.c.d.e.f.ip6.[int|arpa] 237 or \[xfedcba9876543210fedcba9876543210/128].ip6.[int|arpa] 238 239 Note that most of these the various reprentations are obsolete and 240 left-over from the many DNS-for-IPv6 wars. We support all the formats 241 that we can since there is no reason not to. 242 */ 243 244 if (*name == '\\' && *(name+1) == '[' && 245 (*(name+2) == 'x' || *(name+2) == 'X')) 246 { 247 for (j = 0, cp1 = name+3; *cp1 && isxdigit((int) *cp1) && j < 32; cp1++, j++) 248 { 249 char xdig[2]; 250 xdig[0] = *cp1; 251 xdig[1] = 0; 252 if (j%2) 253 addr[j/2] |= strtol(xdig, NULL, 16); 254 else 255 addr[j/2] = strtol(xdig, NULL, 16) << 4; 256 } 257 258 if (*cp1 == '/' && j == 32) 259 return F_IPV6; 260 } 261 else 262 { 263 for (cp1 = name; cp1 != penchunk; cp1 += strlen(cp1)+1) 264 { 265 if (*(cp1+1) || !isxdigit((int)*cp1)) 266 return 0; 267 268 for (j = sizeof(struct all_addr)-1; j>0; j--) 269 addr[j] = (addr[j] >> 4) | (addr[j-1] << 4); 270 addr[0] = (addr[0] >> 4) | (strtol(cp1, NULL, 16) << 4); 271 } 272 273 return F_IPV6; 274 } 275 } 276 #endif 277 278 return 0; 279 } 280 281 static unsigned char *skip_name(unsigned char *ansp, HEADER *header, size_t plen, int extrabytes) 282 { 283 while(1) 284 { 285 unsigned int label_type; 286 287 if (!CHECK_LEN(header, ansp, plen, 1)) 288 return NULL; 289 290 label_type = (*ansp) & 0xc0; 291 292 if (label_type == 0xc0) 293 { 294 /* pointer for compression. */ 295 ansp += 2; 296 break; 297 } 298 else if (label_type == 0x80) 299 return NULL; /* reserved */ 300 else if (label_type == 0x40) 301 { 302 /* Extended label type */ 303 unsigned int count; 304 305 if (!CHECK_LEN(header, ansp, plen, 2)) 306 return NULL; 307 308 if (((*ansp++) & 0x3f) != 1) 309 return NULL; /* we only understand bitstrings */ 310 311 count = *(ansp++); /* Bits in bitstring */ 312 313 if (count == 0) /* count == 0 means 256 bits */ 314 ansp += 32; 315 else 316 ansp += ((count-1)>>3)+1; 317 } 318 else 319 { /* label type == 0 Bottom six bits is length */ 320 unsigned int len = (*ansp++) & 0x3f; 321 322 if (!ADD_RDLEN(header, ansp, plen, len)) 323 return NULL; 324 325 if (len == 0) 326 break; /* zero length label marks the end. */ 327 } 328 } 329 330 if (!CHECK_LEN(header, ansp, plen, extrabytes)) 331 return NULL; 332 333 return ansp; 334 } 335 336 static unsigned char *skip_questions(HEADER *header, size_t plen) 337 { 338 int q; 339 unsigned char *ansp = (unsigned char *)(header+1); 340 341 for (q = ntohs(header->qdcount); q != 0; q--) 342 { 343 if (!(ansp = skip_name(ansp, header, plen, 4))) 344 return NULL; 345 ansp += 4; /* class and type */ 346 } 347 348 return ansp; 349 } 350 351 static unsigned char *skip_section(unsigned char *ansp, int count, HEADER *header, size_t plen) 352 { 353 int i, rdlen; 354 355 for (i = 0; i < count; i++) 356 { 357 if (!(ansp = skip_name(ansp, header, plen, 10))) 358 return NULL; 359 ansp += 8; /* type, class, TTL */ 360 GETSHORT(rdlen, ansp); 361 if (!ADD_RDLEN(header, ansp, plen, rdlen)) 362 return NULL; 363 } 364 365 return ansp; 366 } 367 368 /* CRC the question section. This is used to safely detect query 369 retransmision and to detect answers to questions we didn't ask, which 370 might be poisoning attacks. Note that we decode the name rather 371 than CRC the raw bytes, since replies might be compressed differently. 372 We ignore case in the names for the same reason. Return all-ones 373 if there is not question section. */ 374 unsigned int questions_crc(HEADER *header, size_t plen, char *name) 375 { 376 int q; 377 unsigned int crc = 0xffffffff; 378 unsigned char *p1, *p = (unsigned char *)(header+1); 379 380 for (q = ntohs(header->qdcount); q != 0; q--) 381 { 382 if (!extract_name(header, plen, &p, name, 1, 4)) 383 return crc; /* bad packet */ 384 385 for (p1 = (unsigned char *)name; *p1; p1++) 386 { 387 int i = 8; 388 char c = *p1; 389 390 if (c >= 'A' && c <= 'Z') 391 c += 'a' - 'A'; 392 393 crc ^= c << 24; 394 while (i--) 395 crc = crc & 0x80000000 ? (crc << 1) ^ 0x04c11db7 : crc << 1; 396 } 397 398 /* CRC the class and type as well */ 399 for (p1 = p; p1 < p+4; p1++) 400 { 401 int i = 8; 402 crc ^= *p1 << 24; 403 while (i--) 404 crc = crc & 0x80000000 ? (crc << 1) ^ 0x04c11db7 : crc << 1; 405 } 406 407 p += 4; 408 if (!CHECK_LEN(header, p, plen, 0)) 409 return crc; /* bad packet */ 410 } 411 412 return crc; 413 } 414 415 416 size_t resize_packet(HEADER *header, size_t plen, unsigned char *pheader, size_t hlen) 417 { 418 unsigned char *ansp = skip_questions(header, plen); 419 420 /* if packet is malformed, just return as-is. */ 421 if (!ansp) 422 return plen; 423 424 if (!(ansp = skip_section(ansp, ntohs(header->ancount) + ntohs(header->nscount) + ntohs(header->arcount), 425 header, plen))) 426 return plen; 427 428 /* restore pseudoheader */ 429 if (pheader && ntohs(header->arcount) == 0) 430 { 431 /* must use memmove, may overlap */ 432 memmove(ansp, pheader, hlen); 433 header->arcount = htons(1); 434 ansp += hlen; 435 } 436 437 return ansp - (unsigned char *)header; 438 } 439 440 unsigned char *find_pseudoheader(HEADER *header, size_t plen, size_t *len, unsigned char **p, int *is_sign) 441 { 442 /* See if packet has an RFC2671 pseudoheader, and if so return a pointer to it. 443 also return length of pseudoheader in *len and pointer to the UDP size in *p 444 Finally, check to see if a packet is signed. If it is we cannot change a single bit before 445 forwarding. We look for SIG and TSIG in the addition section, and TKEY queries (for GSS-TSIG) */ 446 447 int i, arcount = ntohs(header->arcount); 448 unsigned char *ansp = (unsigned char *)(header+1); 449 unsigned short rdlen, type, class; 450 unsigned char *ret = NULL; 451 452 if (is_sign) 453 { 454 *is_sign = 0; 455 456 if (header->opcode == QUERY) 457 { 458 for (i = ntohs(header->qdcount); i != 0; i--) 459 { 460 if (!(ansp = skip_name(ansp, header, plen, 4))) 461 return NULL; 462 463 GETSHORT(type, ansp); 464 GETSHORT(class, ansp); 465 466 if (class == C_IN && type == T_TKEY) 467 *is_sign = 1; 468 } 469 } 470 } 471 else 472 { 473 if (!(ansp = skip_questions(header, plen))) 474 return NULL; 475 } 476 477 if (arcount == 0) 478 return NULL; 479 480 if (!(ansp = skip_section(ansp, ntohs(header->ancount) + ntohs(header->nscount), header, plen))) 481 return NULL; 482 483 for (i = 0; i < arcount; i++) 484 { 485 unsigned char *save, *start = ansp; 486 if (!(ansp = skip_name(ansp, header, plen, 10))) 487 return NULL; 488 489 GETSHORT(type, ansp); 490 save = ansp; 491 GETSHORT(class, ansp); 492 ansp += 4; /* TTL */ 493 GETSHORT(rdlen, ansp); 494 if (!ADD_RDLEN(header, ansp, plen, rdlen)) 495 return NULL; 496 if (type == T_OPT) 497 { 498 if (len) 499 *len = ansp - start; 500 if (p) 501 *p = save; 502 ret = start; 503 } 504 else if (is_sign && 505 i == arcount - 1 && 506 class == C_ANY && 507 (type == T_SIG || type == T_TSIG)) 508 *is_sign = 1; 509 } 510 511 return ret; 512 } 513 514 515 /* is addr in the non-globally-routed IP space? */ 516 static int private_net(struct in_addr addr) 517 { 518 in_addr_t ip_addr = ntohl(addr.s_addr); 519 520 return 521 ((ip_addr & 0xFF000000) == 0x7F000000) /* 127.0.0.0/8 (loopback) */ || 522 ((ip_addr & 0xFFFF0000) == 0xC0A80000) /* 192.168.0.0/16 (private) */ || 523 ((ip_addr & 0xFF000000) == 0x0A000000) /* 10.0.0.0/8 (private) */ || 524 ((ip_addr & 0xFFF00000) == 0xAC100000) /* 172.16.0.0/12 (private) */ || 525 ((ip_addr & 0xFFFF0000) == 0xA9FE0000) /* 169.254.0.0/16 (zeroconf) */ ; 526 } 527 528 static unsigned char *do_doctor(unsigned char *p, int count, HEADER *header, size_t qlen) 529 { 530 int i, qtype, qclass, rdlen; 531 unsigned long ttl; 532 533 for (i = count; i != 0; i--) 534 { 535 if (!(p = skip_name(p, header, qlen, 10))) 536 return 0; /* bad packet */ 537 538 GETSHORT(qtype, p); 539 GETSHORT(qclass, p); 540 GETLONG(ttl, p); 541 GETSHORT(rdlen, p); 542 543 if ((qclass == C_IN) && (qtype == T_A)) 544 { 545 struct doctor *doctor; 546 struct in_addr addr; 547 548 if (!CHECK_LEN(header, p, qlen, INADDRSZ)) 549 return 0; 550 551 /* alignment */ 552 memcpy(&addr, p, INADDRSZ); 553 554 for (doctor = daemon->doctors; doctor; doctor = doctor->next) 555 { 556 if (doctor->end.s_addr == 0) 557 { 558 if (!is_same_net(doctor->in, addr, doctor->mask)) 559 continue; 560 } 561 else if (ntohl(doctor->in.s_addr) > ntohl(addr.s_addr) || 562 ntohl(doctor->end.s_addr) < ntohl(addr.s_addr)) 563 continue; 564 565 addr.s_addr &= ~doctor->mask.s_addr; 566 addr.s_addr |= (doctor->out.s_addr & doctor->mask.s_addr); 567 /* Since we munged the data, the server it came from is no longer authoritative */ 568 header->aa = 0; 569 memcpy(p, &addr, INADDRSZ); 570 break; 571 } 572 } 573 574 if (!ADD_RDLEN(header, p, qlen, rdlen)) 575 return 0; /* bad packet */ 576 } 577 578 return p; 579 } 580 581 static int find_soa(HEADER *header, size_t qlen) 582 { 583 unsigned char *p; 584 int qtype, qclass, rdlen; 585 unsigned long ttl, minttl = ULONG_MAX; 586 int i, found_soa = 0; 587 588 /* first move to NS section and find TTL from any SOA section */ 589 if (!(p = skip_questions(header, qlen)) || 590 !(p = do_doctor(p, ntohs(header->ancount), header, qlen))) 591 return 0; /* bad packet */ 592 593 for (i = ntohs(header->nscount); i != 0; i--) 594 { 595 if (!(p = skip_name(p, header, qlen, 10))) 596 return 0; /* bad packet */ 597 598 GETSHORT(qtype, p); 599 GETSHORT(qclass, p); 600 GETLONG(ttl, p); 601 GETSHORT(rdlen, p); 602 603 if ((qclass == C_IN) && (qtype == T_SOA)) 604 { 605 found_soa = 1; 606 if (ttl < minttl) 607 minttl = ttl; 608 609 /* MNAME */ 610 if (!(p = skip_name(p, header, qlen, 0))) 611 return 0; 612 /* RNAME */ 613 if (!(p = skip_name(p, header, qlen, 20))) 614 return 0; 615 p += 16; /* SERIAL REFRESH RETRY EXPIRE */ 616 617 GETLONG(ttl, p); /* minTTL */ 618 if (ttl < minttl) 619 minttl = ttl; 620 } 621 else if (!ADD_RDLEN(header, p, qlen, rdlen)) 622 return 0; /* bad packet */ 623 } 624 625 /* rewrite addresses in additioal section too */ 626 if (!do_doctor(p, ntohs(header->arcount), header, qlen)) 627 return 0; 628 629 if (!found_soa) 630 minttl = daemon->neg_ttl; 631 632 return minttl; 633 } 634 635 /* Note that the following code can create CNAME chains that don't point to a real record, 636 either because of lack of memory, or lack of SOA records. These are treated by the cache code as 637 expired and cleaned out that way. 638 Return 1 if we reject an address because it look like parct of dns-rebinding attack. */ 639 int extract_addresses(HEADER *header, size_t qlen, char *name, time_t now) 640 { 641 unsigned char *p, *p1, *endrr, *namep; 642 int i, j, qtype, qclass, aqtype, aqclass, ardlen, res, searched_soa = 0; 643 unsigned long ttl = 0; 644 struct all_addr addr; 645 646 cache_start_insert(); 647 648 /* find_soa is needed for dns_doctor side-effects, so don't call it lazily if there are any. */ 649 if (daemon->doctors) 650 { 651 searched_soa = 1; 652 ttl = find_soa(header, qlen); 653 } 654 655 /* go through the questions. */ 656 p = (unsigned char *)(header+1); 657 658 for (i = ntohs(header->qdcount); i != 0; i--) 659 { 660 int found = 0, cname_count = 5; 661 struct crec *cpp = NULL; 662 int flags = header->rcode == NXDOMAIN ? F_NXDOMAIN : 0; 663 unsigned long cttl = ULONG_MAX, attl; 664 665 namep = p; 666 if (!extract_name(header, qlen, &p, name, 1, 4)) 667 return 0; /* bad packet */ 668 669 GETSHORT(qtype, p); 670 GETSHORT(qclass, p); 671 672 if (qclass != C_IN) 673 continue; 674 675 /* PTRs: we chase CNAMEs here, since we have no way to 676 represent them in the cache. */ 677 if (qtype == T_PTR) 678 { 679 int name_encoding = in_arpa_name_2_addr(name, &addr); 680 681 if (!name_encoding) 682 continue; 683 684 if (!(flags & F_NXDOMAIN)) 685 { 686 cname_loop: 687 if (!(p1 = skip_questions(header, qlen))) 688 return 0; 689 690 for (j = ntohs(header->ancount); j != 0; j--) 691 { 692 unsigned char *tmp = namep; 693 /* the loop body overwrites the original name, so get it back here. */ 694 if (!extract_name(header, qlen, &tmp, name, 1, 0) || 695 !(res = extract_name(header, qlen, &p1, name, 0, 10))) 696 return 0; /* bad packet */ 697 698 GETSHORT(aqtype, p1); 699 GETSHORT(aqclass, p1); 700 GETLONG(attl, p1); 701 GETSHORT(ardlen, p1); 702 endrr = p1+ardlen; 703 704 /* TTL of record is minimum of CNAMES and PTR */ 705 if (attl < cttl) 706 cttl = attl; 707 708 if (aqclass == C_IN && res != 2 && (aqtype == T_CNAME || aqtype == T_PTR)) 709 { 710 if (!extract_name(header, qlen, &p1, name, 1, 0)) 711 return 0; 712 713 if (aqtype == T_CNAME) 714 { 715 if (!cname_count--) 716 return 0; /* looped CNAMES */ 717 goto cname_loop; 718 } 719 720 cache_insert(name, &addr, now, cttl, name_encoding | F_REVERSE); 721 found = 1; 722 } 723 724 p1 = endrr; 725 if (!CHECK_LEN(header, p1, qlen, 0)) 726 return 0; /* bad packet */ 727 } 728 } 729 730 if (!found && !(daemon->options & OPT_NO_NEG)) 731 { 732 if (!searched_soa) 733 { 734 searched_soa = 1; 735 ttl = find_soa(header, qlen); 736 } 737 if (ttl) 738 cache_insert(NULL, &addr, now, ttl, name_encoding | F_REVERSE | F_NEG | flags); 739 } 740 } 741 else 742 { 743 /* everything other than PTR */ 744 struct crec *newc; 745 int addrlen; 746 747 if (qtype == T_A) 748 { 749 addrlen = INADDRSZ; 750 flags |= F_IPV4; 751 } 752 #ifdef HAVE_IPV6 753 else if (qtype == T_AAAA) 754 { 755 addrlen = IN6ADDRSZ; 756 flags |= F_IPV6; 757 } 758 #endif 759 else 760 continue; 761 762 if (!(flags & F_NXDOMAIN)) 763 { 764 cname_loop1: 765 if (!(p1 = skip_questions(header, qlen))) 766 return 0; 767 768 for (j = ntohs(header->ancount); j != 0; j--) 769 { 770 if (!(res = extract_name(header, qlen, &p1, name, 0, 10))) 771 return 0; /* bad packet */ 772 773 GETSHORT(aqtype, p1); 774 GETSHORT(aqclass, p1); 775 GETLONG(attl, p1); 776 GETSHORT(ardlen, p1); 777 endrr = p1+ardlen; 778 779 if (aqclass == C_IN && res != 2 && (aqtype == T_CNAME || aqtype == qtype)) 780 { 781 if (aqtype == T_CNAME) 782 { 783 if (!cname_count--) 784 return 0; /* looped CNAMES */ 785 newc = cache_insert(name, NULL, now, attl, F_CNAME | F_FORWARD); 786 if (newc && cpp) 787 { 788 cpp->addr.cname.cache = newc; 789 cpp->addr.cname.uid = newc->uid; 790 } 791 792 cpp = newc; 793 if (attl < cttl) 794 cttl = attl; 795 796 if (!extract_name(header, qlen, &p1, name, 1, 0)) 797 return 0; 798 goto cname_loop1; 799 } 800 else 801 { 802 found = 1; 803 804 /* copy address into aligned storage */ 805 if (!CHECK_LEN(header, p1, qlen, addrlen)) 806 return 0; /* bad packet */ 807 memcpy(&addr, p1, addrlen); 808 809 /* check for returned address in private space */ 810 if ((daemon->options & OPT_NO_REBIND) && 811 (flags & F_IPV4) && 812 private_net(addr.addr.addr4)) 813 return 1; 814 815 newc = cache_insert(name, &addr, now, attl, flags | F_FORWARD); 816 if (newc && cpp) 817 { 818 cpp->addr.cname.cache = newc; 819 cpp->addr.cname.uid = newc->uid; 820 } 821 cpp = NULL; 822 } 823 } 824 825 p1 = endrr; 826 if (!CHECK_LEN(header, p1, qlen, 0)) 827 return 0; /* bad packet */ 828 } 829 } 830 831 if (!found && !(daemon->options & OPT_NO_NEG)) 832 { 833 if (!searched_soa) 834 { 835 searched_soa = 1; 836 ttl = find_soa(header, qlen); 837 } 838 /* If there's no SOA to get the TTL from, but there is a CNAME 839 pointing at this, inherit its TTL */ 840 if (ttl || cpp) 841 { 842 newc = cache_insert(name, NULL, now, ttl ? ttl : cttl, F_FORWARD | F_NEG | flags); 843 if (newc && cpp) 844 { 845 cpp->addr.cname.cache = newc; 846 cpp->addr.cname.uid = newc->uid; 847 } 848 } 849 } 850 } 851 } 852 853 /* Don't put stuff from a truncated packet into the cache, but do everything else */ 854 if (!header->tc) 855 cache_end_insert(); 856 857 return 0; 858 } 859 860 /* If the packet holds exactly one query 861 return F_IPV4 or F_IPV6 and leave the name from the query in name. 862 Abuse F_BIGNAME to indicate an NS query - yuck. */ 863 864 unsigned short extract_request(HEADER *header, size_t qlen, char *name, unsigned short *typep) 865 { 866 unsigned char *p = (unsigned char *)(header+1); 867 int qtype, qclass; 868 869 if (typep) 870 *typep = 0; 871 872 if (ntohs(header->qdcount) != 1 || header->opcode != QUERY) 873 return 0; /* must be exactly one query. */ 874 875 if (!extract_name(header, qlen, &p, name, 1, 4)) 876 return 0; /* bad packet */ 877 878 GETSHORT(qtype, p); 879 GETSHORT(qclass, p); 880 881 if (typep) 882 *typep = qtype; 883 884 if (qclass == C_IN) 885 { 886 if (qtype == T_A) 887 return F_IPV4; 888 if (qtype == T_AAAA) 889 return F_IPV6; 890 if (qtype == T_ANY) 891 return F_IPV4 | F_IPV6; 892 if (qtype == T_NS || qtype == T_SOA) 893 return F_QUERY | F_BIGNAME; 894 } 895 896 return F_QUERY; 897 } 898 899 900 size_t setup_reply(HEADER *header, size_t qlen, 901 struct all_addr *addrp, unsigned short flags, unsigned long ttl) 902 { 903 unsigned char *p = skip_questions(header, qlen); 904 905 header->qr = 1; /* response */ 906 header->aa = 0; /* authoritive */ 907 header->ra = 1; /* recursion if available */ 908 header->tc = 0; /* not truncated */ 909 header->nscount = htons(0); 910 header->arcount = htons(0); 911 header->ancount = htons(0); /* no answers unless changed below */ 912 if (flags == F_NEG) 913 header->rcode = SERVFAIL; /* couldn't get memory */ 914 else if (flags == F_NOERR) 915 header->rcode = NOERROR; /* empty domain */ 916 else if (flags == F_NXDOMAIN) 917 header->rcode = NXDOMAIN; 918 else if (p && flags == F_IPV4) 919 { /* we know the address */ 920 header->rcode = NOERROR; 921 header->ancount = htons(1); 922 header->aa = 1; 923 add_resource_record(header, NULL, NULL, sizeof(HEADER), &p, ttl, NULL, T_A, C_IN, "4", addrp); 924 } 925 #ifdef HAVE_IPV6 926 else if (p && flags == F_IPV6) 927 { 928 header->rcode = NOERROR; 929 header->ancount = htons(1); 930 header->aa = 1; 931 add_resource_record(header, NULL, NULL, sizeof(HEADER), &p, ttl, NULL, T_AAAA, C_IN, "6", addrp); 932 } 933 #endif 934 else /* nowhere to forward to */ 935 header->rcode = REFUSED; 936 937 return p - (unsigned char *)header; 938 } 939 940 /* check if name matches local names ie from /etc/hosts or DHCP or local mx names. */ 941 int check_for_local_domain(char *name, time_t now) 942 { 943 struct crec *crecp; 944 struct mx_srv_record *mx; 945 struct txt_record *txt; 946 struct interface_name *intr; 947 struct ptr_record *ptr; 948 949 if ((crecp = cache_find_by_name(NULL, name, now, F_IPV4 | F_IPV6)) && 950 (crecp->flags & (F_HOSTS | F_DHCP))) 951 return 1; 952 953 for (mx = daemon->mxnames; mx; mx = mx->next) 954 if (hostname_isequal(name, mx->name)) 955 return 1; 956 957 for (txt = daemon->txt; txt; txt = txt->next) 958 if (hostname_isequal(name, txt->name)) 959 return 1; 960 961 for (intr = daemon->int_names; intr; intr = intr->next) 962 if (hostname_isequal(name, intr->name)) 963 return 1; 964 965 for (ptr = daemon->ptr; ptr; ptr = ptr->next) 966 if (hostname_isequal(name, ptr->name)) 967 return 1; 968 969 return 0; 970 } 971 972 /* Is the packet a reply with the answer address equal to addr? 973 If so mung is into an NXDOMAIN reply and also put that information 974 in the cache. */ 975 int check_for_bogus_wildcard(HEADER *header, size_t qlen, char *name, 976 struct bogus_addr *baddr, time_t now) 977 { 978 unsigned char *p; 979 int i, qtype, qclass, rdlen; 980 unsigned long ttl; 981 struct bogus_addr *baddrp; 982 983 /* skip over questions */ 984 if (!(p = skip_questions(header, qlen))) 985 return 0; /* bad packet */ 986 987 for (i = ntohs(header->ancount); i != 0; i--) 988 { 989 if (!extract_name(header, qlen, &p, name, 1, 10)) 990 return 0; /* bad packet */ 991 992 GETSHORT(qtype, p); 993 GETSHORT(qclass, p); 994 GETLONG(ttl, p); 995 GETSHORT(rdlen, p); 996 997 if (qclass == C_IN && qtype == T_A) 998 { 999 if (!CHECK_LEN(header, p, qlen, INADDRSZ)) 1000 return 0; 1001 1002 for (baddrp = baddr; baddrp; baddrp = baddrp->next) 1003 if (memcmp(&baddrp->addr, p, INADDRSZ) == 0) 1004 { 1005 /* Found a bogus address. Insert that info here, since there no SOA record 1006 to get the ttl from in the normal processing */ 1007 cache_start_insert(); 1008 cache_insert(name, NULL, now, ttl, F_IPV4 | F_FORWARD | F_NEG | F_NXDOMAIN | F_CONFIG); 1009 cache_end_insert(); 1010 1011 return 1; 1012 } 1013 } 1014 1015 if (!ADD_RDLEN(header, p, qlen, rdlen)) 1016 return 0; 1017 } 1018 1019 return 0; 1020 } 1021 1022 static int add_resource_record(HEADER *header, char *limit, int *truncp, unsigned int nameoffset, unsigned char **pp, 1023 unsigned long ttl, unsigned int *offset, unsigned short type, unsigned short class, char *format, ...) 1024 { 1025 va_list ap; 1026 unsigned char *sav, *p = *pp; 1027 int j; 1028 unsigned short usval; 1029 long lval; 1030 char *sval; 1031 1032 if (truncp && *truncp) 1033 return 0; 1034 1035 PUTSHORT(nameoffset | 0xc000, p); 1036 PUTSHORT(type, p); 1037 PUTSHORT(class, p); 1038 PUTLONG(ttl, p); /* TTL */ 1039 1040 sav = p; /* Save pointer to RDLength field */ 1041 PUTSHORT(0, p); /* Placeholder RDLength */ 1042 1043 va_start(ap, format); /* make ap point to 1st unamed argument */ 1044 1045 for (; *format; format++) 1046 switch (*format) 1047 { 1048 #ifdef HAVE_IPV6 1049 case '6': 1050 sval = va_arg(ap, char *); 1051 memcpy(p, sval, IN6ADDRSZ); 1052 p += IN6ADDRSZ; 1053 break; 1054 #endif 1055 1056 case '4': 1057 sval = va_arg(ap, char *); 1058 memcpy(p, sval, INADDRSZ); 1059 p += INADDRSZ; 1060 break; 1061 1062 case 's': 1063 usval = va_arg(ap, int); 1064 PUTSHORT(usval, p); 1065 break; 1066 1067 case 'l': 1068 lval = va_arg(ap, long); 1069 PUTLONG(lval, p); 1070 break; 1071 1072 case 'd': 1073 /* get domain-name answer arg and store it in RDATA field */ 1074 if (offset) 1075 *offset = p - (unsigned char *)header; 1076 p = do_rfc1035_name(p, va_arg(ap, char *)); 1077 *p++ = 0; 1078 break; 1079 1080 case 't': 1081 usval = va_arg(ap, int); 1082 sval = va_arg(ap, char *); 1083 memcpy(p, sval, usval); 1084 p += usval; 1085 break; 1086 1087 case 'z': 1088 sval = va_arg(ap, char *); 1089 usval = sval ? strlen(sval) : 0; 1090 if (usval > 255) 1091 usval = 255; 1092 *p++ = (unsigned char)usval; 1093 memcpy(p, sval, usval); 1094 p += usval; 1095 break; 1096 } 1097 1098 va_end(ap); /* clean up variable argument pointer */ 1099 1100 j = p - sav - 2; 1101 PUTSHORT(j, sav); /* Now, store real RDLength */ 1102 1103 /* check for overflow of buffer */ 1104 if (limit && ((unsigned char *)limit - p) < 0) 1105 { 1106 if (truncp) 1107 *truncp = 1; 1108 return 0; 1109 } 1110 1111 *pp = p; 1112 return 1; 1113 } 1114 1115 static unsigned long crec_ttl(struct crec *crecp, time_t now) 1116 { 1117 /* Return 0 ttl for DHCP entries, which might change 1118 before the lease expires. */ 1119 1120 if (crecp->flags & (F_IMMORTAL | F_DHCP)) 1121 return daemon->local_ttl; 1122 1123 return crecp->ttd - now; 1124 } 1125 1126 1127 /* return zero if we can't answer from cache, or packet size if we can */ 1128 size_t answer_request(HEADER *header, char *limit, size_t qlen, 1129 struct in_addr local_addr, struct in_addr local_netmask, time_t now) 1130 { 1131 char *name = daemon->namebuff; 1132 unsigned char *p, *ansp, *pheader; 1133 int qtype, qclass; 1134 struct all_addr addr; 1135 unsigned int nameoffset; 1136 unsigned short flag; 1137 int q, ans, anscount = 0, addncount = 0; 1138 int dryrun = 0, sec_reqd = 0; 1139 int is_sign; 1140 struct crec *crecp; 1141 int nxdomain = 0, auth = 1, trunc = 0; 1142 struct mx_srv_record *rec; 1143 1144 /* If there is an RFC2671 pseudoheader then it will be overwritten by 1145 partial replies, so we have to do a dry run to see if we can answer 1146 the query. We check to see if the do bit is set, if so we always 1147 forward rather than answering from the cache, which doesn't include 1148 security information. */ 1149 1150 if (find_pseudoheader(header, qlen, NULL, &pheader, &is_sign)) 1151 { 1152 unsigned short udpsz, ext_rcode, flags; 1153 unsigned char *psave = pheader; 1154 1155 GETSHORT(udpsz, pheader); 1156 GETSHORT(ext_rcode, pheader); 1157 GETSHORT(flags, pheader); 1158 1159 sec_reqd = flags & 0x8000; /* do bit */ 1160 1161 /* If our client is advertising a larger UDP packet size 1162 than we allow, trim it so that we don't get an overlarge 1163 response from upstream */ 1164 1165 if (!is_sign && (udpsz > daemon->edns_pktsz)) 1166 PUTSHORT(daemon->edns_pktsz, psave); 1167 1168 dryrun = 1; 1169 } 1170 1171 if (ntohs(header->qdcount) == 0 || header->opcode != QUERY ) 1172 return 0; 1173 1174 for (rec = daemon->mxnames; rec; rec = rec->next) 1175 rec->offset = 0; 1176 1177 rerun: 1178 /* determine end of question section (we put answers there) */ 1179 if (!(ansp = skip_questions(header, qlen))) 1180 return 0; /* bad packet */ 1181 1182 /* now process each question, answers go in RRs after the question */ 1183 p = (unsigned char *)(header+1); 1184 1185 for (q = ntohs(header->qdcount); q != 0; q--) 1186 { 1187 /* save pointer to name for copying into answers */ 1188 nameoffset = p - (unsigned char *)header; 1189 1190 /* now extract name as .-concatenated string into name */ 1191 if (!extract_name(header, qlen, &p, name, 1, 4)) 1192 return 0; /* bad packet */ 1193 1194 GETSHORT(qtype, p); 1195 GETSHORT(qclass, p); 1196 1197 ans = 0; /* have we answered this question */ 1198 1199 if (qtype == T_TXT || qtype == T_ANY) 1200 { 1201 struct txt_record *t; 1202 for(t = daemon->txt; t ; t = t->next) 1203 { 1204 if (t->class == qclass && hostname_isequal(name, t->name)) 1205 { 1206 ans = 1; 1207 if (!dryrun) 1208 { 1209 log_query(F_CNAME | F_FORWARD | F_CONFIG | F_NXDOMAIN, name, NULL, "<TXT>"); 1210 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, 1211 daemon->local_ttl, NULL, 1212 T_TXT, t->class, "t", t->len, t->txt)) 1213 anscount++; 1214 1215 } 1216 } 1217 } 1218 } 1219 1220 if (qclass == C_IN) 1221 { 1222 if (qtype == T_PTR || qtype == T_ANY) 1223 { 1224 /* see if it's w.z.y.z.in-addr.arpa format */ 1225 int is_arpa = in_arpa_name_2_addr(name, &addr); 1226 struct ptr_record *ptr; 1227 struct interface_name* intr = NULL; 1228 1229 for (ptr = daemon->ptr; ptr; ptr = ptr->next) 1230 if (hostname_isequal(name, ptr->name)) 1231 break; 1232 1233 if (is_arpa == F_IPV4) 1234 for (intr = daemon->int_names; intr; intr = intr->next) 1235 { 1236 if (addr.addr.addr4.s_addr == get_ifaddr(intr->intr).s_addr) 1237 break; 1238 else 1239 while (intr->next && strcmp(intr->intr, intr->next->intr) == 0) 1240 intr = intr->next; 1241 } 1242 1243 if (intr) 1244 { 1245 ans = 1; 1246 if (!dryrun) 1247 { 1248 log_query(F_IPV4 | F_REVERSE | F_CONFIG, intr->name, &addr, NULL); 1249 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, 1250 daemon->local_ttl, NULL, 1251 T_PTR, C_IN, "d", intr->name)) 1252 anscount++; 1253 } 1254 } 1255 else if (ptr) 1256 { 1257 ans = 1; 1258 if (!dryrun) 1259 { 1260 log_query(F_CNAME | F_FORWARD | F_CONFIG | F_NXDOMAIN, name, NULL, "<PTR>"); 1261 for (ptr = daemon->ptr; ptr; ptr = ptr->next) 1262 if (hostname_isequal(name, ptr->name) && 1263 add_resource_record(header, limit, &trunc, nameoffset, &ansp, 1264 daemon->local_ttl, NULL, 1265 T_PTR, C_IN, "d", ptr->ptr)) 1266 anscount++; 1267 1268 } 1269 } 1270 else if ((crecp = cache_find_by_addr(NULL, &addr, now, is_arpa))) 1271 do 1272 { 1273 /* don't answer wildcard queries with data not from /etc/hosts or dhcp leases */ 1274 if (qtype == T_ANY && !(crecp->flags & (F_HOSTS | F_DHCP))) 1275 continue; 1276 1277 if (crecp->flags & F_NEG) 1278 { 1279 ans = 1; 1280 auth = 0; 1281 if (crecp->flags & F_NXDOMAIN) 1282 nxdomain = 1; 1283 if (!dryrun) 1284 log_query(crecp->flags & ~F_FORWARD, name, &addr, NULL); 1285 } 1286 else if ((crecp->flags & (F_HOSTS | F_DHCP)) || !sec_reqd) 1287 { 1288 ans = 1; 1289 if (!(crecp->flags & (F_HOSTS | F_DHCP))) 1290 auth = 0; 1291 if (!dryrun) 1292 { 1293 log_query(crecp->flags & ~F_FORWARD, cache_get_name(crecp), &addr, 1294 record_source(crecp->uid)); 1295 1296 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, 1297 crec_ttl(crecp, now), NULL, 1298 T_PTR, C_IN, "d", cache_get_name(crecp))) 1299 anscount++; 1300 } 1301 } 1302 } while ((crecp = cache_find_by_addr(crecp, &addr, now, is_arpa))); 1303 else if (is_arpa == F_IPV4 && 1304 (daemon->options & OPT_BOGUSPRIV) && 1305 private_net(addr.addr.addr4)) 1306 { 1307 /* if not in cache, enabled and private IPV4 address, return NXDOMAIN */ 1308 ans = 1; 1309 nxdomain = 1; 1310 if (!dryrun) 1311 log_query(F_CONFIG | F_REVERSE | F_IPV4 | F_NEG | F_NXDOMAIN, 1312 name, &addr, NULL); 1313 } 1314 } 1315 1316 for (flag = F_IPV4; flag; flag = (flag == F_IPV4) ? F_IPV6 : 0) 1317 { 1318 unsigned short type = T_A; 1319 1320 if (flag == F_IPV6) 1321 #ifdef HAVE_IPV6 1322 type = T_AAAA; 1323 #else 1324 break; 1325 #endif 1326 1327 if (qtype != type && qtype != T_ANY) 1328 continue; 1329 1330 /* Check for "A for A" queries */ 1331 if (qtype == T_A && (addr.addr.addr4.s_addr = inet_addr(name)) != (in_addr_t) -1) 1332 { 1333 ans = 1; 1334 if (!dryrun) 1335 { 1336 log_query(F_FORWARD | F_CONFIG | F_IPV4, name, &addr, NULL); 1337 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, 1338 daemon->local_ttl, NULL, type, C_IN, "4", &addr)) 1339 anscount++; 1340 } 1341 continue; 1342 } 1343 1344 /* interface name stuff */ 1345 if (qtype == T_A) 1346 { 1347 struct interface_name *intr; 1348 1349 for (intr = daemon->int_names; intr; intr = intr->next) 1350 if (hostname_isequal(name, intr->name)) 1351 break; 1352 1353 if (intr) 1354 { 1355 ans = 1; 1356 if (!dryrun) 1357 { 1358 if ((addr.addr.addr4 = get_ifaddr(intr->intr)).s_addr == (in_addr_t) -1) 1359 log_query(F_FORWARD | F_CONFIG | F_IPV4 | F_NEG, name, NULL, NULL); 1360 else 1361 { 1362 log_query(F_FORWARD | F_CONFIG | F_IPV4, name, &addr, NULL); 1363 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, 1364 daemon->local_ttl, NULL, type, C_IN, "4", &addr)) 1365 anscount++; 1366 } 1367 } 1368 continue; 1369 } 1370 } 1371 1372 cname_restart: 1373 if ((crecp = cache_find_by_name(NULL, name, now, flag | F_CNAME))) 1374 { 1375 int localise = 0; 1376 1377 /* See if a putative address is on the network from which we recieved 1378 the query, is so we'll filter other answers. */ 1379 if (local_addr.s_addr != 0 && (daemon->options & OPT_LOCALISE) && flag == F_IPV4) 1380 { 1381 struct crec *save = crecp; 1382 do { 1383 if ((crecp->flags & F_HOSTS) && 1384 is_same_net(*((struct in_addr *)&crecp->addr), local_addr, local_netmask)) 1385 { 1386 localise = 1; 1387 break; 1388 } 1389 } while ((crecp = cache_find_by_name(crecp, name, now, flag | F_CNAME))); 1390 crecp = save; 1391 } 1392 1393 do 1394 { 1395 /* don't answer wildcard queries with data not from /etc/hosts 1396 or DHCP leases */ 1397 if (qtype == T_ANY && !(crecp->flags & (F_HOSTS | F_DHCP))) 1398 break; 1399 1400 if (crecp->flags & F_CNAME) 1401 { 1402 if (!dryrun) 1403 { 1404 log_query(crecp->flags, name, NULL, record_source(crecp->uid)); 1405 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, 1406 crec_ttl(crecp, now), &nameoffset, 1407 T_CNAME, C_IN, "d", cache_get_name(crecp->addr.cname.cache))) 1408 anscount++; 1409 } 1410 1411 strcpy(name, cache_get_name(crecp->addr.cname.cache)); 1412 goto cname_restart; 1413 } 1414 1415 if (crecp->flags & F_NEG) 1416 { 1417 ans = 1; 1418 auth = 0; 1419 if (crecp->flags & F_NXDOMAIN) 1420 nxdomain = 1; 1421 if (!dryrun) 1422 log_query(crecp->flags, name, NULL, NULL); 1423 } 1424 else if ((crecp->flags & (F_HOSTS | F_DHCP)) || !sec_reqd) 1425 { 1426 /* If we are returning local answers depending on network, 1427 filter here. */ 1428 if (localise && 1429 (crecp->flags & F_HOSTS) && 1430 !is_same_net(*((struct in_addr *)&crecp->addr), local_addr, local_netmask)) 1431 continue; 1432 1433 if (!(crecp->flags & (F_HOSTS | F_DHCP))) 1434 auth = 0; 1435 1436 ans = 1; 1437 if (!dryrun) 1438 { 1439 log_query(crecp->flags & ~F_REVERSE, name, &crecp->addr.addr, 1440 record_source(crecp->uid)); 1441 1442 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, 1443 crec_ttl(crecp, now), NULL, type, C_IN, 1444 type == T_A ? "4" : "6", &crecp->addr)) 1445 anscount++; 1446 } 1447 } 1448 } while ((crecp = cache_find_by_name(crecp, name, now, flag | F_CNAME))); 1449 } 1450 } 1451 1452 if (qtype == T_MX || qtype == T_ANY) 1453 { 1454 int found = 0; 1455 for (rec = daemon->mxnames; rec; rec = rec->next) 1456 if (!rec->issrv && hostname_isequal(name, rec->name)) 1457 { 1458 ans = found = 1; 1459 if (!dryrun) 1460 { 1461 unsigned int offset; 1462 log_query(F_CNAME | F_FORWARD | F_CONFIG | F_NXDOMAIN, name, NULL, "<MX>"); 1463 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->local_ttl, 1464 &offset, T_MX, C_IN, "sd", rec->weight, rec->target)) 1465 { 1466 anscount++; 1467 if (rec->target) 1468 rec->offset = offset; 1469 } 1470 } 1471 } 1472 1473 if (!found && (daemon->options & (OPT_SELFMX | OPT_LOCALMX)) && 1474 cache_find_by_name(NULL, name, now, F_HOSTS | F_DHCP)) 1475 { 1476 ans = 1; 1477 if (!dryrun) 1478 { 1479 log_query(F_CNAME | F_FORWARD | F_CONFIG | F_NXDOMAIN, name, NULL, "<MX>"); 1480 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->local_ttl, NULL, 1481 T_MX, C_IN, "sd", 1, 1482 (daemon->options & OPT_SELFMX) ? name : daemon->mxtarget)) 1483 anscount++; 1484 } 1485 } 1486 } 1487 1488 if (qtype == T_SRV || qtype == T_ANY) 1489 { 1490 int found = 0; 1491 1492 for (rec = daemon->mxnames; rec; rec = rec->next) 1493 if (rec->issrv && hostname_isequal(name, rec->name)) 1494 { 1495 found = ans = 1; 1496 if (!dryrun) 1497 { 1498 unsigned int offset; 1499 log_query(F_CNAME | F_FORWARD | F_CONFIG | F_NXDOMAIN, name, NULL, "<SRV>"); 1500 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->local_ttl, 1501 &offset, T_SRV, C_IN, "sssd", 1502 rec->priority, rec->weight, rec->srvport, rec->target)) 1503 { 1504 anscount++; 1505 if (rec->target) 1506 rec->offset = offset; 1507 } 1508 } 1509 } 1510 1511 if (!found && (daemon->options & OPT_FILTER) && (qtype == T_SRV || (qtype == T_ANY && strchr(name, '_')))) 1512 { 1513 ans = 1; 1514 if (!dryrun) 1515 log_query(F_CONFIG | F_NEG, name, NULL, NULL); 1516 } 1517 } 1518 1519 if (qtype == T_NAPTR || qtype == T_ANY) 1520 { 1521 struct naptr *na; 1522 for (na = daemon->naptr; na; na = na->next) 1523 if (hostname_isequal(name, na->name)) 1524 { 1525 ans = 1; 1526 if (!dryrun) 1527 { 1528 log_query(F_CNAME | F_FORWARD | F_CONFIG | F_NXDOMAIN, name, NULL, "<NAPTR>"); 1529 if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->local_ttl, 1530 NULL, T_NAPTR, C_IN, "sszzzd", 1531 na->order, na->pref, na->flags, na->services, na->regexp, na->replace)) 1532 anscount++; 1533 } 1534 } 1535 } 1536 1537 if (qtype == T_MAILB) 1538 ans = 1, nxdomain = 1; 1539 1540 if (qtype == T_SOA && (daemon->options & OPT_FILTER)) 1541 { 1542 ans = 1; 1543 if (!dryrun) 1544 log_query(F_CONFIG | F_NEG, name, &addr, NULL); 1545 } 1546 } 1547 1548 if (!ans) 1549 return 0; /* failed to answer a question */ 1550 } 1551 1552 if (dryrun) 1553 { 1554 dryrun = 0; 1555 goto rerun; 1556 } 1557 1558 /* create an additional data section, for stuff in SRV and MX record replies. */ 1559 for (rec = daemon->mxnames; rec; rec = rec->next) 1560 if (rec->offset != 0) 1561 { 1562 /* squash dupes */ 1563 struct mx_srv_record *tmp; 1564 for (tmp = rec->next; tmp; tmp = tmp->next) 1565 if (tmp->offset != 0 && hostname_isequal(rec->target, tmp->target)) 1566 tmp->offset = 0; 1567 1568 crecp = NULL; 1569 while ((crecp = cache_find_by_name(crecp, rec->target, now, F_IPV4 | F_IPV6))) 1570 { 1571 #ifdef HAVE_IPV6 1572 int type = crecp->flags & F_IPV4 ? T_A : T_AAAA; 1573 #else 1574 int type = T_A; 1575 #endif 1576 if (crecp->flags & F_NEG) 1577 continue; 1578 1579 if (add_resource_record(header, limit, NULL, rec->offset, &ansp, 1580 crec_ttl(crecp, now), NULL, type, C_IN, 1581 crecp->flags & F_IPV4 ? "4" : "6", &crecp->addr)) 1582 addncount++; 1583 } 1584 } 1585 1586 /* done all questions, set up header and return length of result */ 1587 header->qr = 1; /* response */ 1588 header->aa = auth; /* authoritive - only hosts and DHCP derived names. */ 1589 header->ra = 1; /* recursion if available */ 1590 header->tc = trunc; /* truncation */ 1591 if (anscount == 0 && nxdomain) 1592 header->rcode = NXDOMAIN; 1593 else 1594 header->rcode = NOERROR; /* no error */ 1595 header->ancount = htons(anscount); 1596 header->nscount = htons(0); 1597 header->arcount = htons(addncount); 1598 return ansp - (unsigned char *)header; 1599 } 1600 1601 1602 1603 1604 1605