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