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
19static 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
30static 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
176static 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
283static 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
338static 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
353static 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. */
376unsigned 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
418size_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
442unsigned 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? */
518static 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
530static 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
583static 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. */
641int 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
866unsigned 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
902size_t setup_reply(HEADER *header, size_t qlen,
903		struct all_addr *addrp, unsigned short flags, unsigned long ttl)
904{
905  unsigned char *p = skip_questions(header, qlen);
906
907  header->qr = 1; /* response */
908  header->aa = 0; /* authoritive */
909  header->ra = 1; /* recursion if available */
910  header->tc = 0; /* not truncated */
911  header->nscount = htons(0);
912  header->arcount = htons(0);
913  header->ancount = htons(0); /* no answers unless changed below */
914  if (flags == F_NEG)
915    header->rcode = SERVFAIL; /* couldn't get memory */
916  else if (flags == F_NOERR)
917    header->rcode = NOERROR; /* empty domain */
918  else if (flags == F_NXDOMAIN)
919    header->rcode = NXDOMAIN;
920  else if (p && flags == F_IPV4)
921    { /* we know the address */
922      header->rcode = NOERROR;
923      header->ancount = htons(1);
924      header->aa = 1;
925      add_resource_record(header, NULL, NULL, sizeof(HEADER), &p, ttl, NULL, T_A, C_IN, "4", addrp);
926    }
927#ifdef HAVE_IPV6
928  else if (p && flags == F_IPV6)
929    {
930      header->rcode = NOERROR;
931      header->ancount = htons(1);
932      header->aa = 1;
933      add_resource_record(header, NULL, NULL, sizeof(HEADER), &p, ttl, NULL, T_AAAA, C_IN, "6", addrp);
934    }
935#endif
936  else /* nowhere to forward to */
937    header->rcode = REFUSED;
938
939  return p - (unsigned char *)header;
940}
941
942/* check if name matches local names ie from /etc/hosts or DHCP or local mx names. */
943int check_for_local_domain(char *name, time_t now)
944{
945  struct crec *crecp;
946  struct mx_srv_record *mx;
947  struct txt_record *txt;
948  struct interface_name *intr;
949  struct ptr_record *ptr;
950
951  if ((crecp = cache_find_by_name(NULL, name, now, F_IPV4 | F_IPV6)) &&
952      (crecp->flags & (F_HOSTS | F_DHCP)))
953    return 1;
954
955  for (mx = daemon->mxnames; mx; mx = mx->next)
956    if (hostname_isequal(name, mx->name))
957      return 1;
958
959  for (txt = daemon->txt; txt; txt = txt->next)
960    if (hostname_isequal(name, txt->name))
961      return 1;
962
963  for (intr = daemon->int_names; intr; intr = intr->next)
964    if (hostname_isequal(name, intr->name))
965      return 1;
966
967  for (ptr = daemon->ptr; ptr; ptr = ptr->next)
968    if (hostname_isequal(name, ptr->name))
969      return 1;
970
971  return 0;
972}
973
974/* Is the packet a reply with the answer address equal to addr?
975   If so mung is into an NXDOMAIN reply and also put that information
976   in the cache. */
977int check_for_bogus_wildcard(HEADER *header, size_t qlen, char *name,
978			     struct bogus_addr *baddr, time_t now)
979{
980  unsigned char *p;
981  int i, qtype, qclass, rdlen;
982  unsigned long ttl;
983  struct bogus_addr *baddrp;
984
985  /* skip over questions */
986  if (!(p = skip_questions(header, qlen)))
987    return 0; /* bad packet */
988
989  for (i = ntohs(header->ancount); i != 0; i--)
990    {
991      if (!extract_name(header, qlen, &p, name, 1, 10))
992	return 0; /* bad packet */
993
994      GETSHORT(qtype, p);
995      GETSHORT(qclass, p);
996      GETLONG(ttl, p);
997      GETSHORT(rdlen, p);
998
999      if (qclass == C_IN && qtype == T_A)
1000	{
1001	  if (!CHECK_LEN(header, p, qlen, INADDRSZ))
1002	    return 0;
1003
1004	  for (baddrp = baddr; baddrp; baddrp = baddrp->next)
1005	    if (memcmp(&baddrp->addr, p, INADDRSZ) == 0)
1006	      {
1007		/* Found a bogus address. Insert that info here, since there no SOA record
1008		   to get the ttl from in the normal processing */
1009		cache_start_insert();
1010		cache_insert(name, NULL, now, ttl, F_IPV4 | F_FORWARD | F_NEG | F_NXDOMAIN | F_CONFIG);
1011		cache_end_insert();
1012
1013		return 1;
1014	      }
1015	}
1016
1017      if (!ADD_RDLEN(header, p, qlen, rdlen))
1018	return 0;
1019    }
1020
1021  return 0;
1022}
1023
1024static int add_resource_record(HEADER *header, char *limit, int *truncp, unsigned int nameoffset, unsigned char **pp,
1025			       unsigned long ttl, unsigned int *offset, unsigned short type, unsigned short class, char *format, ...)
1026{
1027  va_list ap;
1028  unsigned char *sav, *p = *pp;
1029  int j;
1030  unsigned short usval;
1031  long lval;
1032  char *sval;
1033
1034  if (truncp && *truncp)
1035    return 0;
1036
1037  PUTSHORT(nameoffset | 0xc000, p);
1038  PUTSHORT(type, p);
1039  PUTSHORT(class, p);
1040  PUTLONG(ttl, p);      /* TTL */
1041
1042  sav = p;              /* Save pointer to RDLength field */
1043  PUTSHORT(0, p);       /* Placeholder RDLength */
1044
1045  va_start(ap, format);   /* make ap point to 1st unamed argument */
1046
1047  for (; *format; format++)
1048    switch (*format)
1049      {
1050#ifdef HAVE_IPV6
1051      case '6':
1052	sval = va_arg(ap, char *);
1053	memcpy(p, sval, IN6ADDRSZ);
1054	p += IN6ADDRSZ;
1055	break;
1056#endif
1057
1058      case '4':
1059	sval = va_arg(ap, char *);
1060	memcpy(p, sval, INADDRSZ);
1061	p += INADDRSZ;
1062	break;
1063
1064      case 's':
1065	usval = va_arg(ap, int);
1066	PUTSHORT(usval, p);
1067	break;
1068
1069      case 'l':
1070	lval = va_arg(ap, long);
1071	PUTLONG(lval, p);
1072	break;
1073
1074      case 'd':
1075	/* get domain-name answer arg and store it in RDATA field */
1076	if (offset)
1077	  *offset = p - (unsigned char *)header;
1078	p = do_rfc1035_name(p, va_arg(ap, char *));
1079	*p++ = 0;
1080	break;
1081
1082      case 't':
1083	usval = va_arg(ap, int);
1084	sval = va_arg(ap, char *);
1085	memcpy(p, sval, usval);
1086	p += usval;
1087	break;
1088
1089      case 'z':
1090	sval = va_arg(ap, char *);
1091	usval = sval ? strlen(sval) : 0;
1092	if (usval > 255)
1093	  usval = 255;
1094	*p++ = (unsigned char)usval;
1095	memcpy(p, sval, usval);
1096	p += usval;
1097	break;
1098      }
1099
1100  va_end(ap);	/* clean up variable argument pointer */
1101
1102  j = p - sav - 2;
1103  PUTSHORT(j, sav);     /* Now, store real RDLength */
1104
1105  /* check for overflow of buffer */
1106  if (limit && ((unsigned char *)limit - p) < 0)
1107    {
1108      if (truncp)
1109	*truncp = 1;
1110      return 0;
1111    }
1112
1113  *pp = p;
1114  return 1;
1115}
1116
1117static unsigned long crec_ttl(struct crec *crecp, time_t now)
1118{
1119  /* Return 0 ttl for DHCP entries, which might change
1120     before the lease expires. */
1121
1122  if  (crecp->flags & (F_IMMORTAL | F_DHCP))
1123    return daemon->local_ttl;
1124
1125  return crecp->ttd - now;
1126}
1127
1128
1129/* return zero if we can't answer from cache, or packet size if we can */
1130size_t answer_request(HEADER *header, char *limit, size_t qlen,
1131		      struct in_addr local_addr, struct in_addr local_netmask, time_t now)
1132{
1133  char *name = daemon->namebuff;
1134  unsigned char *p, *ansp, *pheader;
1135  int qtype, qclass;
1136  struct all_addr addr;
1137  unsigned int nameoffset;
1138  unsigned short flag;
1139  int q, ans, anscount = 0, addncount = 0;
1140  int dryrun = 0, sec_reqd = 0;
1141  int is_sign;
1142  struct crec *crecp;
1143  int nxdomain = 0, auth = 1, trunc = 0;
1144  struct mx_srv_record *rec;
1145
1146  /* If there is an RFC2671 pseudoheader then it will be overwritten by
1147     partial replies, so we have to do a dry run to see if we can answer
1148     the query. We check to see if the do bit is set, if so we always
1149     forward rather than answering from the cache, which doesn't include
1150     security information. */
1151
1152  if (find_pseudoheader(header, qlen, NULL, &pheader, &is_sign))
1153    {
1154      unsigned short udpsz, ext_rcode, flags;
1155      unsigned char *psave = pheader;
1156
1157      GETSHORT(udpsz, pheader);
1158      GETSHORT(ext_rcode, pheader);
1159      GETSHORT(flags, pheader);
1160
1161      sec_reqd = flags & 0x8000; /* do bit */
1162
1163      /* If our client is advertising a larger UDP packet size
1164	 than we allow, trim it so that we don't get an overlarge
1165	 response from upstream */
1166
1167      if (!is_sign && (udpsz > daemon->edns_pktsz))
1168	PUTSHORT(daemon->edns_pktsz, psave);
1169
1170      dryrun = 1;
1171    }
1172
1173  if (ntohs(header->qdcount) == 0 || header->opcode != QUERY )
1174    return 0;
1175
1176  for (rec = daemon->mxnames; rec; rec = rec->next)
1177    rec->offset = 0;
1178
1179 rerun:
1180  /* determine end of question section (we put answers there) */
1181  if (!(ansp = skip_questions(header, qlen)))
1182    return 0; /* bad packet */
1183
1184  /* now process each question, answers go in RRs after the question */
1185  p = (unsigned char *)(header+1);
1186
1187  for (q = ntohs(header->qdcount); q != 0; q--)
1188    {
1189      /* save pointer to name for copying into answers */
1190      nameoffset = p - (unsigned char *)header;
1191
1192      /* now extract name as .-concatenated string into name */
1193      if (!extract_name(header, qlen, &p, name, 1, 4))
1194	return 0; /* bad packet */
1195
1196      GETSHORT(qtype, p);
1197      GETSHORT(qclass, p);
1198
1199      ans = 0; /* have we answered this question */
1200
1201      if (qtype == T_TXT || qtype == T_ANY)
1202	{
1203	  struct txt_record *t;
1204	  for(t = daemon->txt; t ; t = t->next)
1205	    {
1206	      if (t->class == qclass && hostname_isequal(name, t->name))
1207		{
1208		  ans = 1;
1209		  if (!dryrun)
1210		    {
1211		      log_query(F_CNAME | F_FORWARD | F_CONFIG | F_NXDOMAIN, name, NULL, "<TXT>");
1212		      if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
1213					      daemon->local_ttl, NULL,
1214					      T_TXT, t->class, "t", t->len, t->txt))
1215			anscount++;
1216
1217		    }
1218		}
1219	    }
1220	}
1221
1222      if (qclass == C_IN)
1223	{
1224	  if (qtype == T_PTR || qtype == T_ANY)
1225	    {
1226	      /* see if it's w.z.y.z.in-addr.arpa format */
1227	      int is_arpa = in_arpa_name_2_addr(name, &addr);
1228	      struct ptr_record *ptr;
1229	      struct interface_name* intr = NULL;
1230
1231	      for (ptr = daemon->ptr; ptr; ptr = ptr->next)
1232		if (hostname_isequal(name, ptr->name))
1233		  break;
1234
1235	      if (is_arpa == F_IPV4)
1236		for (intr = daemon->int_names; intr; intr = intr->next)
1237		  {
1238		    if (addr.addr.addr4.s_addr == get_ifaddr(intr->intr).s_addr)
1239		      break;
1240		    else
1241		      while (intr->next && strcmp(intr->intr, intr->next->intr) == 0)
1242			intr = intr->next;
1243		  }
1244
1245	      if (intr)
1246		{
1247		  ans = 1;
1248		  if (!dryrun)
1249		    {
1250		      log_query(F_IPV4 | F_REVERSE | F_CONFIG, intr->name, &addr, NULL);
1251		      if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
1252					      daemon->local_ttl, NULL,
1253					      T_PTR, C_IN, "d", intr->name))
1254			anscount++;
1255		    }
1256		}
1257	      else if (ptr)
1258		{
1259		  ans = 1;
1260		  if (!dryrun)
1261		    {
1262		      log_query(F_CNAME | F_FORWARD | F_CONFIG | F_NXDOMAIN, name, NULL, "<PTR>");
1263		      for (ptr = daemon->ptr; ptr; ptr = ptr->next)
1264			if (hostname_isequal(name, ptr->name) &&
1265			    add_resource_record(header, limit, &trunc, nameoffset, &ansp,
1266						daemon->local_ttl, NULL,
1267						T_PTR, C_IN, "d", ptr->ptr))
1268			  anscount++;
1269
1270		    }
1271		}
1272	      else if ((crecp = cache_find_by_addr(NULL, &addr, now, is_arpa)))
1273		do
1274		  {
1275		    /* don't answer wildcard queries with data not from /etc/hosts or dhcp leases */
1276		    if (qtype == T_ANY && !(crecp->flags & (F_HOSTS | F_DHCP)))
1277		      continue;
1278
1279		    if (crecp->flags & F_NEG)
1280		      {
1281			ans = 1;
1282			auth = 0;
1283			if (crecp->flags & F_NXDOMAIN)
1284			  nxdomain = 1;
1285			if (!dryrun)
1286			  log_query(crecp->flags & ~F_FORWARD, name, &addr, NULL);
1287		      }
1288		    else if ((crecp->flags & (F_HOSTS | F_DHCP)) || !sec_reqd)
1289		      {
1290			ans = 1;
1291			if (!(crecp->flags & (F_HOSTS | F_DHCP)))
1292			  auth = 0;
1293			if (!dryrun)
1294			  {
1295			    log_query(crecp->flags & ~F_FORWARD, cache_get_name(crecp), &addr,
1296				      record_source(crecp->uid));
1297
1298			    if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
1299						    crec_ttl(crecp, now), NULL,
1300						    T_PTR, C_IN, "d", cache_get_name(crecp)))
1301			      anscount++;
1302			  }
1303		      }
1304		  } while ((crecp = cache_find_by_addr(crecp, &addr, now, is_arpa)));
1305	      else if (is_arpa == F_IPV4 &&
1306		       (daemon->options & OPT_BOGUSPRIV) &&
1307		       private_net(addr.addr.addr4))
1308		{
1309		  /* if not in cache, enabled and private IPV4 address, return NXDOMAIN */
1310		  ans = 1;
1311		  nxdomain = 1;
1312		  if (!dryrun)
1313		    log_query(F_CONFIG | F_REVERSE | F_IPV4 | F_NEG | F_NXDOMAIN,
1314			      name, &addr, NULL);
1315		}
1316	    }
1317
1318	  for (flag = F_IPV4; flag; flag = (flag == F_IPV4) ? F_IPV6 : 0)
1319	    {
1320	      unsigned short type = T_A;
1321
1322	      if (flag == F_IPV6)
1323#ifdef HAVE_IPV6
1324		type = T_AAAA;
1325#else
1326	        break;
1327#endif
1328
1329	      if (qtype != type && qtype != T_ANY)
1330		continue;
1331
1332	      /* Check for "A for A"  queries */
1333	      if (qtype == T_A && (addr.addr.addr4.s_addr = inet_addr(name)) != (in_addr_t) -1)
1334		{
1335		  ans = 1;
1336		  if (!dryrun)
1337		    {
1338		      log_query(F_FORWARD | F_CONFIG | F_IPV4, name, &addr, NULL);
1339		      if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
1340					      daemon->local_ttl, NULL, type, C_IN, "4", &addr))
1341			anscount++;
1342		    }
1343		  continue;
1344		}
1345
1346	      /* interface name stuff */
1347	      if (qtype == T_A)
1348		{
1349		  struct interface_name *intr;
1350
1351		  for (intr = daemon->int_names; intr; intr = intr->next)
1352		    if (hostname_isequal(name, intr->name))
1353		      break;
1354
1355		  if (intr)
1356		    {
1357		      ans = 1;
1358		      if (!dryrun)
1359			{
1360			  if ((addr.addr.addr4 = get_ifaddr(intr->intr)).s_addr == (in_addr_t) -1)
1361			    log_query(F_FORWARD | F_CONFIG | F_IPV4 | F_NEG, name, NULL, NULL);
1362			  else
1363			    {
1364			      log_query(F_FORWARD | F_CONFIG | F_IPV4, name, &addr, NULL);
1365			      if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
1366						      daemon->local_ttl, NULL, type, C_IN, "4", &addr))
1367				anscount++;
1368			    }
1369			}
1370		      continue;
1371		    }
1372		}
1373
1374	    cname_restart:
1375	      if ((crecp = cache_find_by_name(NULL, name, now, flag | F_CNAME)))
1376		{
1377		  int localise = 0;
1378
1379		  /* See if a putative address is on the network from which we recieved
1380		     the query, is so we'll filter other answers. */
1381		  if (local_addr.s_addr != 0 && (daemon->options & OPT_LOCALISE) && flag == F_IPV4)
1382		    {
1383		      struct crec *save = crecp;
1384		      do {
1385			if ((crecp->flags & F_HOSTS) &&
1386			    is_same_net(*((struct in_addr *)&crecp->addr), local_addr, local_netmask))
1387			  {
1388			    localise = 1;
1389			    break;
1390			  }
1391			} while ((crecp = cache_find_by_name(crecp, name, now, flag | F_CNAME)));
1392		      crecp = save;
1393		    }
1394
1395		  do
1396		    {
1397		      /* don't answer wildcard queries with data not from /etc/hosts
1398			 or DHCP leases */
1399		      if (qtype == T_ANY && !(crecp->flags & (F_HOSTS | F_DHCP)))
1400			break;
1401
1402		      if (crecp->flags & F_CNAME)
1403			{
1404			  if (!dryrun)
1405			    {
1406			      log_query(crecp->flags, name, NULL, record_source(crecp->uid));
1407			      if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
1408						      crec_ttl(crecp, now), &nameoffset,
1409						      T_CNAME, C_IN, "d", cache_get_name(crecp->addr.cname.cache)))
1410				anscount++;
1411			    }
1412
1413			  strcpy(name, cache_get_name(crecp->addr.cname.cache));
1414			  goto cname_restart;
1415			}
1416
1417		      if (crecp->flags & F_NEG)
1418			{
1419			  ans = 1;
1420			  auth = 0;
1421			  if (crecp->flags & F_NXDOMAIN)
1422			    nxdomain = 1;
1423			  if (!dryrun)
1424			    log_query(crecp->flags, name, NULL, NULL);
1425			}
1426		      else if ((crecp->flags & (F_HOSTS | F_DHCP)) || !sec_reqd)
1427			{
1428			  /* If we are returning local answers depending on network,
1429			     filter here. */
1430			  if (localise &&
1431			      (crecp->flags & F_HOSTS) &&
1432			      !is_same_net(*((struct in_addr *)&crecp->addr), local_addr, local_netmask))
1433			    continue;
1434
1435			  if (!(crecp->flags & (F_HOSTS | F_DHCP)))
1436			    auth = 0;
1437
1438			  ans = 1;
1439			  if (!dryrun)
1440			    {
1441			      log_query(crecp->flags & ~F_REVERSE, name, &crecp->addr.addr,
1442					record_source(crecp->uid));
1443
1444			      if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
1445						      crec_ttl(crecp, now), NULL, type, C_IN,
1446						      type == T_A ? "4" : "6", &crecp->addr))
1447				anscount++;
1448			    }
1449			}
1450		    } while ((crecp = cache_find_by_name(crecp, name, now, flag | F_CNAME)));
1451		}
1452	    }
1453
1454	  if (qtype == T_MX || qtype == T_ANY)
1455	    {
1456	      int found = 0;
1457	      for (rec = daemon->mxnames; rec; rec = rec->next)
1458		if (!rec->issrv && hostname_isequal(name, rec->name))
1459		  {
1460		  ans = found = 1;
1461		  if (!dryrun)
1462		    {
1463		      unsigned int offset;
1464		      log_query(F_CNAME | F_FORWARD | F_CONFIG | F_NXDOMAIN, name, NULL, "<MX>");
1465		      if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->local_ttl,
1466					      &offset, T_MX, C_IN, "sd", rec->weight, rec->target))
1467			{
1468			  anscount++;
1469			  if (rec->target)
1470			    rec->offset = offset;
1471			}
1472		    }
1473		  }
1474
1475	      if (!found && (daemon->options & (OPT_SELFMX | OPT_LOCALMX)) &&
1476		  cache_find_by_name(NULL, name, now, F_HOSTS | F_DHCP))
1477		{
1478		  ans = 1;
1479		  if (!dryrun)
1480		    {
1481		      log_query(F_CNAME | F_FORWARD | F_CONFIG | F_NXDOMAIN, name, NULL, "<MX>");
1482		      if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->local_ttl, NULL,
1483					      T_MX, C_IN, "sd", 1,
1484					      (daemon->options & OPT_SELFMX) ? name : daemon->mxtarget))
1485			anscount++;
1486		    }
1487		}
1488	    }
1489
1490	  if (qtype == T_SRV || qtype == T_ANY)
1491	    {
1492	      int found = 0;
1493
1494	      for (rec = daemon->mxnames; rec; rec = rec->next)
1495		if (rec->issrv && hostname_isequal(name, rec->name))
1496		  {
1497		    found = ans = 1;
1498		    if (!dryrun)
1499		      {
1500			unsigned int offset;
1501			log_query(F_CNAME | F_FORWARD | F_CONFIG | F_NXDOMAIN, name, NULL, "<SRV>");
1502			if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->local_ttl,
1503						&offset, T_SRV, C_IN, "sssd",
1504						rec->priority, rec->weight, rec->srvport, rec->target))
1505			  {
1506			    anscount++;
1507			    if (rec->target)
1508			      rec->offset = offset;
1509			  }
1510		      }
1511		  }
1512
1513	      if (!found && (daemon->options & OPT_FILTER) &&  (qtype == T_SRV || (qtype == T_ANY && strchr(name, '_'))))
1514		{
1515		  ans = 1;
1516		  if (!dryrun)
1517		    log_query(F_CONFIG | F_NEG, name, NULL, NULL);
1518		}
1519	    }
1520
1521	  if (qtype == T_NAPTR || qtype == T_ANY)
1522	    {
1523	      struct naptr *na;
1524	      for (na = daemon->naptr; na; na = na->next)
1525		if (hostname_isequal(name, na->name))
1526		  {
1527		    ans = 1;
1528		    if (!dryrun)
1529		      {
1530			log_query(F_CNAME | F_FORWARD | F_CONFIG | F_NXDOMAIN, name, NULL, "<NAPTR>");
1531			if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->local_ttl,
1532						NULL, T_NAPTR, C_IN, "sszzzd",
1533						na->order, na->pref, na->flags, na->services, na->regexp, na->replace))
1534			  anscount++;
1535		      }
1536		  }
1537	    }
1538
1539	  if (qtype == T_MAILB)
1540	    ans = 1, nxdomain = 1;
1541
1542	  if (qtype == T_SOA && (daemon->options & OPT_FILTER))
1543	    {
1544	      ans = 1;
1545	      if (!dryrun)
1546		log_query(F_CONFIG | F_NEG, name, &addr, NULL);
1547	    }
1548	}
1549
1550      if (!ans)
1551	return 0; /* failed to answer a question */
1552    }
1553
1554  if (dryrun)
1555    {
1556      dryrun = 0;
1557      goto rerun;
1558    }
1559
1560  /* create an additional data section, for stuff in SRV and MX record replies. */
1561  for (rec = daemon->mxnames; rec; rec = rec->next)
1562    if (rec->offset != 0)
1563      {
1564	/* squash dupes */
1565	struct mx_srv_record *tmp;
1566	for (tmp = rec->next; tmp; tmp = tmp->next)
1567	  if (tmp->offset != 0 && hostname_isequal(rec->target, tmp->target))
1568	    tmp->offset = 0;
1569
1570	crecp = NULL;
1571	while ((crecp = cache_find_by_name(crecp, rec->target, now, F_IPV4 | F_IPV6)))
1572	  {
1573#ifdef HAVE_IPV6
1574	    int type =  crecp->flags & F_IPV4 ? T_A : T_AAAA;
1575#else
1576	    int type = T_A;
1577#endif
1578	    if (crecp->flags & F_NEG)
1579	      continue;
1580
1581	    if (add_resource_record(header, limit, NULL, rec->offset, &ansp,
1582				    crec_ttl(crecp, now), NULL, type, C_IN,
1583				    crecp->flags & F_IPV4 ? "4" : "6", &crecp->addr))
1584	      addncount++;
1585	  }
1586      }
1587
1588  /* done all questions, set up header and return length of result */
1589  header->qr = 1; /* response */
1590  header->aa = auth; /* authoritive - only hosts and DHCP derived names. */
1591  header->ra = 1; /* recursion if available */
1592  header->tc = trunc; /* truncation */
1593  if (anscount == 0 && nxdomain)
1594    header->rcode = NXDOMAIN;
1595  else
1596    header->rcode = NOERROR; /* no error */
1597  header->ancount = htons(anscount);
1598  header->nscount = htons(0);
1599  header->arcount = htons(addncount);
1600  return ansp - (unsigned char *)header;
1601}
1602
1603
1604
1605
1606
1607