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