Blame


1 c45084ea 2005-11-29 pbug /*
2 48603f7d 2014-04-13 pjp * Copyright (c) 2005-2014 Peter J. Philipp
3 c45084ea 2005-11-29 pbug * All rights reserved.
4 c45084ea 2005-11-29 pbug *
5 c45084ea 2005-11-29 pbug * Redistribution and use in source and binary forms, with or without
6 c45084ea 2005-11-29 pbug * modification, are permitted provided that the following conditions
7 c45084ea 2005-11-29 pbug * are met:
8 c45084ea 2005-11-29 pbug * 1. Redistributions of source code must retain the above copyright
9 c45084ea 2005-11-29 pbug * notice, this list of conditions and the following disclaimer.
10 c45084ea 2005-11-29 pbug * 2. Redistributions in binary form must reproduce the above copyright
11 c45084ea 2005-11-29 pbug * notice, this list of conditions and the following disclaimer in the
12 c45084ea 2005-11-29 pbug * documentation and/or other materials provided with the distribution.
13 c45084ea 2005-11-29 pbug * 3. The name of the author may not be used to endorse or promote products
14 c45084ea 2005-11-29 pbug * derived from this software without specific prior written permission
15 c45084ea 2005-11-29 pbug *
16 c45084ea 2005-11-29 pbug * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 c45084ea 2005-11-29 pbug * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 c45084ea 2005-11-29 pbug * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 c45084ea 2005-11-29 pbug * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 c45084ea 2005-11-29 pbug * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 c45084ea 2005-11-29 pbug * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 c45084ea 2005-11-29 pbug * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 c45084ea 2005-11-29 pbug * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 c45084ea 2005-11-29 pbug * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 c45084ea 2005-11-29 pbug * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 c45084ea 2005-11-29 pbug *
27 c45084ea 2005-11-29 pbug */
28 c45084ea 2005-11-29 pbug #include "include.h"
29 c45084ea 2005-11-29 pbug #include "dns.h"
30 c45084ea 2005-11-29 pbug #include "db.h"
31 c45084ea 2005-11-29 pbug
32 0e7d94ac 2014-05-18 pjp /* prototypes */
33 c45084ea 2005-11-29 pbug
34 0e7d94ac 2014-05-18 pjp extern int additional_a(char *, int, struct domain *, char *, int, int, int *);
35 0e7d94ac 2014-05-18 pjp extern int additional_aaaa(char *, int, struct domain *, char *, int, int, int *);
36 0e7d94ac 2014-05-18 pjp extern int additional_mx(char *, int, struct domain *, char *, int, int, int *);
37 0e7d94ac 2014-05-18 pjp extern int additional_ptr(char *, int, struct domain *, char *, int, int, int *);
38 0e7d94ac 2014-05-18 pjp extern int additional_opt(struct question *, char *, int, int);
39 0e7d94ac 2014-05-18 pjp extern struct question *build_fake_question(char *, int, u_int16_t);
40 0e7d94ac 2014-05-18 pjp extern int compress_label(u_char *, int, int);
41 0e7d94ac 2014-05-18 pjp extern void dolog(int, char *, ...);
42 0e7d94ac 2014-05-18 pjp extern int free_question(struct question *);
43 0e7d94ac 2014-05-18 pjp extern int lookup_zone(DB *, struct question *, struct domain *, int *, char *, int);
44 0e7d94ac 2014-05-18 pjp extern void slave_shutdown(void);
45 a042435d 2010-03-19 pbug
46 c45084ea 2005-11-29 pbug
47 0e7d94ac 2014-05-18 pjp struct domain *Lookup_zone(DB *, char *, u_int16_t, u_int16_t, int);
48 0e7d94ac 2014-05-18 pjp void collects_init(void);
49 0e7d94ac 2014-05-18 pjp u_int16_t create_anyreply(struct sreply *, char *, int, int, int);
50 0e7d94ac 2014-05-18 pjp u_short in_cksum(const u_short *, register int, int);
51 a2b189d4 2014-10-08 pjp int reply_a(struct sreply *, DB *);
52 a2b189d4 2014-10-08 pjp int reply_aaaa(struct sreply *, DB *);
53 a2b189d4 2014-10-08 pjp int reply_mx(struct sreply *, DB *);
54 a2b189d4 2014-10-08 pjp int reply_ns(struct sreply *, DB *);
55 a2b189d4 2014-10-08 pjp int reply_notimpl(struct sreply *);
56 a2b189d4 2014-10-08 pjp int reply_nxdomain(struct sreply *);
57 a2b189d4 2014-10-08 pjp int reply_noerror(struct sreply *);
58 a2b189d4 2014-10-08 pjp int reply_soa(struct sreply *);
59 a2b189d4 2014-10-08 pjp int reply_ptr(struct sreply *);
60 a2b189d4 2014-10-08 pjp int reply_txt(struct sreply *);
61 a2b189d4 2014-10-08 pjp int reply_spf(struct sreply *);
62 a2b189d4 2014-10-08 pjp int reply_srv(struct sreply *, DB *);
63 a2b189d4 2014-10-08 pjp int reply_naptr(struct sreply *, DB *);
64 a2b189d4 2014-10-08 pjp int reply_sshfp(struct sreply *);
65 a2b189d4 2014-10-08 pjp int reply_cname(struct sreply *);
66 a2b189d4 2014-10-08 pjp int reply_any(struct sreply *);
67 a2b189d4 2014-10-08 pjp int reply_refused(struct sreply *);
68 a2b189d4 2014-10-08 pjp int reply_fmterror(struct sreply *);
69 a2b189d4 2014-10-08 pjp int reply_raw2(int, char *, int, struct recurses *);
70 a2b189d4 2014-10-08 pjp int reply_raw6(int, char *, int, struct recurses *);
71 0e7d94ac 2014-05-18 pjp void update_db(DB *, struct domain *);
72 0e7d94ac 2014-05-18 pjp
73 0e7d94ac 2014-05-18 pjp #ifdef __linux__
74 0e7d94ac 2014-05-18 pjp static int udp_cksum(const struct iphdr *, const struct udphdr *, int);
75 ce12744a 2010-09-25 pbug #else
76 0e7d94ac 2014-05-18 pjp static int udp_cksum(const struct ip *, const struct udphdr *, int);
77 ce12744a 2010-09-25 pbug #endif
78 ce12744a 2010-09-25 pbug
79 a042435d 2010-03-19 pbug SLIST_HEAD(listhead, collects) collectshead;
80 a042435d 2010-03-19 pbug
81 a042435d 2010-03-19 pbug struct collects {
82 a042435d 2010-03-19 pbug char *name;
83 b6dc64dc 2010-04-15 pbug u_int16_t namelen;
84 a042435d 2010-03-19 pbug u_int16_t type;
85 a042435d 2010-03-19 pbug struct domain *sd;
86 c0963faf 2014-05-01 pjp SLIST_ENTRY(collects) collect_entry;
87 a042435d 2010-03-19 pbug } *cn1, *cn2, *cnp;
88 33a0a60d 2009-11-03 pbug
89 dd869383 2013-02-16 pjp extern int debug, verbose;
90 a042435d 2010-03-19 pbug
91 a042435d 2010-03-19 pbug
92 a2b189d4 2014-10-08 pjp static const char rcsid[] = "$Id: reply.c,v 1.60 2014/10/08 21:00:55 pjp Exp $";
93 dd869383 2013-02-16 pjp
94 c45084ea 2005-11-29 pbug /*
95 c45084ea 2005-11-29 pbug * REPLY_A() - replies a DNS question (*q) on socket (so)
96 c45084ea 2005-11-29 pbug *
97 c45084ea 2005-11-29 pbug */
98 c45084ea 2005-11-29 pbug
99 a2b189d4 2014-10-08 pjp int
100 33a0a60d 2009-11-03 pbug reply_a(struct sreply *sreply, DB *db)
101 c45084ea 2005-11-29 pbug {
102 df34d218 2014-04-21 pjp char *reply = sreply->replybuf;
103 c45084ea 2005-11-29 pbug struct dns_header *odh;
104 b6dc64dc 2010-04-15 pbug u_int16_t outlen;
105 c45084ea 2005-11-29 pbug int a_count;
106 33a0a60d 2009-11-03 pbug int mod, pos;
107 ed247332 2010-03-09 pbug int ttlhack = 0;
108 c45084ea 2005-11-29 pbug
109 c45084ea 2005-11-29 pbug struct answer {
110 c45084ea 2005-11-29 pbug char name[2];
111 c45084ea 2005-11-29 pbug u_int16_t type;
112 c45084ea 2005-11-29 pbug u_int16_t class;
113 c45084ea 2005-11-29 pbug u_int32_t ttl;
114 c45084ea 2005-11-29 pbug u_int16_t rdlength; /* 12 */
115 c45084ea 2005-11-29 pbug in_addr_t rdata; /* 16 */
116 c45084ea 2005-11-29 pbug } __attribute__((packed));
117 c45084ea 2005-11-29 pbug
118 c45084ea 2005-11-29 pbug struct answer *answer;
119 c45084ea 2005-11-29 pbug
120 c45084ea 2005-11-29 pbug int so = sreply->so;
121 c45084ea 2005-11-29 pbug char *buf = sreply->buf;
122 c45084ea 2005-11-29 pbug int len = sreply->len;
123 c45084ea 2005-11-29 pbug struct question *q = sreply->q;
124 c45084ea 2005-11-29 pbug struct sockaddr *sa = sreply->sa;
125 c45084ea 2005-11-29 pbug int salen = sreply->salen;
126 c45084ea 2005-11-29 pbug struct domain *sd = sreply->sd1;
127 c45084ea 2005-11-29 pbug
128 ed247332 2010-03-09 pbug u_int8_t region = sreply->region;
129 f1e3cfca 2010-03-12 pbug int istcp = sreply->istcp;
130 df34d218 2014-04-21 pjp int replysize = 512;
131 a2b189d4 2014-10-08 pjp int retlen = -1;
132 c45084ea 2005-11-29 pbug
133 df34d218 2014-04-21 pjp if (istcp) {
134 df34d218 2014-04-21 pjp replysize = 65535;
135 df34d218 2014-04-21 pjp }
136 cd18f393 2014-05-10 pjp
137 cd18f393 2014-05-10 pjp if (q->edns0len > 512)
138 cd18f393 2014-05-10 pjp replysize = q->edns0len;
139 df34d218 2014-04-21 pjp
140 959d1769 2010-04-05 pbug odh = (struct dns_header *)&reply[0];
141 f1e3cfca 2010-03-12 pbug
142 c45084ea 2005-11-29 pbug outlen = sizeof(struct dns_header);
143 c45084ea 2005-11-29 pbug
144 df34d218 2014-04-21 pjp if (len > replysize) {
145 a2b189d4 2014-10-08 pjp return (retlen);
146 c45084ea 2005-11-29 pbug }
147 c45084ea 2005-11-29 pbug
148 df34d218 2014-04-21 pjp memcpy(reply, buf, sizeof(struct dns_header) + q->hdr->namelen + 4);
149 c45084ea 2005-11-29 pbug memset((char *)&odh->query, 0, sizeof(u_int16_t));
150 c45084ea 2005-11-29 pbug
151 c45084ea 2005-11-29 pbug outlen += (q->hdr->namelen + 4);
152 c45084ea 2005-11-29 pbug
153 c45084ea 2005-11-29 pbug SET_DNS_REPLY(odh);
154 22893736 2010-09-19 pbug if (sreply->sr == NULL)
155 22893736 2010-09-19 pbug SET_DNS_AUTHORITATIVE(odh);
156 22893736 2010-09-19 pbug else
157 22893736 2010-09-19 pbug SET_DNS_RECURSION_AVAIL(odh);
158 22893736 2010-09-19 pbug
159 c45084ea 2005-11-29 pbug HTONS(odh->query);
160 c45084ea 2005-11-29 pbug
161 5841985a 2010-03-18 pbug odh->question = htons(1);
162 5841985a 2010-03-18 pbug odh->answer = htons(sd->a_count);
163 c45084ea 2005-11-29 pbug odh->nsrr = 0;
164 c45084ea 2005-11-29 pbug odh->additional = 0;
165 c45084ea 2005-11-29 pbug
166 c45084ea 2005-11-29 pbug /* skip dns header, question name, qtype and qclass */
167 959d1769 2010-04-05 pbug answer = (struct answer *)(&reply[0] + sizeof(struct dns_header) +
168 c45084ea 2005-11-29 pbug q->hdr->namelen + 4);
169 c45084ea 2005-11-29 pbug
170 ed247332 2010-03-09 pbug /* if we aren't a balance record our region code is 0xff so check */
171 ed247332 2010-03-09 pbug if (sd->region[sd->a_ptr] != 0xff) {
172 ed247332 2010-03-09 pbug ttlhack = 1;
173 ed247332 2010-03-09 pbug }
174 ed247332 2010-03-09 pbug
175 c45084ea 2005-11-29 pbug a_count = 0;
176 33a0a60d 2009-11-03 pbug pos = sd->a_ptr;
177 33a0a60d 2009-11-03 pbug mod = sd->a_count;
178 33a0a60d 2009-11-03 pbug
179 c45084ea 2005-11-29 pbug do {
180 d6a24f1e 2008-07-24 pbug /*
181 ed247332 2010-03-09 pbug * skip records that are not in the needed region
182 ed247332 2010-03-09 pbug */
183 ed247332 2010-03-09 pbug if (ttlhack && sd->region[pos % mod] != region) {
184 ed247332 2010-03-09 pbug pos++;
185 ed247332 2010-03-09 pbug continue;
186 ed247332 2010-03-09 pbug }
187 ed247332 2010-03-09 pbug
188 ed247332 2010-03-09 pbug /*
189 d6a24f1e 2008-07-24 pbug * answer->name is a pointer to the request (0xc00c)
190 d6a24f1e 2008-07-24 pbug */
191 c45084ea 2005-11-29 pbug
192 d6a24f1e 2008-07-24 pbug answer->name[0] = 0xc0; /* 1 byte */
193 d6a24f1e 2008-07-24 pbug answer->name[1] = 0x0c; /* 2 bytes */
194 d6a24f1e 2008-07-24 pbug answer->type = q->hdr->qtype; /* 4 bytes */
195 d6a24f1e 2008-07-24 pbug answer->class = q->hdr->qclass; /* 6 bytes */
196 5528a18e 2010-09-21 pbug if (sreply->sr != NULL)
197 5528a18e 2010-09-21 pbug answer->ttl = htonl(sd->ttl - (time(NULL) - sd->created));
198 5528a18e 2010-09-21 pbug else
199 5528a18e 2010-09-21 pbug answer->ttl = htonl(sd->ttl); /* 10 bytes */
200 c45084ea 2005-11-29 pbug
201 d6a24f1e 2008-07-24 pbug answer->rdlength = htons(sizeof(in_addr_t)); /* 12 bytes */
202 d6a24f1e 2008-07-24 pbug
203 33a0a60d 2009-11-03 pbug memcpy((char *)&answer->rdata, (char *)&sd->a[pos++ % mod],
204 d6a24f1e 2008-07-24 pbug sizeof(in_addr_t)); /* 16 bytes */
205 33a0a60d 2009-11-03 pbug
206 33a0a60d 2009-11-03 pbug a_count++;
207 c45084ea 2005-11-29 pbug outlen += 16;
208 c45084ea 2005-11-29 pbug
209 c45084ea 2005-11-29 pbug /* can we afford to write another header? if no truncate */
210 1f1faf13 2014-05-11 pjp if (sd->a_count > 1 && outlen + 16 > replysize) {
211 c45084ea 2005-11-29 pbug NTOHS(odh->query);
212 c45084ea 2005-11-29 pbug SET_DNS_TRUNCATION(odh);
213 c45084ea 2005-11-29 pbug HTONS(odh->query);
214 c45084ea 2005-11-29 pbug goto out;
215 c45084ea 2005-11-29 pbug }
216 c45084ea 2005-11-29 pbug
217 ed247332 2010-03-09 pbug
218 c45084ea 2005-11-29 pbug /* set new offset for answer */
219 c45084ea 2005-11-29 pbug answer = (struct answer *)&reply[outlen];
220 b0a72376 2010-04-01 pbug } while (a_count < RECORD_COUNT && --sd->a_count);
221 ed247332 2010-03-09 pbug
222 ed247332 2010-03-09 pbug if (ttlhack) {
223 5841985a 2010-03-18 pbug odh->answer = htons(a_count);
224 cd18f393 2014-05-10 pjp }
225 cd18f393 2014-05-10 pjp
226 cd18f393 2014-05-10 pjp if (q->edns0len) {
227 cd18f393 2014-05-10 pjp /* tag on edns0 opt record */
228 cd18f393 2014-05-10 pjp odh->additional = htons(1);
229 cd18f393 2014-05-10 pjp outlen = additional_opt(q, reply, replysize, outlen);
230 ed247332 2010-03-09 pbug }
231 ed247332 2010-03-09 pbug
232 c45084ea 2005-11-29 pbug out:
233 22893736 2010-09-19 pbug if (sreply->sr != NULL) {
234 a2b189d4 2014-10-08 pjp retlen = reply_raw2(so, reply, outlen, sreply->sr);
235 22893736 2010-09-19 pbug } else {
236 22893736 2010-09-19 pbug if (istcp) {
237 22893736 2010-09-19 pbug char *tmpbuf;
238 22893736 2010-09-19 pbug u_int16_t *plen;
239 959d1769 2010-04-05 pbug
240 22893736 2010-09-19 pbug tmpbuf = malloc(outlen + 2);
241 22893736 2010-09-19 pbug if (tmpbuf == NULL) {
242 dd869383 2013-02-16 pjp dolog(LOG_INFO, "malloc: %s\n", strerror(errno));
243 22893736 2010-09-19 pbug }
244 22893736 2010-09-19 pbug plen = (u_int16_t *)tmpbuf;
245 22893736 2010-09-19 pbug *plen = htons(outlen);
246 22893736 2010-09-19 pbug
247 22893736 2010-09-19 pbug memcpy(&tmpbuf[2], reply, outlen);
248 959d1769 2010-04-05 pbug
249 a2b189d4 2014-10-08 pjp if ((retlen = send(so, tmpbuf, outlen + 2, 0)) < 0) {
250 dd869383 2013-02-16 pjp dolog(LOG_INFO, "send: %s\n", strerror(errno));
251 22893736 2010-09-19 pbug }
252 22893736 2010-09-19 pbug free(tmpbuf);
253 22893736 2010-09-19 pbug } else {
254 a2b189d4 2014-10-08 pjp if ((retlen = sendto(so, reply, outlen, 0, sa, salen)) < 0) {
255 dd869383 2013-02-16 pjp dolog(LOG_INFO, "sendto: %s\n", strerror(errno));
256 22893736 2010-09-19 pbug }
257 22893736 2010-09-19 pbug }
258 33a0a60d 2009-11-03 pbug
259 22893736 2010-09-19 pbug } /* if (->sr) */
260 33a0a60d 2009-11-03 pbug /*
261 33a0a60d 2009-11-03 pbug * update a_ptr setting
262 33a0a60d 2009-11-03 pbug */
263 c45084ea 2005-11-29 pbug
264 33a0a60d 2009-11-03 pbug sd->a_ptr = (sd->a_ptr + 1) % mod;
265 33a0a60d 2009-11-03 pbug sd->a_count = mod; /* I know I know */
266 33a0a60d 2009-11-03 pbug update_db(db, sd);
267 33a0a60d 2009-11-03 pbug
268 a2b189d4 2014-10-08 pjp return (retlen);
269 c45084ea 2005-11-29 pbug }
270 c45084ea 2005-11-29 pbug
271 c45084ea 2005-11-29 pbug /*
272 c45084ea 2005-11-29 pbug * REPLY_AAAA() - replies a DNS question (*q) on socket (so)
273 c45084ea 2005-11-29 pbug *
274 c45084ea 2005-11-29 pbug */
275 c45084ea 2005-11-29 pbug
276 a2b189d4 2014-10-08 pjp int
277 33a0a60d 2009-11-03 pbug reply_aaaa(struct sreply *sreply, DB *db)
278 c45084ea 2005-11-29 pbug {
279 df34d218 2014-04-21 pjp char *reply = sreply->replybuf;
280 c45084ea 2005-11-29 pbug struct dns_header *odh;
281 b6dc64dc 2010-04-15 pbug u_int16_t outlen;
282 c45084ea 2005-11-29 pbug int aaaa_count;
283 33a0a60d 2009-11-03 pbug int mod, pos;
284 c45084ea 2005-11-29 pbug
285 c45084ea 2005-11-29 pbug struct answer {
286 c45084ea 2005-11-29 pbug char name[2];
287 c45084ea 2005-11-29 pbug u_int16_t type;
288 c45084ea 2005-11-29 pbug u_int16_t class;
289 c45084ea 2005-11-29 pbug u_int32_t ttl;
290 c45084ea 2005-11-29 pbug u_int16_t rdlength; /* 12 */
291 c45084ea 2005-11-29 pbug char rdata; /* 12 + 16 */
292 c45084ea 2005-11-29 pbug } __attribute__((packed));
293 c45084ea 2005-11-29 pbug
294 c45084ea 2005-11-29 pbug struct answer *answer;
295 c45084ea 2005-11-29 pbug
296 c45084ea 2005-11-29 pbug int so = sreply->so;
297 c45084ea 2005-11-29 pbug char *buf = sreply->buf;
298 c45084ea 2005-11-29 pbug int len = sreply->len;
299 c45084ea 2005-11-29 pbug struct question *q = sreply->q;
300 c45084ea 2005-11-29 pbug struct sockaddr *sa = sreply->sa;
301 c45084ea 2005-11-29 pbug int salen = sreply->salen;
302 c45084ea 2005-11-29 pbug struct domain *sd = sreply->sd1;
303 f1e3cfca 2010-03-12 pbug int istcp = sreply->istcp;
304 df34d218 2014-04-21 pjp int replysize = 512;
305 a2b189d4 2014-10-08 pjp int retlen = -1;
306 df34d218 2014-04-21 pjp
307 df34d218 2014-04-21 pjp if (istcp) {
308 df34d218 2014-04-21 pjp replysize = 65535;
309 df34d218 2014-04-21 pjp }
310 cd18f393 2014-05-10 pjp
311 cd18f393 2014-05-10 pjp if (q->edns0len > 512)
312 cd18f393 2014-05-10 pjp replysize = q->edns0len;
313 c45084ea 2005-11-29 pbug
314 c45084ea 2005-11-29 pbug
315 959d1769 2010-04-05 pbug odh = (struct dns_header *)&reply[0];
316 c45084ea 2005-11-29 pbug
317 c45084ea 2005-11-29 pbug outlen = sizeof(struct dns_header);
318 c45084ea 2005-11-29 pbug
319 df34d218 2014-04-21 pjp if (len > replysize) {
320 a2b189d4 2014-10-08 pjp return (retlen);
321 c45084ea 2005-11-29 pbug }
322 c45084ea 2005-11-29 pbug
323 df34d218 2014-04-21 pjp memcpy(reply, buf, sizeof(struct dns_header) + q->hdr->namelen + 4);
324 c45084ea 2005-11-29 pbug memset((char *)&odh->query, 0, sizeof(u_int16_t));
325 c45084ea 2005-11-29 pbug
326 c45084ea 2005-11-29 pbug outlen += (q->hdr->namelen + 4);
327 c45084ea 2005-11-29 pbug
328 c45084ea 2005-11-29 pbug SET_DNS_REPLY(odh);
329 8c01150e 2010-09-25 pbug if (sreply->sr == NULL)
330 8c01150e 2010-09-25 pbug SET_DNS_AUTHORITATIVE(odh);
331 8c01150e 2010-09-25 pbug else
332 8c01150e 2010-09-25 pbug SET_DNS_RECURSION_AVAIL(odh);
333 c45084ea 2005-11-29 pbug
334 c45084ea 2005-11-29 pbug HTONS(odh->query);
335 c45084ea 2005-11-29 pbug
336 5841985a 2010-03-18 pbug odh->question = htons(1);
337 5841985a 2010-03-18 pbug odh->answer = htons(sd->aaaa_count);
338 c45084ea 2005-11-29 pbug odh->nsrr = 0;
339 c45084ea 2005-11-29 pbug odh->additional = 0;
340 c45084ea 2005-11-29 pbug
341 c45084ea 2005-11-29 pbug /* skip dns header, question name, qtype and qclass */
342 959d1769 2010-04-05 pbug answer = (struct answer *)(&reply[0] + sizeof(struct dns_header) +
343 f1e3cfca 2010-03-12 pbug q->hdr->namelen + 4);
344 f1e3cfca 2010-03-12 pbug
345 c45084ea 2005-11-29 pbug
346 c45084ea 2005-11-29 pbug aaaa_count = 0;
347 33a0a60d 2009-11-03 pbug pos = sd->aaaa_ptr;
348 33a0a60d 2009-11-03 pbug mod = sd->aaaa_count;
349 c45084ea 2005-11-29 pbug
350 c45084ea 2005-11-29 pbug do {
351 c45084ea 2005-11-29 pbug answer->name[0] = 0xc0;
352 c45084ea 2005-11-29 pbug answer->name[1] = 0x0c;
353 c45084ea 2005-11-29 pbug answer->type = q->hdr->qtype;
354 c45084ea 2005-11-29 pbug answer->class = q->hdr->qclass;
355 8c01150e 2010-09-25 pbug if (sreply->sr != NULL)
356 8c01150e 2010-09-25 pbug answer->ttl = htonl(sd->ttl - (time(NULL) - sd->created));
357 8c01150e 2010-09-25 pbug else
358 8c01150e 2010-09-25 pbug answer->ttl = htonl(sd->ttl); /* 10 bytes */
359 c45084ea 2005-11-29 pbug
360 c45084ea 2005-11-29 pbug answer->rdlength = htons(sizeof(struct in6_addr));
361 c45084ea 2005-11-29 pbug
362 f98bb34d 2011-09-19 pbug memcpy((char *)&answer->rdata, (char *)&sd->aaaa[pos++ % mod], sizeof(struct in6_addr));
363 c45084ea 2005-11-29 pbug outlen += 28;
364 c45084ea 2005-11-29 pbug
365 c45084ea 2005-11-29 pbug /* can we afford to write another header? if no truncate */
366 1f1faf13 2014-05-11 pjp if (sd->aaaa_count > 1 && outlen + 28 > replysize) {
367 c45084ea 2005-11-29 pbug NTOHS(odh->query);
368 c45084ea 2005-11-29 pbug SET_DNS_TRUNCATION(odh);
369 c45084ea 2005-11-29 pbug HTONS(odh->query);
370 c45084ea 2005-11-29 pbug goto out;
371 c45084ea 2005-11-29 pbug }
372 c45084ea 2005-11-29 pbug
373 33a0a60d 2009-11-03 pbug aaaa_count++;
374 33a0a60d 2009-11-03 pbug
375 c45084ea 2005-11-29 pbug /* set new offset for answer */
376 c45084ea 2005-11-29 pbug answer = (struct answer *)&reply[outlen];
377 b0a72376 2010-04-01 pbug } while (aaaa_count < RECORD_COUNT && --sd->aaaa_count);
378 c45084ea 2005-11-29 pbug
379 cd18f393 2014-05-10 pjp if (q->edns0len) {
380 cd18f393 2014-05-10 pjp /* tag on edns0 opt record */
381 cd18f393 2014-05-10 pjp odh->additional = htons(1);
382 cd18f393 2014-05-10 pjp outlen = additional_opt(q, reply, replysize, outlen);
383 cd18f393 2014-05-10 pjp }
384 cd18f393 2014-05-10 pjp
385 c45084ea 2005-11-29 pbug out:
386 8c01150e 2010-09-25 pbug if (sreply->sr != NULL) {
387 a2b189d4 2014-10-08 pjp retlen = reply_raw2(so, reply, outlen, sreply->sr);
388 8c01150e 2010-09-25 pbug } else {
389 8c01150e 2010-09-25 pbug if (istcp) {
390 8c01150e 2010-09-25 pbug char *tmpbuf;
391 8c01150e 2010-09-25 pbug u_int16_t *plen;
392 959d1769 2010-04-05 pbug
393 8c01150e 2010-09-25 pbug tmpbuf = malloc(outlen + 2);
394 8c01150e 2010-09-25 pbug if (tmpbuf == NULL) {
395 dd869383 2013-02-16 pjp dolog(LOG_INFO, "malloc: %s\n", strerror(errno));
396 8c01150e 2010-09-25 pbug }
397 8c01150e 2010-09-25 pbug plen = (u_int16_t *)tmpbuf;
398 8c01150e 2010-09-25 pbug *plen = htons(outlen);
399 8c01150e 2010-09-25 pbug
400 8c01150e 2010-09-25 pbug memcpy(&tmpbuf[2], reply, outlen);
401 8c01150e 2010-09-25 pbug
402 a2b189d4 2014-10-08 pjp if ((retlen = send(so, tmpbuf, outlen + 2, 0)) < 0) {
403 dd869383 2013-02-16 pjp dolog(LOG_INFO, "send: %s\n", strerror(errno));
404 8c01150e 2010-09-25 pbug }
405 8c01150e 2010-09-25 pbug free(tmpbuf);
406 8c01150e 2010-09-25 pbug } else {
407 a2b189d4 2014-10-08 pjp if ((retlen = sendto(so, reply, outlen, 0, sa, salen)) < 0) {
408 dd869383 2013-02-16 pjp dolog(LOG_INFO, "sendto: %s\n", strerror(errno));
409 8c01150e 2010-09-25 pbug }
410 f1e3cfca 2010-03-12 pbug }
411 c45084ea 2005-11-29 pbug }
412 c45084ea 2005-11-29 pbug
413 33a0a60d 2009-11-03 pbug sd->aaaa_ptr = (sd->aaaa_ptr + 1) % mod;
414 33a0a60d 2009-11-03 pbug sd->aaaa_count = mod;
415 33a0a60d 2009-11-03 pbug update_db(db, sd);
416 33a0a60d 2009-11-03 pbug
417 a2b189d4 2014-10-08 pjp return (retlen);
418 c45084ea 2005-11-29 pbug }
419 c45084ea 2005-11-29 pbug
420 c45084ea 2005-11-29 pbug /*
421 c45084ea 2005-11-29 pbug * REPLY_MX() - replies a DNS question (*q) on socket (so)
422 c45084ea 2005-11-29 pbug *
423 c45084ea 2005-11-29 pbug */
424 c45084ea 2005-11-29 pbug
425 a2b189d4 2014-10-08 pjp int
426 a042435d 2010-03-19 pbug reply_mx(struct sreply *sreply, DB *db)
427 c45084ea 2005-11-29 pbug {
428 df34d218 2014-04-21 pjp char *reply = sreply->replybuf;
429 c45084ea 2005-11-29 pbug struct dns_header *odh;
430 a042435d 2010-03-19 pbug struct domain *sd0;
431 c45084ea 2005-11-29 pbug int mx_count;
432 f1e3cfca 2010-03-12 pbug u_int16_t *plen;
433 a042435d 2010-03-19 pbug char *name;
434 b6dc64dc 2010-04-15 pbug u_int16_t outlen;
435 b6dc64dc 2010-04-15 pbug u_int16_t namelen;
436 a042435d 2010-03-19 pbug int additional = 0;
437 c45084ea 2005-11-29 pbug
438 c45084ea 2005-11-29 pbug struct answer {
439 c45084ea 2005-11-29 pbug char name[2];
440 c45084ea 2005-11-29 pbug u_int16_t type;
441 c45084ea 2005-11-29 pbug u_int16_t class;
442 c45084ea 2005-11-29 pbug u_int32_t ttl;
443 c45084ea 2005-11-29 pbug u_int16_t rdlength; /* 12 */
444 c45084ea 2005-11-29 pbug u_int16_t mx_priority;
445 c45084ea 2005-11-29 pbug char exchange;
446 c45084ea 2005-11-29 pbug } __attribute__((packed));
447 c45084ea 2005-11-29 pbug
448 c45084ea 2005-11-29 pbug struct answer *answer;
449 c45084ea 2005-11-29 pbug
450 c45084ea 2005-11-29 pbug int so = sreply->so;
451 c45084ea 2005-11-29 pbug char *buf = sreply->buf;
452 c45084ea 2005-11-29 pbug int len = sreply->len;
453 c45084ea 2005-11-29 pbug struct question *q = sreply->q;
454 c45084ea 2005-11-29 pbug struct sockaddr *sa = sreply->sa;
455 c45084ea 2005-11-29 pbug int salen = sreply->salen;
456 c45084ea 2005-11-29 pbug struct domain *sd = sreply->sd1;
457 f1e3cfca 2010-03-12 pbug int istcp = sreply->istcp;
458 959d1769 2010-04-05 pbug int wildcard = sreply->wildcard;
459 df34d218 2014-04-21 pjp int replysize = 512;
460 a2b189d4 2014-10-08 pjp int retlen = -1;
461 df34d218 2014-04-21 pjp
462 df34d218 2014-04-21 pjp if (istcp) {
463 df34d218 2014-04-21 pjp replysize = 65535;
464 df34d218 2014-04-21 pjp }
465 c45084ea 2005-11-29 pbug
466 cd18f393 2014-05-10 pjp if (q->edns0len > 512)
467 cd18f393 2014-05-10 pjp replysize = q->edns0len;
468 c45084ea 2005-11-29 pbug
469 a042435d 2010-03-19 pbug odh = (struct dns_header *)&reply[0];
470 f1e3cfca 2010-03-12 pbug
471 c45084ea 2005-11-29 pbug outlen = sizeof(struct dns_header);
472 c45084ea 2005-11-29 pbug
473 df34d218 2014-04-21 pjp if (len > replysize) {
474 a2b189d4 2014-10-08 pjp return (retlen);
475 c45084ea 2005-11-29 pbug }
476 c45084ea 2005-11-29 pbug
477 df34d218 2014-04-21 pjp memcpy(reply, buf, sizeof(struct dns_header) + q->hdr->namelen + 4);
478 c45084ea 2005-11-29 pbug memset((char *)&odh->query, 0, sizeof(u_int16_t));
479 c45084ea 2005-11-29 pbug
480 c45084ea 2005-11-29 pbug outlen += (q->hdr->namelen + 4);
481 c45084ea 2005-11-29 pbug
482 c45084ea 2005-11-29 pbug SET_DNS_REPLY(odh);
483 8bd942da 2010-09-26 pbug
484 8bd942da 2010-09-26 pbug if (sreply->sr == NULL) {
485 8bd942da 2010-09-26 pbug SET_DNS_AUTHORITATIVE(odh);
486 8bd942da 2010-09-26 pbug } else
487 8bd942da 2010-09-26 pbug SET_DNS_RECURSION_AVAIL(odh);
488 c45084ea 2005-11-29 pbug
489 c45084ea 2005-11-29 pbug HTONS(odh->query);
490 c45084ea 2005-11-29 pbug
491 5841985a 2010-03-18 pbug odh->question = htons(1);
492 5841985a 2010-03-18 pbug odh->answer = htons(sd->mx_count);
493 c45084ea 2005-11-29 pbug odh->nsrr = 0;
494 c45084ea 2005-11-29 pbug odh->additional = 0;
495 c45084ea 2005-11-29 pbug
496 c45084ea 2005-11-29 pbug /* skip dns header, question name, qtype and qclass */
497 a042435d 2010-03-19 pbug answer = (struct answer *)(&reply[0] + sizeof(struct dns_header) +
498 f1e3cfca 2010-03-12 pbug q->hdr->namelen + 4);
499 c45084ea 2005-11-29 pbug
500 c45084ea 2005-11-29 pbug mx_count = 0;
501 c45084ea 2005-11-29 pbug do {
502 c45084ea 2005-11-29 pbug answer->name[0] = 0xc0;
503 c45084ea 2005-11-29 pbug answer->name[1] = 0x0c;
504 c45084ea 2005-11-29 pbug answer->type = q->hdr->qtype;
505 c45084ea 2005-11-29 pbug answer->class = q->hdr->qclass;
506 8bd942da 2010-09-26 pbug if (sreply->sr != NULL)
507 8bd942da 2010-09-26 pbug answer->ttl = htonl(sd->ttl - (time(NULL) - sd->created));
508 8bd942da 2010-09-26 pbug else
509 8bd942da 2010-09-26 pbug answer->ttl = htonl(sd->ttl);
510 c45084ea 2005-11-29 pbug
511 f98bb34d 2011-09-19 pbug answer->rdlength = htons(sizeof(u_int16_t) + sd->mx[mx_count].exchangelen);
512 a042435d 2010-03-19 pbug
513 f98bb34d 2011-09-19 pbug answer->mx_priority = htons(sd->mx[mx_count].preference);
514 f98bb34d 2011-09-19 pbug memcpy((char *)&answer->exchange, (char *)sd->mx[mx_count].exchange, sd->mx[mx_count].exchangelen);
515 a042435d 2010-03-19 pbug
516 f98bb34d 2011-09-19 pbug name = sd->mx[mx_count].exchange;
517 f98bb34d 2011-09-19 pbug namelen = sd->mx[mx_count].exchangelen;
518 f98bb34d 2011-09-19 pbug
519 959d1769 2010-04-05 pbug sd0 = Lookup_zone(db, name, namelen, htons(DNS_TYPE_A), wildcard);
520 a042435d 2010-03-19 pbug if (sd0 != NULL) {
521 a042435d 2010-03-19 pbug cn1 = malloc(sizeof(struct collects));
522 a042435d 2010-03-19 pbug if (cn1 != NULL) {
523 a042435d 2010-03-19 pbug cn1->name = malloc(namelen);
524 a042435d 2010-03-19 pbug if (cn1->name != NULL) {
525 a042435d 2010-03-19 pbug memcpy(cn1->name, name, namelen);
526 a042435d 2010-03-19 pbug cn1->namelen = namelen;
527 a042435d 2010-03-19 pbug cn1->sd = sd0;
528 a042435d 2010-03-19 pbug cn1->type = DNS_TYPE_A;
529 a042435d 2010-03-19 pbug
530 c0963faf 2014-05-01 pjp SLIST_INSERT_HEAD(&collectshead, cn1, collect_entry);
531 a042435d 2010-03-19 pbug }
532 a042435d 2010-03-19 pbug }
533 a042435d 2010-03-19 pbug }
534 959d1769 2010-04-05 pbug sd0 = Lookup_zone(db, name, namelen, htons(DNS_TYPE_AAAA), wildcard);
535 a042435d 2010-03-19 pbug if (sd0 != NULL) {
536 a042435d 2010-03-19 pbug cn1 = malloc(sizeof(struct collects));
537 a042435d 2010-03-19 pbug if (cn1 != NULL) {
538 a042435d 2010-03-19 pbug cn1->name = malloc(namelen);
539 a042435d 2010-03-19 pbug if (cn1->name != NULL) {
540 a042435d 2010-03-19 pbug memcpy(cn1->name, name, namelen);
541 a042435d 2010-03-19 pbug cn1->namelen = namelen;
542 a042435d 2010-03-19 pbug cn1->sd = sd0;
543 a042435d 2010-03-19 pbug cn1->type = DNS_TYPE_AAAA;
544 a042435d 2010-03-19 pbug
545 c0963faf 2014-05-01 pjp SLIST_INSERT_HEAD(&collectshead, cn1, collect_entry);
546 a042435d 2010-03-19 pbug }
547 a042435d 2010-03-19 pbug }
548 a042435d 2010-03-19 pbug }
549 a042435d 2010-03-19 pbug
550 f98bb34d 2011-09-19 pbug outlen += (12 + 2 + sd->mx[mx_count].exchangelen);
551 c45084ea 2005-11-29 pbug
552 c45084ea 2005-11-29 pbug /* can we afford to write another header? if no truncate */
553 1f1faf13 2014-05-11 pjp if (sd->mx_count > 1 && (outlen + 12 + 2 + sd->mx[mx_count].exchangelen) > replysize) {
554 c45084ea 2005-11-29 pbug NTOHS(odh->query);
555 c45084ea 2005-11-29 pbug SET_DNS_TRUNCATION(odh);
556 c45084ea 2005-11-29 pbug HTONS(odh->query);
557 c45084ea 2005-11-29 pbug goto out;
558 c45084ea 2005-11-29 pbug }
559 c45084ea 2005-11-29 pbug
560 c45084ea 2005-11-29 pbug /* set new offset for answer */
561 c45084ea 2005-11-29 pbug answer = (struct answer *)&reply[outlen];
562 b0a72376 2010-04-01 pbug } while (++mx_count < RECORD_COUNT && --sd->mx_count);
563 c45084ea 2005-11-29 pbug
564 a042435d 2010-03-19 pbug /* write additional */
565 a042435d 2010-03-19 pbug
566 c0963faf 2014-05-01 pjp SLIST_FOREACH(cnp, &collectshead, collect_entry) {
567 a042435d 2010-03-19 pbug int addcount;
568 a042435d 2010-03-19 pbug int tmplen;
569 a042435d 2010-03-19 pbug
570 a042435d 2010-03-19 pbug switch (cnp->type) {
571 a042435d 2010-03-19 pbug case DNS_TYPE_A:
572 df34d218 2014-04-21 pjp tmplen = additional_a(cnp->name, cnp->namelen, cnp->sd, reply, replysize, outlen, &addcount);
573 a042435d 2010-03-19 pbug additional += addcount;
574 a042435d 2010-03-19 pbug break;
575 a042435d 2010-03-19 pbug case DNS_TYPE_AAAA:
576 df34d218 2014-04-21 pjp tmplen = additional_aaaa(cnp->name, cnp->namelen, cnp->sd, reply, replysize, outlen, &addcount);
577 a042435d 2010-03-19 pbug additional += addcount;
578 a042435d 2010-03-19 pbug break;
579 a042435d 2010-03-19 pbug }
580 a042435d 2010-03-19 pbug
581 a042435d 2010-03-19 pbug if (tmplen > 0) {
582 a042435d 2010-03-19 pbug outlen = tmplen;
583 a042435d 2010-03-19 pbug }
584 a042435d 2010-03-19 pbug }
585 a042435d 2010-03-19 pbug
586 a042435d 2010-03-19 pbug odh->additional = htons(additional);
587 a042435d 2010-03-19 pbug
588 a042435d 2010-03-19 pbug while (!SLIST_EMPTY(&collectshead)) {
589 a042435d 2010-03-19 pbug cn1 = SLIST_FIRST(&collectshead);
590 c0963faf 2014-05-01 pjp SLIST_REMOVE_HEAD(&collectshead, collect_entry);
591 a042435d 2010-03-19 pbug free(cn1->name);
592 a042435d 2010-03-19 pbug free(cn1->sd);
593 a042435d 2010-03-19 pbug free(cn1);
594 cd18f393 2014-05-10 pjp }
595 cd18f393 2014-05-10 pjp
596 cd18f393 2014-05-10 pjp if (q->edns0len) {
597 cd18f393 2014-05-10 pjp /* tag on edns0 opt record */
598 cd18f393 2014-05-10 pjp NTOHS(odh->additional);
599 cd18f393 2014-05-10 pjp odh->additional++;
600 cd18f393 2014-05-10 pjp HTONS(odh->additional);
601 cd18f393 2014-05-10 pjp
602 cd18f393 2014-05-10 pjp outlen = additional_opt(q, reply, replysize, outlen);
603 a042435d 2010-03-19 pbug }
604 a042435d 2010-03-19 pbug
605 c45084ea 2005-11-29 pbug out:
606 8bd942da 2010-09-26 pbug if (sreply->sr != NULL) {
607 a2b189d4 2014-10-08 pjp retlen = reply_raw2(so, reply, outlen, sreply->sr);
608 8bd942da 2010-09-26 pbug } else {
609 8bd942da 2010-09-26 pbug if (istcp) {
610 8bd942da 2010-09-26 pbug char *tmpbuf;
611 a042435d 2010-03-19 pbug
612 8bd942da 2010-09-26 pbug tmpbuf = malloc(outlen + 2);
613 8bd942da 2010-09-26 pbug if (tmpbuf == NULL) {
614 dd869383 2013-02-16 pjp dolog(LOG_INFO, "malloc: %s\n", strerror(errno));
615 8bd942da 2010-09-26 pbug }
616 8bd942da 2010-09-26 pbug plen = (u_int16_t *)tmpbuf;
617 8bd942da 2010-09-26 pbug *plen = htons(outlen);
618 8bd942da 2010-09-26 pbug
619 8bd942da 2010-09-26 pbug memcpy(&tmpbuf[2], reply, outlen);
620 a2b189d4 2014-10-08 pjp if ((retlen = send(so, tmpbuf, outlen + 2, 0)) < 0) {
621 dd869383 2013-02-16 pjp dolog(LOG_INFO, "send: %s\n", strerror(errno));
622 8bd942da 2010-09-26 pbug }
623 8bd942da 2010-09-26 pbug free(tmpbuf);
624 8bd942da 2010-09-26 pbug } else {
625 a2b189d4 2014-10-08 pjp if ((retlen = sendto(so, reply, outlen, 0, sa, salen)) < 0) {
626 dd869383 2013-02-16 pjp dolog(LOG_INFO, "sendto: %s\n", strerror(errno));
627 8bd942da 2010-09-26 pbug }
628 f1e3cfca 2010-03-12 pbug }
629 c45084ea 2005-11-29 pbug }
630 c45084ea 2005-11-29 pbug
631 a2b189d4 2014-10-08 pjp return (retlen);
632 c45084ea 2005-11-29 pbug }
633 c45084ea 2005-11-29 pbug
634 c45084ea 2005-11-29 pbug /*
635 c45084ea 2005-11-29 pbug * REPLY_NS() - replies a DNS question (*q) on socket (so)
636 c45084ea 2005-11-29 pbug *
637 c45084ea 2005-11-29 pbug */
638 c45084ea 2005-11-29 pbug
639 a2b189d4 2014-10-08 pjp int
640 33a0a60d 2009-11-03 pbug reply_ns(struct sreply *sreply, DB *db)
641 c45084ea 2005-11-29 pbug {
642 df34d218 2014-04-21 pjp char *reply = sreply->replybuf;
643 c45084ea 2005-11-29 pbug struct dns_header *odh;
644 a042435d 2010-03-19 pbug struct domain *sd0;
645 b0a72376 2010-04-01 pbug int tmplen;
646 c45084ea 2005-11-29 pbug int ns_count;
647 33a0a60d 2009-11-03 pbug int mod, pos;
648 f1e3cfca 2010-03-12 pbug u_int16_t *plen;
649 a042435d 2010-03-19 pbug char *name;
650 b6dc64dc 2010-04-15 pbug u_int16_t outlen;
651 b6dc64dc 2010-04-15 pbug u_int16_t namelen;
652 a042435d 2010-03-19 pbug int additional = 0;
653 c45084ea 2005-11-29 pbug
654 c45084ea 2005-11-29 pbug struct answer {
655 c45084ea 2005-11-29 pbug char name[2];
656 c45084ea 2005-11-29 pbug u_int16_t type;
657 c45084ea 2005-11-29 pbug u_int16_t class;
658 c45084ea 2005-11-29 pbug u_int32_t ttl;
659 c45084ea 2005-11-29 pbug u_int16_t rdlength; /* 12 */
660 c45084ea 2005-11-29 pbug char ns;
661 c45084ea 2005-11-29 pbug } __attribute__((packed));
662 c45084ea 2005-11-29 pbug
663 c45084ea 2005-11-29 pbug struct answer *answer;
664 c45084ea 2005-11-29 pbug
665 c45084ea 2005-11-29 pbug int so = sreply->so;
666 c45084ea 2005-11-29 pbug char *buf = sreply->buf;
667 c45084ea 2005-11-29 pbug int len = sreply->len;
668 c45084ea 2005-11-29 pbug struct question *q = sreply->q;
669 c45084ea 2005-11-29 pbug struct sockaddr *sa = sreply->sa;
670 c45084ea 2005-11-29 pbug int salen = sreply->salen;
671 c45084ea 2005-11-29 pbug struct domain *sd = sreply->sd1;
672 f1e3cfca 2010-03-12 pbug int istcp = sreply->istcp;
673 959d1769 2010-04-05 pbug int wildcard = sreply->wildcard;
674 df34d218 2014-04-21 pjp int replysize = 512;
675 a2b189d4 2014-10-08 pjp int retlen = -1;
676 df34d218 2014-04-21 pjp
677 df34d218 2014-04-21 pjp if (istcp) {
678 df34d218 2014-04-21 pjp replysize = 65535;
679 df34d218 2014-04-21 pjp }
680 cd18f393 2014-05-10 pjp
681 cd18f393 2014-05-10 pjp if (q->edns0len > 512)
682 cd18f393 2014-05-10 pjp replysize = q->edns0len;
683 c45084ea 2005-11-29 pbug
684 a042435d 2010-03-19 pbug odh = (struct dns_header *)&reply[0];
685 f1e3cfca 2010-03-12 pbug
686 c45084ea 2005-11-29 pbug outlen = sizeof(struct dns_header);
687 c45084ea 2005-11-29 pbug
688 df34d218 2014-04-21 pjp if (len > replysize) {
689 a2b189d4 2014-10-08 pjp return (retlen);
690 c45084ea 2005-11-29 pbug }
691 c45084ea 2005-11-29 pbug
692 df34d218 2014-04-21 pjp memcpy(reply, buf, sizeof(struct dns_header) + q->hdr->namelen + 4);
693 f1e3cfca 2010-03-12 pbug
694 c45084ea 2005-11-29 pbug memset((char *)&odh->query, 0, sizeof(u_int16_t));
695 c45084ea 2005-11-29 pbug
696 c45084ea 2005-11-29 pbug outlen += (q->hdr->namelen + 4);
697 c45084ea 2005-11-29 pbug
698 c45084ea 2005-11-29 pbug SET_DNS_REPLY(odh);
699 5841985a 2010-03-18 pbug
700 09fdca23 2010-09-25 pbug if (sreply->sr == NULL) {
701 09fdca23 2010-09-25 pbug switch (sd->ns_type) {
702 09fdca23 2010-09-25 pbug case 0:
703 09fdca23 2010-09-25 pbug SET_DNS_AUTHORITATIVE(odh);
704 09fdca23 2010-09-25 pbug break;
705 09fdca23 2010-09-25 pbug default:
706 09fdca23 2010-09-25 pbug SET_DNS_RECURSION(odh);
707 09fdca23 2010-09-25 pbug break;
708 09fdca23 2010-09-25 pbug }
709 09fdca23 2010-09-25 pbug } else
710 09fdca23 2010-09-25 pbug SET_DNS_RECURSION_AVAIL(odh);
711 b0a72376 2010-04-01 pbug
712 c45084ea 2005-11-29 pbug
713 c45084ea 2005-11-29 pbug HTONS(odh->query);
714 c45084ea 2005-11-29 pbug
715 5841985a 2010-03-18 pbug odh->question = htons(1);
716 b0a72376 2010-04-01 pbug switch (sd->ns_type) {
717 b0a72376 2010-04-01 pbug case NS_TYPE_DELEGATE:
718 5841985a 2010-03-18 pbug odh->answer = 0;
719 5841985a 2010-03-18 pbug odh->nsrr = htons(sd->ns_count);
720 b0a72376 2010-04-01 pbug break;
721 b0a72376 2010-04-01 pbug default:
722 b0a72376 2010-04-01 pbug odh->answer = htons(sd->ns_count);
723 b0a72376 2010-04-01 pbug odh->nsrr = 0;
724 b0a72376 2010-04-01 pbug break;
725 5841985a 2010-03-18 pbug }
726 c45084ea 2005-11-29 pbug odh->additional = 0;
727 c45084ea 2005-11-29 pbug
728 c45084ea 2005-11-29 pbug /* skip dns header, question name, qtype and qclass */
729 a042435d 2010-03-19 pbug answer = (struct answer *)(&reply[0] + sizeof(struct dns_header) +
730 c45084ea 2005-11-29 pbug q->hdr->namelen + 4);
731 c45084ea 2005-11-29 pbug
732 c45084ea 2005-11-29 pbug ns_count = 0;
733 33a0a60d 2009-11-03 pbug mod = sd->ns_count;
734 33a0a60d 2009-11-03 pbug pos = sd->ns_ptr;
735 33a0a60d 2009-11-03 pbug
736 c45084ea 2005-11-29 pbug do {
737 c45084ea 2005-11-29 pbug answer->name[0] = 0xc0;
738 c45084ea 2005-11-29 pbug answer->name[1] = 0x0c;
739 4cc84fc5 2010-03-19 pbug answer->type = htons(DNS_TYPE_NS);
740 c45084ea 2005-11-29 pbug answer->class = q->hdr->qclass;
741 09fdca23 2010-09-25 pbug if (sreply->sr != NULL)
742 09fdca23 2010-09-25 pbug answer->ttl = htonl(sd->ttl - (time(NULL) - sd->created));
743 09fdca23 2010-09-25 pbug else
744 09fdca23 2010-09-25 pbug answer->ttl = htonl(sd->ttl);
745 c45084ea 2005-11-29 pbug
746 f98bb34d 2011-09-19 pbug name = sd->ns[pos % mod].nsserver;
747 f98bb34d 2011-09-19 pbug namelen = sd->ns[pos % mod].nslen;
748 c45084ea 2005-11-29 pbug
749 a042435d 2010-03-19 pbug answer->rdlength = htons(namelen);
750 c45084ea 2005-11-29 pbug
751 a042435d 2010-03-19 pbug memcpy((char *)&answer->ns, (char *)name, namelen);
752 33a0a60d 2009-11-03 pbug
753 959d1769 2010-04-05 pbug sd0 = Lookup_zone(db, name, namelen, htons(DNS_TYPE_A), wildcard);
754 a042435d 2010-03-19 pbug if (sd0 != NULL) {
755 a042435d 2010-03-19 pbug cn1 = malloc(sizeof(struct collects));
756 a042435d 2010-03-19 pbug if (cn1 != NULL) {
757 a042435d 2010-03-19 pbug cn1->name = malloc(namelen);
758 a042435d 2010-03-19 pbug if (cn1->name != NULL) {
759 a042435d 2010-03-19 pbug memcpy(cn1->name, name, namelen);
760 a042435d 2010-03-19 pbug cn1->namelen = namelen;
761 a042435d 2010-03-19 pbug cn1->sd = sd0;
762 a042435d 2010-03-19 pbug cn1->type = DNS_TYPE_A;
763 a042435d 2010-03-19 pbug
764 c0963faf 2014-05-01 pjp SLIST_INSERT_HEAD(&collectshead, cn1, collect_entry);
765 a042435d 2010-03-19 pbug }
766 a042435d 2010-03-19 pbug }
767 a042435d 2010-03-19 pbug
768 a042435d 2010-03-19 pbug }
769 959d1769 2010-04-05 pbug sd0 = Lookup_zone(db, name, namelen, htons(DNS_TYPE_AAAA), wildcard);
770 a042435d 2010-03-19 pbug if (sd0 != NULL) {
771 a042435d 2010-03-19 pbug cn1 = malloc(sizeof(struct collects));
772 a042435d 2010-03-19 pbug if (cn1 != NULL) {
773 a042435d 2010-03-19 pbug cn1->name = malloc(namelen);
774 a042435d 2010-03-19 pbug if (cn1->name != NULL) {
775 a042435d 2010-03-19 pbug memcpy(cn1->name, name, namelen);
776 a042435d 2010-03-19 pbug cn1->namelen = namelen;
777 a042435d 2010-03-19 pbug cn1->sd = sd0;
778 a042435d 2010-03-19 pbug cn1->type = DNS_TYPE_AAAA;
779 a042435d 2010-03-19 pbug
780 c0963faf 2014-05-01 pjp SLIST_INSERT_HEAD(&collectshead, cn1, collect_entry);
781 a042435d 2010-03-19 pbug
782 a042435d 2010-03-19 pbug }
783 a042435d 2010-03-19 pbug }
784 a042435d 2010-03-19 pbug
785 a042435d 2010-03-19 pbug }
786 a042435d 2010-03-19 pbug
787 a042435d 2010-03-19 pbug outlen += (12 + namelen);
788 a042435d 2010-03-19 pbug
789 b0a72376 2010-04-01 pbug /* compress the label if possible */
790 c5bcfb5c 2010-07-27 pbug if ((tmplen = compress_label((u_char*)reply, outlen, namelen)) > 0) {
791 b0a72376 2010-04-01 pbug /* XXX */
792 b0a72376 2010-04-01 pbug outlen = tmplen;
793 b0a72376 2010-04-01 pbug }
794 a042435d 2010-03-19 pbug
795 b0a72376 2010-04-01 pbug answer->rdlength = htons(&reply[outlen] - &answer->ns);
796 b0a72376 2010-04-01 pbug
797 b0a72376 2010-04-01 pbug
798 c45084ea 2005-11-29 pbug /* can we afford to write another header? if no truncate */
799 1f1faf13 2014-05-11 pjp if (sd->ns_count > 1 && (outlen + 12 + sd->ns[pos % mod].nslen) > replysize) {
800 c45084ea 2005-11-29 pbug NTOHS(odh->query);
801 c45084ea 2005-11-29 pbug SET_DNS_TRUNCATION(odh);
802 c45084ea 2005-11-29 pbug HTONS(odh->query);
803 c45084ea 2005-11-29 pbug goto out;
804 c45084ea 2005-11-29 pbug }
805 c45084ea 2005-11-29 pbug
806 33a0a60d 2009-11-03 pbug pos++;
807 c45084ea 2005-11-29 pbug /* set new offset for answer */
808 c45084ea 2005-11-29 pbug answer = (struct answer *)&reply[outlen];
809 b0a72376 2010-04-01 pbug } while (++ns_count < RECORD_COUNT && --sd->ns_count);
810 a042435d 2010-03-19 pbug
811 a042435d 2010-03-19 pbug /* shuffle through our linked collect structure and add additional */
812 a042435d 2010-03-19 pbug
813 c0963faf 2014-05-01 pjp SLIST_FOREACH(cnp, &collectshead, collect_entry) {
814 a042435d 2010-03-19 pbug int addcount;
815 a042435d 2010-03-19 pbug int tmplen;
816 a042435d 2010-03-19 pbug
817 a042435d 2010-03-19 pbug switch (cnp->type) {
818 a042435d 2010-03-19 pbug case DNS_TYPE_A:
819 df34d218 2014-04-21 pjp tmplen = additional_a(cnp->name, cnp->namelen, cnp->sd, reply, replysize, outlen, &addcount);
820 a042435d 2010-03-19 pbug additional += addcount;
821 a042435d 2010-03-19 pbug break;
822 a042435d 2010-03-19 pbug case DNS_TYPE_AAAA:
823 df34d218 2014-04-21 pjp tmplen = additional_aaaa(cnp->name, cnp->namelen, cnp->sd, reply, replysize, outlen, &addcount);
824 a042435d 2010-03-19 pbug additional += addcount;
825 a042435d 2010-03-19 pbug break;
826 a042435d 2010-03-19 pbug }
827 a042435d 2010-03-19 pbug
828 a042435d 2010-03-19 pbug if (tmplen > 0) {
829 a042435d 2010-03-19 pbug outlen = tmplen;
830 a042435d 2010-03-19 pbug }
831 a042435d 2010-03-19 pbug }
832 c45084ea 2005-11-29 pbug
833 a042435d 2010-03-19 pbug odh->additional = htons(additional);
834 a042435d 2010-03-19 pbug
835 a042435d 2010-03-19 pbug while (!SLIST_EMPTY(&collectshead)) {
836 a042435d 2010-03-19 pbug cn1 = SLIST_FIRST(&collectshead);
837 c0963faf 2014-05-01 pjp SLIST_REMOVE_HEAD(&collectshead, collect_entry);
838 a042435d 2010-03-19 pbug free(cn1->name);
839 a042435d 2010-03-19 pbug free(cn1->sd);
840 a042435d 2010-03-19 pbug free(cn1);
841 a042435d 2010-03-19 pbug }
842 a042435d 2010-03-19 pbug
843 cd18f393 2014-05-10 pjp if (q->edns0len) {
844 cd18f393 2014-05-10 pjp /* tag on edns0 opt record */
845 cd18f393 2014-05-10 pjp NTOHS(odh->additional);
846 cd18f393 2014-05-10 pjp odh->additional++;
847 cd18f393 2014-05-10 pjp HTONS(odh->additional);
848 cd18f393 2014-05-10 pjp
849 cd18f393 2014-05-10 pjp outlen = additional_opt(q, reply, replysize, outlen);
850 cd18f393 2014-05-10 pjp }
851 cd18f393 2014-05-10 pjp
852 c45084ea 2005-11-29 pbug out:
853 09fdca23 2010-09-25 pbug if (sreply->sr != NULL) {
854 a2b189d4 2014-10-08 pjp retlen = reply_raw2(so, reply, outlen, sreply->sr);
855 09fdca23 2010-09-25 pbug } else {
856 09fdca23 2010-09-25 pbug if (istcp) {
857 09fdca23 2010-09-25 pbug char *tmpbuf;
858 a042435d 2010-03-19 pbug
859 09fdca23 2010-09-25 pbug tmpbuf = malloc(outlen + 2);
860 09fdca23 2010-09-25 pbug if (tmpbuf == NULL) {
861 dd869383 2013-02-16 pjp dolog(LOG_INFO, "malloc: %s\n", strerror(errno));
862 09fdca23 2010-09-25 pbug }
863 09fdca23 2010-09-25 pbug plen = (u_int16_t *)tmpbuf;
864 09fdca23 2010-09-25 pbug *plen = htons(outlen);
865 09fdca23 2010-09-25 pbug
866 09fdca23 2010-09-25 pbug memcpy(&tmpbuf[2], reply, outlen);
867 a2b189d4 2014-10-08 pjp if ((retlen = send(so, tmpbuf, outlen + 2, 0)) < 0) {
868 dd869383 2013-02-16 pjp dolog(LOG_INFO, "send: %s\n", strerror(errno));
869 09fdca23 2010-09-25 pbug }
870 09fdca23 2010-09-25 pbug free(tmpbuf);
871 09fdca23 2010-09-25 pbug } else {
872 a2b189d4 2014-10-08 pjp if ((retlen = sendto(so, reply, outlen, 0, sa, salen)) < 0) {
873 dd869383 2013-02-16 pjp dolog(LOG_INFO, "sendto: %s\n", strerror(errno));
874 09fdca23 2010-09-25 pbug }
875 f1e3cfca 2010-03-12 pbug }
876 c45084ea 2005-11-29 pbug }
877 33a0a60d 2009-11-03 pbug
878 33a0a60d 2009-11-03 pbug sd->ns_ptr = (sd->ns_ptr + 1) % mod;
879 33a0a60d 2009-11-03 pbug sd->ns_count = mod;
880 33a0a60d 2009-11-03 pbug
881 33a0a60d 2009-11-03 pbug update_db(db, sd);
882 c45084ea 2005-11-29 pbug
883 a2b189d4 2014-10-08 pjp return (retlen);
884 c45084ea 2005-11-29 pbug }
885 c45084ea 2005-11-29 pbug
886 c45084ea 2005-11-29 pbug
887 c45084ea 2005-11-29 pbug /*
888 c45084ea 2005-11-29 pbug * REPLY_CNAME() - replies a DNS question (*q) on socket (so)
889 c45084ea 2005-11-29 pbug *
890 c45084ea 2005-11-29 pbug */
891 c45084ea 2005-11-29 pbug
892 c45084ea 2005-11-29 pbug
893 a2b189d4 2014-10-08 pjp int
894 c45084ea 2005-11-29 pbug reply_cname(struct sreply *sreply)
895 c45084ea 2005-11-29 pbug {
896 df34d218 2014-04-21 pjp char *reply = sreply->replybuf;
897 c45084ea 2005-11-29 pbug struct dns_header *odh;
898 b6dc64dc 2010-04-15 pbug u_int16_t outlen;
899 c45084ea 2005-11-29 pbug char *p;
900 c45084ea 2005-11-29 pbug int i, tmplen;
901 c45084ea 2005-11-29 pbug int labellen;
902 c45084ea 2005-11-29 pbug char *label, *plabel;
903 c45084ea 2005-11-29 pbug int addcount;
904 f1e3cfca 2010-03-12 pbug u_int16_t *plen;
905 c45084ea 2005-11-29 pbug
906 c45084ea 2005-11-29 pbug struct answer {
907 c45084ea 2005-11-29 pbug char name[2];
908 c45084ea 2005-11-29 pbug u_int16_t type;
909 c45084ea 2005-11-29 pbug u_int16_t class;
910 c45084ea 2005-11-29 pbug u_int32_t ttl;
911 c45084ea 2005-11-29 pbug u_int16_t rdlength; /* 12 */
912 c45084ea 2005-11-29 pbug char rdata;
913 c45084ea 2005-11-29 pbug } __attribute__((packed));
914 c45084ea 2005-11-29 pbug
915 c45084ea 2005-11-29 pbug struct answer *answer;
916 c45084ea 2005-11-29 pbug
917 c45084ea 2005-11-29 pbug int so = sreply->so;
918 c45084ea 2005-11-29 pbug char *buf = sreply->buf;
919 c45084ea 2005-11-29 pbug int len = sreply->len;
920 c45084ea 2005-11-29 pbug struct question *q = sreply->q;
921 c45084ea 2005-11-29 pbug struct sockaddr *sa = sreply->sa;
922 c45084ea 2005-11-29 pbug int salen = sreply->salen;
923 c45084ea 2005-11-29 pbug struct domain *sd = sreply->sd1;
924 c45084ea 2005-11-29 pbug struct domain *sd1 = sreply->sd2;
925 f1e3cfca 2010-03-12 pbug int istcp = sreply->istcp;
926 df34d218 2014-04-21 pjp int replysize = 512;
927 a2b189d4 2014-10-08 pjp int retlen = -1;
928 c45084ea 2005-11-29 pbug
929 df34d218 2014-04-21 pjp if (istcp) {
930 df34d218 2014-04-21 pjp replysize = 65535;
931 df34d218 2014-04-21 pjp }
932 cd18f393 2014-05-10 pjp
933 cd18f393 2014-05-10 pjp if (q->edns0len > 512)
934 cd18f393 2014-05-10 pjp replysize = q->edns0len;
935 df34d218 2014-04-21 pjp
936 c45084ea 2005-11-29 pbug odh = (struct dns_header *)&reply[0];
937 c45084ea 2005-11-29 pbug outlen = sizeof(struct dns_header);
938 c45084ea 2005-11-29 pbug
939 df34d218 2014-04-21 pjp if (len > replysize) {
940 a2b189d4 2014-10-08 pjp return (retlen);
941 c45084ea 2005-11-29 pbug }
942 c45084ea 2005-11-29 pbug
943 c45084ea 2005-11-29 pbug /* copy question to reply */
944 df34d218 2014-04-21 pjp memcpy(reply, buf, sizeof(struct dns_header) + q->hdr->namelen + 4);
945 f1e3cfca 2010-03-12 pbug
946 c45084ea 2005-11-29 pbug /* blank query */
947 c45084ea 2005-11-29 pbug memset((char *)&odh->query, 0, sizeof(u_int16_t));
948 c45084ea 2005-11-29 pbug
949 c45084ea 2005-11-29 pbug outlen += (q->hdr->namelen + 4);
950 c45084ea 2005-11-29 pbug
951 c45084ea 2005-11-29 pbug SET_DNS_REPLY(odh);
952 b55adb0c 2010-09-26 pbug if (sreply->sr == NULL)
953 b55adb0c 2010-09-26 pbug SET_DNS_AUTHORITATIVE(odh);
954 b55adb0c 2010-09-26 pbug else
955 b55adb0c 2010-09-26 pbug SET_DNS_RECURSION_AVAIL(odh);
956 c45084ea 2005-11-29 pbug
957 c45084ea 2005-11-29 pbug HTONS(odh->query);
958 c45084ea 2005-11-29 pbug
959 c45084ea 2005-11-29 pbug odh->question = htons(1);
960 c45084ea 2005-11-29 pbug odh->answer = htons(1);
961 c45084ea 2005-11-29 pbug odh->nsrr = 0;
962 c45084ea 2005-11-29 pbug odh->additional = 0;
963 c45084ea 2005-11-29 pbug
964 c45084ea 2005-11-29 pbug answer = (struct answer *)(&reply[0] + sizeof(struct dns_header) +
965 c45084ea 2005-11-29 pbug q->hdr->namelen + 4);
966 c45084ea 2005-11-29 pbug
967 c45084ea 2005-11-29 pbug answer->name[0] = 0xc0;
968 c45084ea 2005-11-29 pbug answer->name[1] = 0x0c;
969 5841985a 2010-03-18 pbug answer->type = htons(DNS_TYPE_CNAME);
970 c45084ea 2005-11-29 pbug answer->class = q->hdr->qclass;
971 b55adb0c 2010-09-26 pbug if (sreply->sr != NULL)
972 b55adb0c 2010-09-26 pbug answer->ttl = htonl(sd->ttl - (time(NULL) - sd->created));
973 b55adb0c 2010-09-26 pbug else
974 b55adb0c 2010-09-26 pbug answer->ttl = htonl(sd->ttl);
975 c45084ea 2005-11-29 pbug
976 c45084ea 2005-11-29 pbug outlen += 12; /* up to rdata length */
977 c45084ea 2005-11-29 pbug
978 c45084ea 2005-11-29 pbug p = (char *)&answer->rdata;
979 c45084ea 2005-11-29 pbug
980 c45084ea 2005-11-29 pbug label = &sd->cname[0];
981 c45084ea 2005-11-29 pbug labellen = sd->cnamelen;
982 c45084ea 2005-11-29 pbug
983 c45084ea 2005-11-29 pbug plabel = label;
984 c45084ea 2005-11-29 pbug
985 c45084ea 2005-11-29 pbug /* copy label to reply */
986 df34d218 2014-04-21 pjp for (i = outlen; i < replysize; i++) {
987 c45084ea 2005-11-29 pbug if (i - outlen == labellen)
988 c45084ea 2005-11-29 pbug break;
989 c45084ea 2005-11-29 pbug
990 c45084ea 2005-11-29 pbug reply[i] = *plabel++;
991 c45084ea 2005-11-29 pbug }
992 c45084ea 2005-11-29 pbug
993 df34d218 2014-04-21 pjp if (i >= replysize)
994 a2b189d4 2014-10-08 pjp return (retlen);
995 c45084ea 2005-11-29 pbug
996 c45084ea 2005-11-29 pbug outlen = i;
997 c45084ea 2005-11-29 pbug
998 c45084ea 2005-11-29 pbug /* compress the label if possible */
999 c5bcfb5c 2010-07-27 pbug if ((tmplen = compress_label((u_char*)reply, outlen, labellen)) > 0) {
1000 c45084ea 2005-11-29 pbug /* XXX */
1001 c45084ea 2005-11-29 pbug outlen = tmplen;
1002 c45084ea 2005-11-29 pbug }
1003 c45084ea 2005-11-29 pbug
1004 c45084ea 2005-11-29 pbug answer->rdlength = htons(&reply[outlen] - &answer->rdata);
1005 c45084ea 2005-11-29 pbug
1006 f1e3cfca 2010-03-12 pbug
1007 c45084ea 2005-11-29 pbug if (ntohs(q->hdr->qtype) == DNS_TYPE_A && sd1 != NULL) {
1008 df34d218 2014-04-21 pjp tmplen = additional_a(sd->cname, sd->cnamelen, sd1, reply, replysize, outlen, &addcount);
1009 f1e3cfca 2010-03-12 pbug
1010 c45084ea 2005-11-29 pbug if (tmplen > 0)
1011 c45084ea 2005-11-29 pbug outlen = tmplen;
1012 c45084ea 2005-11-29 pbug
1013 c45084ea 2005-11-29 pbug NTOHS(odh->answer);
1014 c45084ea 2005-11-29 pbug odh->answer += addcount;
1015 c45084ea 2005-11-29 pbug HTONS(odh->answer);
1016 c45084ea 2005-11-29 pbug } else if (ntohs(q->hdr->qtype) == DNS_TYPE_AAAA && sd1 != NULL) {
1017 df34d218 2014-04-21 pjp tmplen = additional_aaaa(sd->cname, sd->cnamelen, sd1, reply, replysize, outlen, &addcount);
1018 f1e3cfca 2010-03-12 pbug
1019 c45084ea 2005-11-29 pbug if (tmplen > 0)
1020 c45084ea 2005-11-29 pbug outlen = tmplen;
1021 c45084ea 2005-11-29 pbug
1022 c45084ea 2005-11-29 pbug NTOHS(odh->answer);
1023 c45084ea 2005-11-29 pbug odh->answer += addcount;
1024 c45084ea 2005-11-29 pbug HTONS(odh->answer);
1025 c45084ea 2005-11-29 pbug } else if (ntohs(q->hdr->qtype) == DNS_TYPE_MX && sd1 != NULL) {
1026 df34d218 2014-04-21 pjp tmplen = additional_mx(sd->cname, sd->cnamelen, sd1, reply, replysize, outlen, &addcount);
1027 f1e3cfca 2010-03-12 pbug
1028 c45084ea 2005-11-29 pbug if (tmplen > 0)
1029 c45084ea 2005-11-29 pbug outlen = tmplen;
1030 c45084ea 2005-11-29 pbug
1031 c45084ea 2005-11-29 pbug NTOHS(odh->answer);
1032 c45084ea 2005-11-29 pbug odh->answer += addcount;
1033 c45084ea 2005-11-29 pbug HTONS(odh->answer);
1034 c45084ea 2005-11-29 pbug } else if (ntohs(q->hdr->qtype) == DNS_TYPE_PTR && sd1 != NULL) {
1035 df34d218 2014-04-21 pjp tmplen = additional_ptr(sd->cname, sd->cnamelen, sd1, reply, replysize, outlen, &addcount);
1036 f1e3cfca 2010-03-12 pbug
1037 c45084ea 2005-11-29 pbug if (tmplen > 0)
1038 c45084ea 2005-11-29 pbug outlen = tmplen;
1039 c45084ea 2005-11-29 pbug
1040 c45084ea 2005-11-29 pbug NTOHS(odh->answer);
1041 c45084ea 2005-11-29 pbug odh->answer += addcount;
1042 c45084ea 2005-11-29 pbug HTONS(odh->answer);
1043 c45084ea 2005-11-29 pbug }
1044 f1e3cfca 2010-03-12 pbug
1045 cd18f393 2014-05-10 pjp if (q->edns0len) {
1046 cd18f393 2014-05-10 pjp /* tag on edns0 opt record */
1047 cd18f393 2014-05-10 pjp NTOHS(odh->additional);
1048 cd18f393 2014-05-10 pjp odh->additional++;
1049 cd18f393 2014-05-10 pjp HTONS(odh->additional);
1050 cd18f393 2014-05-10 pjp
1051 cd18f393 2014-05-10 pjp outlen = additional_opt(q, reply, replysize, outlen);
1052 cd18f393 2014-05-10 pjp }
1053 cd18f393 2014-05-10 pjp
1054 b55adb0c 2010-09-26 pbug if (sreply->sr != NULL) {
1055 a2b189d4 2014-10-08 pjp retlen = reply_raw2(so, reply, outlen, sreply->sr);
1056 b55adb0c 2010-09-26 pbug } else {
1057 b55adb0c 2010-09-26 pbug if (istcp) {
1058 b55adb0c 2010-09-26 pbug char *tmpbuf;
1059 f1e3cfca 2010-03-12 pbug
1060 b55adb0c 2010-09-26 pbug tmpbuf = malloc(outlen + 2);
1061 b55adb0c 2010-09-26 pbug if (tmpbuf == NULL) {
1062 dd869383 2013-02-16 pjp dolog(LOG_INFO, "malloc: %s\n", strerror(errno));
1063 b55adb0c 2010-09-26 pbug }
1064 b55adb0c 2010-09-26 pbug plen = (u_int16_t *)tmpbuf;
1065 b55adb0c 2010-09-26 pbug *plen = htons(outlen);
1066 b55adb0c 2010-09-26 pbug
1067 b55adb0c 2010-09-26 pbug memcpy(&tmpbuf[2], reply, outlen);
1068 f1e3cfca 2010-03-12 pbug
1069 a2b189d4 2014-10-08 pjp if ((retlen = send(so, tmpbuf, outlen + 2, 0)) < 0) {
1070 dd869383 2013-02-16 pjp dolog(LOG_INFO, "send: %s\n", strerror(errno));
1071 b55adb0c 2010-09-26 pbug }
1072 b55adb0c 2010-09-26 pbug free(tmpbuf);
1073 b55adb0c 2010-09-26 pbug } else {
1074 a2b189d4 2014-10-08 pjp if ((retlen = sendto(so, reply, outlen, 0, sa, salen)) < 0) {
1075 dd869383 2013-02-16 pjp dolog(LOG_INFO, "sendto: %s\n", strerror(errno));
1076 b55adb0c 2010-09-26 pbug }
1077 f1e3cfca 2010-03-12 pbug }
1078 c45084ea 2005-11-29 pbug }
1079 c45084ea 2005-11-29 pbug
1080 a2b189d4 2014-10-08 pjp return (retlen);
1081 c45084ea 2005-11-29 pbug }
1082 c45084ea 2005-11-29 pbug
1083 c45084ea 2005-11-29 pbug /*
1084 c45084ea 2005-11-29 pbug * REPLY_PTR() - replies a DNS question (*q) on socket (so)
1085 c45084ea 2005-11-29 pbug *
1086 c45084ea 2005-11-29 pbug */
1087 c45084ea 2005-11-29 pbug
1088 a2b189d4 2014-10-08 pjp int
1089 c45084ea 2005-11-29 pbug reply_ptr(struct sreply *sreply)
1090 c45084ea 2005-11-29 pbug {
1091 df34d218 2014-04-21 pjp char *reply = sreply->replybuf;
1092 c45084ea 2005-11-29 pbug struct dns_header *odh;
1093 b6dc64dc 2010-04-15 pbug u_int16_t outlen;
1094 c45084ea 2005-11-29 pbug char *p;
1095 c45084ea 2005-11-29 pbug int i, tmplen;
1096 c45084ea 2005-11-29 pbug int labellen;
1097 c45084ea 2005-11-29 pbug char *label, *plabel;
1098 c45084ea 2005-11-29 pbug
1099 c45084ea 2005-11-29 pbug struct answer {
1100 c45084ea 2005-11-29 pbug char name[2];
1101 c45084ea 2005-11-29 pbug u_int16_t type;
1102 c45084ea 2005-11-29 pbug u_int16_t class;
1103 c45084ea 2005-11-29 pbug u_int32_t ttl;
1104 c45084ea 2005-11-29 pbug u_int16_t rdlength; /* 12 */
1105 c45084ea 2005-11-29 pbug char rdata;
1106 c45084ea 2005-11-29 pbug } __attribute__((packed));
1107 c45084ea 2005-11-29 pbug
1108 c45084ea 2005-11-29 pbug struct answer *answer;
1109 c45084ea 2005-11-29 pbug
1110 c45084ea 2005-11-29 pbug int so = sreply->so;
1111 c45084ea 2005-11-29 pbug char *buf = sreply->buf;
1112 c45084ea 2005-11-29 pbug int len = sreply->len;
1113 c45084ea 2005-11-29 pbug struct question *q = sreply->q;
1114 c45084ea 2005-11-29 pbug struct sockaddr *sa = sreply->sa;
1115 c45084ea 2005-11-29 pbug int salen = sreply->salen;
1116 c45084ea 2005-11-29 pbug struct domain *sd = sreply->sd1;
1117 f1e3cfca 2010-03-12 pbug int istcp = sreply->istcp;
1118 df34d218 2014-04-21 pjp int replysize = 512;
1119 a2b189d4 2014-10-08 pjp int retlen = -1;
1120 df34d218 2014-04-21 pjp
1121 df34d218 2014-04-21 pjp if (istcp) {
1122 df34d218 2014-04-21 pjp replysize = 65535;
1123 df34d218 2014-04-21 pjp }
1124 cd18f393 2014-05-10 pjp
1125 cd18f393 2014-05-10 pjp if (q->edns0len > 512)
1126 cd18f393 2014-05-10 pjp replysize = q->edns0len;
1127 c45084ea 2005-11-29 pbug
1128 c45084ea 2005-11-29 pbug odh = (struct dns_header *)&reply[0];
1129 c45084ea 2005-11-29 pbug outlen = sizeof(struct dns_header);
1130 c45084ea 2005-11-29 pbug
1131 c45084ea 2005-11-29 pbug
1132 df34d218 2014-04-21 pjp if (len > replysize) {
1133 a2b189d4 2014-10-08 pjp return (retlen);
1134 c45084ea 2005-11-29 pbug }
1135 c45084ea 2005-11-29 pbug
1136 c45084ea 2005-11-29 pbug /* copy question to reply */
1137 df34d218 2014-04-21 pjp memcpy(reply, buf, sizeof(struct dns_header) + q->hdr->namelen + 4);
1138 c45084ea 2005-11-29 pbug /* blank query */
1139 c45084ea 2005-11-29 pbug memset((char *)&odh->query, 0, sizeof(u_int16_t));
1140 c45084ea 2005-11-29 pbug
1141 c45084ea 2005-11-29 pbug outlen += (q->hdr->namelen + 4);
1142 c45084ea 2005-11-29 pbug
1143 c45084ea 2005-11-29 pbug SET_DNS_REPLY(odh);
1144 3553d5f3 2010-09-26 pbug if (sreply->sr == NULL)
1145 3553d5f3 2010-09-26 pbug SET_DNS_AUTHORITATIVE(odh);
1146 3553d5f3 2010-09-26 pbug else
1147 3553d5f3 2010-09-26 pbug SET_DNS_RECURSION_AVAIL(odh);
1148 c45084ea 2005-11-29 pbug
1149 c45084ea 2005-11-29 pbug HTONS(odh->query);
1150 c45084ea 2005-11-29 pbug
1151 5841985a 2010-03-18 pbug odh->question = htons(1);
1152 5841985a 2010-03-18 pbug odh->answer = htons(1);
1153 c45084ea 2005-11-29 pbug odh->nsrr = 0;
1154 c45084ea 2005-11-29 pbug odh->additional = 0;
1155 c45084ea 2005-11-29 pbug
1156 c45084ea 2005-11-29 pbug answer = (struct answer *)(&reply[0] + sizeof(struct dns_header) +
1157 c45084ea 2005-11-29 pbug q->hdr->namelen + 4);
1158 c45084ea 2005-11-29 pbug
1159 c45084ea 2005-11-29 pbug answer->name[0] = 0xc0;
1160 c45084ea 2005-11-29 pbug answer->name[1] = 0x0c;
1161 c45084ea 2005-11-29 pbug answer->type = q->hdr->qtype;
1162 c45084ea 2005-11-29 pbug answer->class = q->hdr->qclass;
1163 3553d5f3 2010-09-26 pbug if (sreply->sr != NULL)
1164 3553d5f3 2010-09-26 pbug answer->ttl = htonl(sd->ttl - (time(NULL) - sd->created));
1165 3553d5f3 2010-09-26 pbug else
1166 3553d5f3 2010-09-26 pbug answer->ttl = htonl(sd->ttl);
1167 c45084ea 2005-11-29 pbug
1168 c45084ea 2005-11-29 pbug outlen += 12; /* up to rdata length */
1169 c45084ea 2005-11-29 pbug
1170 c45084ea 2005-11-29 pbug p = (char *)&answer->rdata;
1171 c45084ea 2005-11-29 pbug
1172 c45084ea 2005-11-29 pbug label = &sd->ptr[0];
1173 c45084ea 2005-11-29 pbug labellen = sd->ptrlen;
1174 c45084ea 2005-11-29 pbug
1175 c45084ea 2005-11-29 pbug plabel = label;
1176 c45084ea 2005-11-29 pbug
1177 c45084ea 2005-11-29 pbug /* copy label to reply */
1178 df34d218 2014-04-21 pjp for (i = outlen; i < replysize; i++) {
1179 c45084ea 2005-11-29 pbug if (i - outlen == labellen)
1180 c45084ea 2005-11-29 pbug break;
1181 c45084ea 2005-11-29 pbug
1182 c45084ea 2005-11-29 pbug reply[i] = *plabel++;
1183 c45084ea 2005-11-29 pbug }
1184 c45084ea 2005-11-29 pbug
1185 df34d218 2014-04-21 pjp if (i >= replysize) {
1186 a2b189d4 2014-10-08 pjp return (retlen);
1187 c45084ea 2005-11-29 pbug }
1188 c45084ea 2005-11-29 pbug
1189 c45084ea 2005-11-29 pbug outlen = i;
1190 c45084ea 2005-11-29 pbug
1191 c45084ea 2005-11-29 pbug /* compress the label if possible */
1192 c5bcfb5c 2010-07-27 pbug if ((tmplen = compress_label((u_char*)reply, outlen, labellen)) > 0) {
1193 c45084ea 2005-11-29 pbug outlen = tmplen;
1194 c45084ea 2005-11-29 pbug }
1195 c45084ea 2005-11-29 pbug
1196 c45084ea 2005-11-29 pbug answer->rdlength = htons(&reply[outlen] - &answer->rdata);
1197 cd18f393 2014-05-10 pjp
1198 cd18f393 2014-05-10 pjp if (q->edns0len) {
1199 cd18f393 2014-05-10 pjp /* tag on edns0 opt record */
1200 cd18f393 2014-05-10 pjp NTOHS(odh->additional);
1201 cd18f393 2014-05-10 pjp odh->additional++;
1202 cd18f393 2014-05-10 pjp HTONS(odh->additional);
1203 cd18f393 2014-05-10 pjp
1204 cd18f393 2014-05-10 pjp outlen = additional_opt(q, reply, replysize, outlen);
1205 cd18f393 2014-05-10 pjp }
1206 c45084ea 2005-11-29 pbug
1207 3553d5f3 2010-09-26 pbug if (sreply->sr != NULL) {
1208 a2b189d4 2014-10-08 pjp retlen = reply_raw2(so, reply, outlen, sreply->sr);
1209 3553d5f3 2010-09-26 pbug } else {
1210 3553d5f3 2010-09-26 pbug if (istcp) {
1211 3553d5f3 2010-09-26 pbug char *tmpbuf;
1212 3553d5f3 2010-09-26 pbug u_int16_t *plen;
1213 f1e3cfca 2010-03-12 pbug
1214 3553d5f3 2010-09-26 pbug tmpbuf = malloc(outlen + 2);
1215 3553d5f3 2010-09-26 pbug if (tmpbuf == NULL) {
1216 dd869383 2013-02-16 pjp dolog(LOG_INFO, "malloc: %s\n", strerror(errno));
1217 3553d5f3 2010-09-26 pbug }
1218 3553d5f3 2010-09-26 pbug plen = (u_int16_t *)tmpbuf;
1219 3553d5f3 2010-09-26 pbug *plen = htons(outlen);
1220 3553d5f3 2010-09-26 pbug
1221 3553d5f3 2010-09-26 pbug memcpy(&tmpbuf[2], reply, outlen);
1222 3553d5f3 2010-09-26 pbug
1223 a2b189d4 2014-10-08 pjp if ((retlen = send(so, tmpbuf, outlen + 2, 0)) < 0) {
1224 dd869383 2013-02-16 pjp dolog(LOG_INFO, "send: %s\n", strerror(errno));
1225 3553d5f3 2010-09-26 pbug }
1226 3553d5f3 2010-09-26 pbug free(tmpbuf);
1227 3553d5f3 2010-09-26 pbug } else {
1228 a2b189d4 2014-10-08 pjp if ((retlen = sendto(so, reply, outlen, 0, sa, salen)) < 0) {
1229 dd869383 2013-02-16 pjp dolog(LOG_INFO, "sendto: %s\n", strerror(errno));
1230 3553d5f3 2010-09-26 pbug }
1231 f1e3cfca 2010-03-12 pbug }
1232 c45084ea 2005-11-29 pbug }
1233 c45084ea 2005-11-29 pbug
1234 a2b189d4 2014-10-08 pjp return (retlen);
1235 c45084ea 2005-11-29 pbug }
1236 c45084ea 2005-11-29 pbug
1237 c45084ea 2005-11-29 pbug /*
1238 c45084ea 2005-11-29 pbug * REPLY_SOA() - replies a DNS question (*q) on socket (so)
1239 c45084ea 2005-11-29 pbug *
1240 c45084ea 2005-11-29 pbug */
1241 c45084ea 2005-11-29 pbug
1242 c45084ea 2005-11-29 pbug
1243 a2b189d4 2014-10-08 pjp int
1244 c45084ea 2005-11-29 pbug reply_soa(struct sreply *sreply)
1245 c45084ea 2005-11-29 pbug {
1246 df34d218 2014-04-21 pjp char *reply = sreply->replybuf;
1247 c45084ea 2005-11-29 pbug struct dns_header *odh;
1248 b6dc64dc 2010-04-15 pbug u_int16_t outlen;
1249 c45084ea 2005-11-29 pbug char *p;
1250 c45084ea 2005-11-29 pbug u_int32_t *soa_val;
1251 c45084ea 2005-11-29 pbug int i, tmplen;
1252 c45084ea 2005-11-29 pbug int labellen;
1253 c45084ea 2005-11-29 pbug char *label, *plabel;
1254 c45084ea 2005-11-29 pbug
1255 c45084ea 2005-11-29 pbug struct answer {
1256 c45084ea 2005-11-29 pbug char name[2];
1257 c45084ea 2005-11-29 pbug u_int16_t type;
1258 c45084ea 2005-11-29 pbug u_int16_t class;
1259 c45084ea 2005-11-29 pbug u_int32_t ttl;
1260 c45084ea 2005-11-29 pbug u_int16_t rdlength; /* 12 */
1261 c45084ea 2005-11-29 pbug char rdata;
1262 c45084ea 2005-11-29 pbug } __attribute__((packed));
1263 c45084ea 2005-11-29 pbug
1264 c45084ea 2005-11-29 pbug struct soa {
1265 c45084ea 2005-11-29 pbug char *nsserver;
1266 c45084ea 2005-11-29 pbug char *responsible_person;
1267 c45084ea 2005-11-29 pbug u_int32_t serial;
1268 c45084ea 2005-11-29 pbug u_int32_t refresh;
1269 c45084ea 2005-11-29 pbug u_int32_t retry;
1270 c45084ea 2005-11-29 pbug u_int32_t expire;
1271 c45084ea 2005-11-29 pbug u_int32_t minttl;
1272 c45084ea 2005-11-29 pbug };
1273 c45084ea 2005-11-29 pbug
1274 c45084ea 2005-11-29 pbug
1275 c45084ea 2005-11-29 pbug struct answer *answer;
1276 c45084ea 2005-11-29 pbug
1277 c45084ea 2005-11-29 pbug int so = sreply->so;
1278 c45084ea 2005-11-29 pbug char *buf = sreply->buf;
1279 c45084ea 2005-11-29 pbug int len = sreply->len;
1280 c45084ea 2005-11-29 pbug struct question *q = sreply->q;
1281 c45084ea 2005-11-29 pbug struct sockaddr *sa = sreply->sa;
1282 c45084ea 2005-11-29 pbug int salen = sreply->salen;
1283 c45084ea 2005-11-29 pbug struct domain *sd = sreply->sd1;
1284 f1e3cfca 2010-03-12 pbug int istcp = sreply->istcp;
1285 df34d218 2014-04-21 pjp int replysize = 512;
1286 a2b189d4 2014-10-08 pjp int retlen = -1;
1287 df34d218 2014-04-21 pjp
1288 df34d218 2014-04-21 pjp if (istcp) {
1289 df34d218 2014-04-21 pjp replysize = 65535;
1290 df34d218 2014-04-21 pjp }
1291 cd18f393 2014-05-10 pjp
1292 cd18f393 2014-05-10 pjp if (q->edns0len > 512)
1293 cd18f393 2014-05-10 pjp replysize = q->edns0len;
1294 c45084ea 2005-11-29 pbug
1295 1a591502 2010-03-28 pbug /* st */
1296 c45084ea 2005-11-29 pbug
1297 c45084ea 2005-11-29 pbug odh = (struct dns_header *)&reply[0];
1298 c45084ea 2005-11-29 pbug outlen = sizeof(struct dns_header);
1299 c45084ea 2005-11-29 pbug
1300 df34d218 2014-04-21 pjp if (len > replysize) {
1301 a2b189d4 2014-10-08 pjp return (retlen);
1302 c45084ea 2005-11-29 pbug }
1303 c45084ea 2005-11-29 pbug
1304 c45084ea 2005-11-29 pbug /* copy question to reply */
1305 df34d218 2014-04-21 pjp memcpy(reply, buf, sizeof(struct dns_header) + q->hdr->namelen + 4);
1306 c45084ea 2005-11-29 pbug /* blank query */
1307 c45084ea 2005-11-29 pbug memset((char *)&odh->query, 0, sizeof(u_int16_t));
1308 c45084ea 2005-11-29 pbug
1309 c45084ea 2005-11-29 pbug outlen += (q->hdr->namelen + 4);
1310 c45084ea 2005-11-29 pbug
1311 c45084ea 2005-11-29 pbug SET_DNS_REPLY(odh);
1312 b55adb0c 2010-09-26 pbug if (sreply->sr == NULL)
1313 b55adb0c 2010-09-26 pbug SET_DNS_AUTHORITATIVE(odh);
1314 b55adb0c 2010-09-26 pbug else
1315 b55adb0c 2010-09-26 pbug SET_DNS_RECURSION_AVAIL(odh);
1316 c45084ea 2005-11-29 pbug
1317 c45084ea 2005-11-29 pbug NTOHS(odh->query);
1318 c45084ea 2005-11-29 pbug
1319 5841985a 2010-03-18 pbug odh->question = htons(1);
1320 5841985a 2010-03-18 pbug odh->answer = htons(1);
1321 c45084ea 2005-11-29 pbug odh->nsrr = 0;
1322 c45084ea 2005-11-29 pbug odh->additional = 0;
1323 c45084ea 2005-11-29 pbug
1324 c45084ea 2005-11-29 pbug answer = (struct answer *)(&reply[0] + sizeof(struct dns_header) +
1325 c45084ea 2005-11-29 pbug q->hdr->namelen + 4);
1326 c45084ea 2005-11-29 pbug
1327 c45084ea 2005-11-29 pbug answer->name[0] = 0xc0;
1328 c45084ea 2005-11-29 pbug answer->name[1] = 0x0c;
1329 c45084ea 2005-11-29 pbug answer->type = q->hdr->qtype;
1330 c45084ea 2005-11-29 pbug answer->class = q->hdr->qclass;
1331 b55adb0c 2010-09-26 pbug if (sreply->sr != NULL)
1332 b55adb0c 2010-09-26 pbug answer->ttl = htonl(sd->ttl - (time(NULL) - sd->created));
1333 b55adb0c 2010-09-26 pbug else
1334 b55adb0c 2010-09-26 pbug answer->ttl = htonl(sd->ttl);
1335 c45084ea 2005-11-29 pbug
1336 c45084ea 2005-11-29 pbug outlen += 12; /* up to rdata length */
1337 c45084ea 2005-11-29 pbug
1338 c45084ea 2005-11-29 pbug p = (char *)&answer->rdata;
1339 c45084ea 2005-11-29 pbug
1340 c45084ea 2005-11-29 pbug
1341 f98bb34d 2011-09-19 pbug label = sd->soa.nsserver;
1342 f98bb34d 2011-09-19 pbug labellen = sd->soa.nsserver_len;
1343 c45084ea 2005-11-29 pbug
1344 c45084ea 2005-11-29 pbug plabel = label;
1345 c45084ea 2005-11-29 pbug
1346 c45084ea 2005-11-29 pbug /* copy label to reply */
1347 df34d218 2014-04-21 pjp for (i = outlen; i < replysize; i++) {
1348 c45084ea 2005-11-29 pbug if (i - outlen == labellen)
1349 c45084ea 2005-11-29 pbug break;
1350 c45084ea 2005-11-29 pbug
1351 c45084ea 2005-11-29 pbug reply[i] = *plabel++;
1352 c45084ea 2005-11-29 pbug }
1353 c45084ea 2005-11-29 pbug
1354 df34d218 2014-04-21 pjp if (i >= replysize) {
1355 a2b189d4 2014-10-08 pjp return (retlen);
1356 c45084ea 2005-11-29 pbug }
1357 c45084ea 2005-11-29 pbug
1358 c45084ea 2005-11-29 pbug outlen = i;
1359 c45084ea 2005-11-29 pbug
1360 c45084ea 2005-11-29 pbug /* compress the label if possible */
1361 c5bcfb5c 2010-07-27 pbug if ((tmplen = compress_label((u_char*)reply, outlen, labellen)) > 0) {
1362 c45084ea 2005-11-29 pbug outlen = tmplen;
1363 c45084ea 2005-11-29 pbug }
1364 c45084ea 2005-11-29 pbug
1365 f98bb34d 2011-09-19 pbug label = sd->soa.responsible_person;
1366 f98bb34d 2011-09-19 pbug labellen = sd->soa.rp_len;
1367 c45084ea 2005-11-29 pbug plabel = label;
1368 c45084ea 2005-11-29 pbug
1369 df34d218 2014-04-21 pjp for (i = outlen; i < replysize; i++) {
1370 c45084ea 2005-11-29 pbug if (i - outlen == labellen)
1371 c45084ea 2005-11-29 pbug break;
1372 c45084ea 2005-11-29 pbug
1373 c45084ea 2005-11-29 pbug reply[i] = *plabel++;
1374 c45084ea 2005-11-29 pbug }
1375 c45084ea 2005-11-29 pbug
1376 df34d218 2014-04-21 pjp if (i >= replysize) {
1377 a2b189d4 2014-10-08 pjp return (retlen);
1378 c45084ea 2005-11-29 pbug }
1379 c45084ea 2005-11-29 pbug
1380 c45084ea 2005-11-29 pbug outlen = i;
1381 c45084ea 2005-11-29 pbug
1382 c45084ea 2005-11-29 pbug /* 2 compress the label if possible */
1383 c45084ea 2005-11-29 pbug
1384 c5bcfb5c 2010-07-27 pbug if ((tmplen = compress_label((u_char*)reply, outlen, labellen)) > 0) {
1385 c45084ea 2005-11-29 pbug outlen = tmplen;
1386 c45084ea 2005-11-29 pbug }
1387 c45084ea 2005-11-29 pbug
1388 c45084ea 2005-11-29 pbug
1389 1a591502 2010-03-28 pbug /* XXX */
1390 df34d218 2014-04-21 pjp if ((outlen + sizeof(sd->soa.serial)) > replysize) {
1391 c45084ea 2005-11-29 pbug /* XXX server error reply? */
1392 a2b189d4 2014-10-08 pjp return (retlen);
1393 c45084ea 2005-11-29 pbug }
1394 c45084ea 2005-11-29 pbug soa_val = (u_int32_t *)&reply[outlen];
1395 f98bb34d 2011-09-19 pbug *soa_val = htonl(sd->soa.serial);
1396 f98bb34d 2011-09-19 pbug outlen += sizeof(sd->soa.serial); /* XXX */
1397 c45084ea 2005-11-29 pbug
1398 1a591502 2010-03-28 pbug /* XXX */
1399 df34d218 2014-04-21 pjp if ((outlen + sizeof(sd->soa.refresh)) > replysize) {
1400 a2b189d4 2014-10-08 pjp return (retlen);
1401 c45084ea 2005-11-29 pbug }
1402 c45084ea 2005-11-29 pbug soa_val = (u_int32_t *)&reply[outlen];
1403 f98bb34d 2011-09-19 pbug *soa_val = htonl(sd->soa.refresh);
1404 f98bb34d 2011-09-19 pbug outlen += sizeof(sd->soa.refresh); /* XXX */
1405 c45084ea 2005-11-29 pbug
1406 df34d218 2014-04-21 pjp if ((outlen + sizeof(sd->soa.retry)) > replysize) {
1407 a2b189d4 2014-10-08 pjp return (retlen);
1408 c45084ea 2005-11-29 pbug }
1409 c45084ea 2005-11-29 pbug soa_val = (u_int32_t *)&reply[outlen];
1410 f98bb34d 2011-09-19 pbug *soa_val = htonl(sd->soa.retry);
1411 f98bb34d 2011-09-19 pbug outlen += sizeof(sd->soa.retry); /* XXX */
1412 c45084ea 2005-11-29 pbug
1413 df34d218 2014-04-21 pjp if ((outlen + sizeof(sd->soa.expire)) > replysize) {
1414 a2b189d4 2014-10-08 pjp return (retlen);
1415 c45084ea 2005-11-29 pbug }
1416 c45084ea 2005-11-29 pbug soa_val = (u_int32_t *)&reply[outlen];
1417 f98bb34d 2011-09-19 pbug *soa_val = htonl(sd->soa.expire);
1418 f98bb34d 2011-09-19 pbug outlen += sizeof(sd->soa.expire);
1419 c45084ea 2005-11-29 pbug
1420 df34d218 2014-04-21 pjp if ((outlen + sizeof(sd->soa.minttl)) > replysize) {
1421 a2b189d4 2014-10-08 pjp return (retlen);
1422 c45084ea 2005-11-29 pbug }
1423 c45084ea 2005-11-29 pbug soa_val = (u_int32_t *)&reply[outlen];
1424 f98bb34d 2011-09-19 pbug *soa_val = htonl(sd->soa.minttl);
1425 f98bb34d 2011-09-19 pbug outlen += sizeof(sd->soa.minttl);
1426 c45084ea 2005-11-29 pbug
1427 c45084ea 2005-11-29 pbug answer->rdlength = htons(&reply[outlen] - &answer->rdata);
1428 cd18f393 2014-05-10 pjp
1429 cd18f393 2014-05-10 pjp if (q->edns0len) {
1430 cd18f393 2014-05-10 pjp /* tag on edns0 opt record */
1431 cd18f393 2014-05-10 pjp NTOHS(odh->additional);
1432 cd18f393 2014-05-10 pjp odh->additional++;
1433 cd18f393 2014-05-10 pjp HTONS(odh->additional);
1434 cd18f393 2014-05-10 pjp
1435 cd18f393 2014-05-10 pjp outlen = additional_opt(q, reply, replysize, outlen);
1436 cd18f393 2014-05-10 pjp }
1437 f5989689 2014-04-21 pjp
1438 f5989689 2014-04-21 pjp if (sreply->sr != NULL) {
1439 a2b189d4 2014-10-08 pjp retlen = reply_raw2(so, reply, outlen, sreply->sr);
1440 f5989689 2014-04-21 pjp } else {
1441 f5989689 2014-04-21 pjp if (istcp) {
1442 f5989689 2014-04-21 pjp char *tmpbuf;
1443 f5989689 2014-04-21 pjp u_int16_t *plen;
1444 f5989689 2014-04-21 pjp
1445 f5989689 2014-04-21 pjp tmpbuf = malloc(outlen + 2);
1446 f5989689 2014-04-21 pjp if (tmpbuf == NULL) {
1447 f5989689 2014-04-21 pjp dolog(LOG_INFO, "malloc: %s\n", strerror(errno));
1448 f5989689 2014-04-21 pjp }
1449 f5989689 2014-04-21 pjp plen = (u_int16_t *)tmpbuf;
1450 f5989689 2014-04-21 pjp *plen = htons(outlen);
1451 f5989689 2014-04-21 pjp
1452 f5989689 2014-04-21 pjp memcpy(&tmpbuf[2], reply, outlen);
1453 f5989689 2014-04-21 pjp
1454 a2b189d4 2014-10-08 pjp if ((retlen = send(so, tmpbuf, outlen + 2, 0)) < 0) {
1455 f5989689 2014-04-21 pjp dolog(LOG_INFO, "send: %s\n", strerror(errno));
1456 f5989689 2014-04-21 pjp }
1457 f5989689 2014-04-21 pjp free(tmpbuf);
1458 f5989689 2014-04-21 pjp } else {
1459 a2b189d4 2014-10-08 pjp if ((retlen = sendto(so, reply, outlen, 0, sa, salen)) < 0) {
1460 f5989689 2014-04-21 pjp dolog(LOG_INFO, "sendto: %s\n", strerror(errno));
1461 f5989689 2014-04-21 pjp }
1462 f5989689 2014-04-21 pjp }
1463 f5989689 2014-04-21 pjp }
1464 f5989689 2014-04-21 pjp
1465 a2b189d4 2014-10-08 pjp return (retlen);
1466 f5989689 2014-04-21 pjp }
1467 f5989689 2014-04-21 pjp
1468 f5989689 2014-04-21 pjp /*
1469 f5989689 2014-04-21 pjp * REPLY_SPF() - replies a DNS question (*q) on socket (so)
1470 f5989689 2014-04-21 pjp * based on reply_txt...
1471 f5989689 2014-04-21 pjp */
1472 f5989689 2014-04-21 pjp
1473 f5989689 2014-04-21 pjp
1474 a2b189d4 2014-10-08 pjp int
1475 f5989689 2014-04-21 pjp reply_spf(struct sreply *sreply)
1476 f5989689 2014-04-21 pjp {
1477 df34d218 2014-04-21 pjp char *reply = sreply->replybuf;
1478 f5989689 2014-04-21 pjp struct dns_header *odh;
1479 f5989689 2014-04-21 pjp u_int16_t outlen;
1480 f5989689 2014-04-21 pjp char *p;
1481 f5989689 2014-04-21 pjp
1482 f5989689 2014-04-21 pjp struct answer {
1483 f5989689 2014-04-21 pjp char name[2];
1484 f5989689 2014-04-21 pjp u_int16_t type;
1485 f5989689 2014-04-21 pjp u_int16_t class;
1486 f5989689 2014-04-21 pjp u_int32_t ttl;
1487 f5989689 2014-04-21 pjp u_int16_t rdlength; /* 12 */
1488 f5989689 2014-04-21 pjp char rdata;
1489 f5989689 2014-04-21 pjp } __attribute__((packed));
1490 f5989689 2014-04-21 pjp
1491 f5989689 2014-04-21 pjp struct answer *answer;
1492 f5989689 2014-04-21 pjp
1493 f5989689 2014-04-21 pjp int so = sreply->so;
1494 f5989689 2014-04-21 pjp char *buf = sreply->buf;
1495 f5989689 2014-04-21 pjp int len = sreply->len;
1496 f5989689 2014-04-21 pjp struct question *q = sreply->q;
1497 f5989689 2014-04-21 pjp struct sockaddr *sa = sreply->sa;
1498 f5989689 2014-04-21 pjp int salen = sreply->salen;
1499 f5989689 2014-04-21 pjp struct domain *sd = sreply->sd1;
1500 f5989689 2014-04-21 pjp int istcp = sreply->istcp;
1501 df34d218 2014-04-21 pjp int replysize = 512;
1502 a2b189d4 2014-10-08 pjp int retlen = -1;
1503 df34d218 2014-04-21 pjp
1504 df34d218 2014-04-21 pjp if (istcp) {
1505 df34d218 2014-04-21 pjp replysize = 65535;
1506 df34d218 2014-04-21 pjp }
1507 f5989689 2014-04-21 pjp
1508 cd18f393 2014-05-10 pjp if (q->edns0len > 512)
1509 cd18f393 2014-05-10 pjp replysize = q->edns0len;
1510 cd18f393 2014-05-10 pjp
1511 f5989689 2014-04-21 pjp /* st */
1512 f5989689 2014-04-21 pjp
1513 f5989689 2014-04-21 pjp odh = (struct dns_header *)&reply[0];
1514 f5989689 2014-04-21 pjp outlen = sizeof(struct dns_header);
1515 f5989689 2014-04-21 pjp
1516 df34d218 2014-04-21 pjp if (len > replysize) {
1517 a2b189d4 2014-10-08 pjp return (retlen);
1518 f5989689 2014-04-21 pjp }
1519 f5989689 2014-04-21 pjp
1520 f5989689 2014-04-21 pjp /* copy question to reply */
1521 df34d218 2014-04-21 pjp memcpy(reply, buf, sizeof(struct dns_header) + q->hdr->namelen + 4);
1522 f5989689 2014-04-21 pjp /* blank query */
1523 f5989689 2014-04-21 pjp memset((char *)&odh->query, 0, sizeof(u_int16_t));
1524 f5989689 2014-04-21 pjp
1525 f5989689 2014-04-21 pjp outlen += (q->hdr->namelen + 4);
1526 f5989689 2014-04-21 pjp
1527 f5989689 2014-04-21 pjp SET_DNS_REPLY(odh);
1528 f5989689 2014-04-21 pjp if (sreply->sr == NULL)
1529 f5989689 2014-04-21 pjp SET_DNS_AUTHORITATIVE(odh);
1530 f5989689 2014-04-21 pjp else
1531 f5989689 2014-04-21 pjp SET_DNS_RECURSION_AVAIL(odh);
1532 c45084ea 2005-11-29 pbug
1533 f5989689 2014-04-21 pjp HTONS(odh->query);
1534 f5989689 2014-04-21 pjp
1535 f5989689 2014-04-21 pjp odh->question = htons(1);
1536 f5989689 2014-04-21 pjp odh->answer = htons(1);
1537 f5989689 2014-04-21 pjp odh->nsrr = 0;
1538 f5989689 2014-04-21 pjp odh->additional = 0;
1539 f5989689 2014-04-21 pjp
1540 f5989689 2014-04-21 pjp answer = (struct answer *)(&reply[0] + sizeof(struct dns_header) +
1541 f5989689 2014-04-21 pjp q->hdr->namelen + 4);
1542 f5989689 2014-04-21 pjp
1543 f5989689 2014-04-21 pjp answer->name[0] = 0xc0;
1544 f5989689 2014-04-21 pjp answer->name[1] = 0x0c;
1545 f5989689 2014-04-21 pjp answer->type = q->hdr->qtype;
1546 f5989689 2014-04-21 pjp answer->class = q->hdr->qclass;
1547 f5989689 2014-04-21 pjp if (sreply->sr != NULL)
1548 f5989689 2014-04-21 pjp answer->ttl = htonl(sd->ttl - (time(NULL) - sd->created));
1549 f5989689 2014-04-21 pjp else
1550 f5989689 2014-04-21 pjp answer->ttl = htonl(sd->ttl);
1551 f5989689 2014-04-21 pjp
1552 f5989689 2014-04-21 pjp outlen += 12; /* up to rdata length */
1553 f5989689 2014-04-21 pjp
1554 f5989689 2014-04-21 pjp p = (char *)&answer->rdata;
1555 f5989689 2014-04-21 pjp
1556 f5989689 2014-04-21 pjp *p = sd->spflen;
1557 f5989689 2014-04-21 pjp memcpy((p + 1), sd->spf, sd->spflen);
1558 f5989689 2014-04-21 pjp outlen += (sd->spflen + 1);
1559 f5989689 2014-04-21 pjp
1560 f5989689 2014-04-21 pjp answer->rdlength = htons(sd->spflen + 1);
1561 f5989689 2014-04-21 pjp
1562 cd18f393 2014-05-10 pjp if (q->edns0len) {
1563 cd18f393 2014-05-10 pjp /* tag on edns0 opt record */
1564 cd18f393 2014-05-10 pjp NTOHS(odh->additional);
1565 cd18f393 2014-05-10 pjp odh->additional++;
1566 cd18f393 2014-05-10 pjp HTONS(odh->additional);
1567 cd18f393 2014-05-10 pjp
1568 cd18f393 2014-05-10 pjp outlen = additional_opt(q, reply, replysize, outlen);
1569 cd18f393 2014-05-10 pjp }
1570 cd18f393 2014-05-10 pjp
1571 b55adb0c 2010-09-26 pbug if (sreply->sr != NULL) {
1572 a2b189d4 2014-10-08 pjp retlen = reply_raw2(so, reply, outlen, sreply->sr);
1573 b55adb0c 2010-09-26 pbug } else {
1574 b55adb0c 2010-09-26 pbug if (istcp) {
1575 b55adb0c 2010-09-26 pbug char *tmpbuf;
1576 b55adb0c 2010-09-26 pbug u_int16_t *plen;
1577 f1e3cfca 2010-03-12 pbug
1578 b55adb0c 2010-09-26 pbug tmpbuf = malloc(outlen + 2);
1579 b55adb0c 2010-09-26 pbug if (tmpbuf == NULL) {
1580 dd869383 2013-02-16 pjp dolog(LOG_INFO, "malloc: %s\n", strerror(errno));
1581 b55adb0c 2010-09-26 pbug }
1582 b55adb0c 2010-09-26 pbug plen = (u_int16_t *)tmpbuf;
1583 b55adb0c 2010-09-26 pbug *plen = htons(outlen);
1584 b55adb0c 2010-09-26 pbug
1585 b55adb0c 2010-09-26 pbug memcpy(&tmpbuf[2], reply, outlen);
1586 b55adb0c 2010-09-26 pbug
1587 a2b189d4 2014-10-08 pjp if ((retlen = send(so, tmpbuf, outlen + 2, 0)) < 0) {
1588 dd869383 2013-02-16 pjp dolog(LOG_INFO, "send: %s\n", strerror(errno));
1589 b55adb0c 2010-09-26 pbug }
1590 b55adb0c 2010-09-26 pbug free(tmpbuf);
1591 b55adb0c 2010-09-26 pbug } else {
1592 a2b189d4 2014-10-08 pjp if ((retlen = sendto(so, reply, outlen, 0, sa, salen)) < 0) {
1593 dd869383 2013-02-16 pjp dolog(LOG_INFO, "sendto: %s\n", strerror(errno));
1594 b55adb0c 2010-09-26 pbug }
1595 f1e3cfca 2010-03-12 pbug }
1596 c45084ea 2005-11-29 pbug }
1597 c45084ea 2005-11-29 pbug
1598 a2b189d4 2014-10-08 pjp return (retlen);
1599 c45084ea 2005-11-29 pbug }
1600 fe42904f 2010-03-27 pbug
1601 fe42904f 2010-03-27 pbug /*
1602 fe42904f 2010-03-27 pbug * REPLY_TXT() - replies a DNS question (*q) on socket (so)
1603 fe42904f 2010-03-27 pbug *
1604 fe42904f 2010-03-27 pbug */
1605 fe42904f 2010-03-27 pbug
1606 fe42904f 2010-03-27 pbug
1607 a2b189d4 2014-10-08 pjp int
1608 fe42904f 2010-03-27 pbug reply_txt(struct sreply *sreply)
1609 fe42904f 2010-03-27 pbug {
1610 df34d218 2014-04-21 pjp char *reply = sreply->replybuf;
1611 fe42904f 2010-03-27 pbug struct dns_header *odh;
1612 b6dc64dc 2010-04-15 pbug u_int16_t outlen;
1613 fe42904f 2010-03-27 pbug char *p;
1614 c45084ea 2005-11-29 pbug
1615 fe42904f 2010-03-27 pbug struct answer {
1616 fe42904f 2010-03-27 pbug char name[2];
1617 fe42904f 2010-03-27 pbug u_int16_t type;
1618 fe42904f 2010-03-27 pbug u_int16_t class;
1619 fe42904f 2010-03-27 pbug u_int32_t ttl;
1620 fe42904f 2010-03-27 pbug u_int16_t rdlength; /* 12 */
1621 fe42904f 2010-03-27 pbug char rdata;
1622 fe42904f 2010-03-27 pbug } __attribute__((packed));
1623 fe42904f 2010-03-27 pbug
1624 fe42904f 2010-03-27 pbug struct answer *answer;
1625 fe42904f 2010-03-27 pbug
1626 fe42904f 2010-03-27 pbug int so = sreply->so;
1627 fe42904f 2010-03-27 pbug char *buf = sreply->buf;
1628 fe42904f 2010-03-27 pbug int len = sreply->len;
1629 fe42904f 2010-03-27 pbug struct question *q = sreply->q;
1630 fe42904f 2010-03-27 pbug struct sockaddr *sa = sreply->sa;
1631 fe42904f 2010-03-27 pbug int salen = sreply->salen;
1632 fe42904f 2010-03-27 pbug struct domain *sd = sreply->sd1;
1633 fe42904f 2010-03-27 pbug int istcp = sreply->istcp;
1634 df34d218 2014-04-21 pjp int replysize = 512;
1635 a2b189d4 2014-10-08 pjp int retlen = -1;
1636 df34d218 2014-04-21 pjp
1637 df34d218 2014-04-21 pjp if (istcp) {
1638 df34d218 2014-04-21 pjp replysize = 65535;
1639 df34d218 2014-04-21 pjp }
1640 cd18f393 2014-05-10 pjp
1641 cd18f393 2014-05-10 pjp if (q->edns0len > 512)
1642 cd18f393 2014-05-10 pjp replysize = q->edns0len;
1643 fe42904f 2010-03-27 pbug
1644 fe42904f 2010-03-27 pbug /* st */
1645 fe42904f 2010-03-27 pbug
1646 fe42904f 2010-03-27 pbug odh = (struct dns_header *)&reply[0];
1647 fe42904f 2010-03-27 pbug outlen = sizeof(struct dns_header);
1648 fe42904f 2010-03-27 pbug
1649 df34d218 2014-04-21 pjp if (len > replysize) {
1650 a2b189d4 2014-10-08 pjp return (retlen);
1651 fe42904f 2010-03-27 pbug }
1652 fe42904f 2010-03-27 pbug
1653 fe42904f 2010-03-27 pbug /* copy question to reply */
1654 df34d218 2014-04-21 pjp memcpy(reply, buf, sizeof(struct dns_header) + q->hdr->namelen + 4);
1655 fe42904f 2010-03-27 pbug /* blank query */
1656 fe42904f 2010-03-27 pbug memset((char *)&odh->query, 0, sizeof(u_int16_t));
1657 fe42904f 2010-03-27 pbug
1658 fe42904f 2010-03-27 pbug outlen += (q->hdr->namelen + 4);
1659 fe42904f 2010-03-27 pbug
1660 fe42904f 2010-03-27 pbug SET_DNS_REPLY(odh);
1661 b55adb0c 2010-09-26 pbug if (sreply->sr == NULL)
1662 b55adb0c 2010-09-26 pbug SET_DNS_AUTHORITATIVE(odh);
1663 b55adb0c 2010-09-26 pbug else
1664 b55adb0c 2010-09-26 pbug SET_DNS_RECURSION_AVAIL(odh);
1665 fe42904f 2010-03-27 pbug
1666 fe42904f 2010-03-27 pbug HTONS(odh->query);
1667 fe42904f 2010-03-27 pbug
1668 fe42904f 2010-03-27 pbug odh->question = htons(1);
1669 fe42904f 2010-03-27 pbug odh->answer = htons(1);
1670 fe42904f 2010-03-27 pbug odh->nsrr = 0;
1671 fe42904f 2010-03-27 pbug odh->additional = 0;
1672 fe42904f 2010-03-27 pbug
1673 fe42904f 2010-03-27 pbug answer = (struct answer *)(&reply[0] + sizeof(struct dns_header) +
1674 fe42904f 2010-03-27 pbug q->hdr->namelen + 4);
1675 fe42904f 2010-03-27 pbug
1676 fe42904f 2010-03-27 pbug answer->name[0] = 0xc0;
1677 fe42904f 2010-03-27 pbug answer->name[1] = 0x0c;
1678 fe42904f 2010-03-27 pbug answer->type = q->hdr->qtype;
1679 fe42904f 2010-03-27 pbug answer->class = q->hdr->qclass;
1680 b55adb0c 2010-09-26 pbug if (sreply->sr != NULL)
1681 b55adb0c 2010-09-26 pbug answer->ttl = htonl(sd->ttl - (time(NULL) - sd->created));
1682 b55adb0c 2010-09-26 pbug else
1683 b55adb0c 2010-09-26 pbug answer->ttl = htonl(sd->ttl);
1684 fe42904f 2010-03-27 pbug
1685 fe42904f 2010-03-27 pbug outlen += 12; /* up to rdata length */
1686 fe42904f 2010-03-27 pbug
1687 fe42904f 2010-03-27 pbug p = (char *)&answer->rdata;
1688 fe42904f 2010-03-27 pbug
1689 fe42904f 2010-03-27 pbug *p = sd->txtlen;
1690 fe42904f 2010-03-27 pbug memcpy((p + 1), sd->txt, sd->txtlen);
1691 fe42904f 2010-03-27 pbug outlen += (sd->txtlen + 1);
1692 fe42904f 2010-03-27 pbug
1693 fe42904f 2010-03-27 pbug answer->rdlength = htons(sd->txtlen + 1);
1694 fe42904f 2010-03-27 pbug
1695 cd18f393 2014-05-10 pjp if (q->edns0len) {
1696 cd18f393 2014-05-10 pjp /* tag on edns0 opt record */
1697 cd18f393 2014-05-10 pjp NTOHS(odh->additional);
1698 cd18f393 2014-05-10 pjp odh->additional++;
1699 cd18f393 2014-05-10 pjp HTONS(odh->additional);
1700 cd18f393 2014-05-10 pjp
1701 cd18f393 2014-05-10 pjp outlen = additional_opt(q, reply, replysize, outlen);
1702 cd18f393 2014-05-10 pjp }
1703 cd18f393 2014-05-10 pjp
1704 b55adb0c 2010-09-26 pbug if (sreply->sr != NULL) {
1705 a2b189d4 2014-10-08 pjp retlen = reply_raw2(so, reply, outlen, sreply->sr);
1706 b55adb0c 2010-09-26 pbug } else {
1707 b55adb0c 2010-09-26 pbug if (istcp) {
1708 b55adb0c 2010-09-26 pbug char *tmpbuf;
1709 b55adb0c 2010-09-26 pbug u_int16_t *plen;
1710 fe42904f 2010-03-27 pbug
1711 b55adb0c 2010-09-26 pbug tmpbuf = malloc(outlen + 2);
1712 b55adb0c 2010-09-26 pbug if (tmpbuf == NULL) {
1713 dd869383 2013-02-16 pjp dolog(LOG_INFO, "malloc: %s\n", strerror(errno));
1714 b55adb0c 2010-09-26 pbug }
1715 b55adb0c 2010-09-26 pbug plen = (u_int16_t *)tmpbuf;
1716 b55adb0c 2010-09-26 pbug *plen = htons(outlen);
1717 b55adb0c 2010-09-26 pbug
1718 b55adb0c 2010-09-26 pbug memcpy(&tmpbuf[2], reply, outlen);
1719 fe42904f 2010-03-27 pbug
1720 a2b189d4 2014-10-08 pjp if ((retlen = send(so, tmpbuf, outlen + 2, 0)) < 0) {
1721 dd869383 2013-02-16 pjp dolog(LOG_INFO, "send: %s\n", strerror(errno));
1722 b55adb0c 2010-09-26 pbug }
1723 b55adb0c 2010-09-26 pbug free(tmpbuf);
1724 b55adb0c 2010-09-26 pbug } else {
1725 a2b189d4 2014-10-08 pjp if ((retlen = sendto(so, reply, outlen, 0, sa, salen)) < 0) {
1726 dd869383 2013-02-16 pjp dolog(LOG_INFO, "sendto: %s\n", strerror(errno));
1727 b55adb0c 2010-09-26 pbug }
1728 fe42904f 2010-03-27 pbug }
1729 fe42904f 2010-03-27 pbug }
1730 fe42904f 2010-03-27 pbug
1731 a2b189d4 2014-10-08 pjp return (retlen);
1732 fe42904f 2010-03-27 pbug }
1733 6f8190d3 2012-04-30 pbug
1734 df34d218 2014-04-21 pjp /*
1735 df34d218 2014-04-21 pjp * REPLY_SSHFP() - replies a DNS question (*q) on socket (so)
1736 df34d218 2014-04-21 pjp * (based on reply_srv)
1737 df34d218 2014-04-21 pjp */
1738 6f8190d3 2012-04-30 pbug
1739 df34d218 2014-04-21 pjp
1740 a2b189d4 2014-10-08 pjp int
1741 df34d218 2014-04-21 pjp reply_sshfp(struct sreply *sreply)
1742 df34d218 2014-04-21 pjp {
1743 df34d218 2014-04-21 pjp char *reply = sreply->replybuf;
1744 df34d218 2014-04-21 pjp struct dns_header *odh;
1745 df34d218 2014-04-21 pjp int sshfp_count;
1746 df34d218 2014-04-21 pjp u_int16_t *plen;
1747 df34d218 2014-04-21 pjp u_int16_t outlen;
1748 df34d218 2014-04-21 pjp
1749 df34d218 2014-04-21 pjp struct answer {
1750 df34d218 2014-04-21 pjp char name[2];
1751 df34d218 2014-04-21 pjp u_int16_t type;
1752 df34d218 2014-04-21 pjp u_int16_t class;
1753 df34d218 2014-04-21 pjp u_int32_t ttl;
1754 df34d218 2014-04-21 pjp u_int16_t rdlength; /* 12 */
1755 df34d218 2014-04-21 pjp u_int8_t sshfp_alg;
1756 df34d218 2014-04-21 pjp u_int8_t sshfp_type;
1757 df34d218 2014-04-21 pjp char target;
1758 df34d218 2014-04-21 pjp } __attribute__((packed));
1759 df34d218 2014-04-21 pjp
1760 df34d218 2014-04-21 pjp struct answer *answer;
1761 df34d218 2014-04-21 pjp
1762 df34d218 2014-04-21 pjp int so = sreply->so;
1763 df34d218 2014-04-21 pjp char *buf = sreply->buf;
1764 df34d218 2014-04-21 pjp int len = sreply->len;
1765 df34d218 2014-04-21 pjp struct question *q = sreply->q;
1766 df34d218 2014-04-21 pjp struct sockaddr *sa = sreply->sa;
1767 df34d218 2014-04-21 pjp int salen = sreply->salen;
1768 df34d218 2014-04-21 pjp struct domain *sd = sreply->sd1;
1769 df34d218 2014-04-21 pjp int istcp = sreply->istcp;
1770 df34d218 2014-04-21 pjp int typelen = 0;
1771 df34d218 2014-04-21 pjp int replysize = 512;
1772 a2b189d4 2014-10-08 pjp int retlen = -1;
1773 df34d218 2014-04-21 pjp
1774 df34d218 2014-04-21 pjp if (istcp) {
1775 df34d218 2014-04-21 pjp replysize = 65535;
1776 df34d218 2014-04-21 pjp }
1777 cd18f393 2014-05-10 pjp
1778 cd18f393 2014-05-10 pjp if (q->edns0len > 512)
1779 cd18f393 2014-05-10 pjp replysize = q->edns0len;
1780 df34d218 2014-04-21 pjp
1781 df34d218 2014-04-21 pjp
1782 df34d218 2014-04-21 pjp odh = (struct dns_header *)&reply[0];
1783 df34d218 2014-04-21 pjp
1784 df34d218 2014-04-21 pjp outlen = sizeof(struct dns_header);
1785 df34d218 2014-04-21 pjp
1786 df34d218 2014-04-21 pjp if (len > replysize) {
1787 a2b189d4 2014-10-08 pjp return (retlen);
1788 df34d218 2014-04-21 pjp }
1789 df34d218 2014-04-21 pjp
1790 df34d218 2014-04-21 pjp memcpy(reply, buf, sizeof(struct dns_header) + q->hdr->namelen + 4);
1791 df34d218 2014-04-21 pjp memset((char *)&odh->query, 0, sizeof(u_int16_t));
1792 df34d218 2014-04-21 pjp
1793 df34d218 2014-04-21 pjp outlen += (q->hdr->namelen + 4);
1794 df34d218 2014-04-21 pjp
1795 df34d218 2014-04-21 pjp SET_DNS_REPLY(odh);
1796 df34d218 2014-04-21 pjp
1797 df34d218 2014-04-21 pjp if (sreply->sr == NULL) {
1798 df34d218 2014-04-21 pjp SET_DNS_AUTHORITATIVE(odh);
1799 df34d218 2014-04-21 pjp } else
1800 df34d218 2014-04-21 pjp SET_DNS_RECURSION_AVAIL(odh);
1801 df34d218 2014-04-21 pjp
1802 df34d218 2014-04-21 pjp HTONS(odh->query);
1803 df34d218 2014-04-21 pjp
1804 df34d218 2014-04-21 pjp odh->question = htons(1);
1805 df34d218 2014-04-21 pjp odh->answer = htons(sd->sshfp_count);
1806 df34d218 2014-04-21 pjp odh->nsrr = 0;
1807 df34d218 2014-04-21 pjp odh->additional = 0;
1808 df34d218 2014-04-21 pjp
1809 df34d218 2014-04-21 pjp /* skip dns header, question name, qtype and qclass */
1810 df34d218 2014-04-21 pjp answer = (struct answer *)(&reply[0] + sizeof(struct dns_header) +
1811 df34d218 2014-04-21 pjp q->hdr->namelen + 4);
1812 df34d218 2014-04-21 pjp
1813 df34d218 2014-04-21 pjp sshfp_count = 0;
1814 df34d218 2014-04-21 pjp do {
1815 df34d218 2014-04-21 pjp answer->name[0] = 0xc0;
1816 df34d218 2014-04-21 pjp answer->name[1] = 0x0c;
1817 df34d218 2014-04-21 pjp answer->type = q->hdr->qtype;
1818 df34d218 2014-04-21 pjp answer->class = q->hdr->qclass;
1819 df34d218 2014-04-21 pjp if (sreply->sr != NULL)
1820 df34d218 2014-04-21 pjp answer->ttl = htonl(sd->ttl - (time(NULL) - sd->created));
1821 df34d218 2014-04-21 pjp else
1822 df34d218 2014-04-21 pjp answer->ttl = htonl(sd->ttl);
1823 df34d218 2014-04-21 pjp
1824 df34d218 2014-04-21 pjp switch (sd->sshfp[sshfp_count].fptype) {
1825 df34d218 2014-04-21 pjp case 1:
1826 df34d218 2014-04-21 pjp typelen = DNS_SSHFP_SIZE_SHA1;
1827 df34d218 2014-04-21 pjp break;
1828 df34d218 2014-04-21 pjp case 2:
1829 df34d218 2014-04-21 pjp typelen = DNS_SSHFP_SIZE_SHA256;
1830 df34d218 2014-04-21 pjp break;
1831 df34d218 2014-04-21 pjp default:
1832 df34d218 2014-04-21 pjp dolog(LOG_ERR, "oops bad sshfp type? not returning a packet!\n");
1833 a2b189d4 2014-10-08 pjp return (retlen);
1834 df34d218 2014-04-21 pjp }
1835 df34d218 2014-04-21 pjp
1836 df34d218 2014-04-21 pjp answer->rdlength = htons((2 * sizeof(u_int8_t)) + typelen);
1837 df34d218 2014-04-21 pjp answer->sshfp_alg = sd->sshfp[sshfp_count].algorithm;
1838 df34d218 2014-04-21 pjp answer->sshfp_type = sd->sshfp[sshfp_count].fptype;
1839 df34d218 2014-04-21 pjp
1840 df34d218 2014-04-21 pjp memcpy((char *)&answer->target, (char *)sd->sshfp[sshfp_count].fingerprint, sd->sshfp[sshfp_count].fplen);
1841 df34d218 2014-04-21 pjp
1842 df34d218 2014-04-21 pjp /* can we afford to write another header? if no truncate */
1843 1f1faf13 2014-05-11 pjp if (sd->sshfp_count > 1 && (outlen + 12 + 2 + sd->sshfp[sshfp_count].fplen) > replysize) {
1844 df34d218 2014-04-21 pjp NTOHS(odh->query);
1845 df34d218 2014-04-21 pjp SET_DNS_TRUNCATION(odh);
1846 df34d218 2014-04-21 pjp HTONS(odh->query);
1847 df34d218 2014-04-21 pjp goto out;
1848 df34d218 2014-04-21 pjp }
1849 df34d218 2014-04-21 pjp
1850 df34d218 2014-04-21 pjp /* set new offset for answer */
1851 df34d218 2014-04-21 pjp outlen += (12 + 2 + sd->sshfp[sshfp_count].fplen);
1852 df34d218 2014-04-21 pjp answer = (struct answer *)&reply[outlen];
1853 df34d218 2014-04-21 pjp } while (++sshfp_count < RECORD_COUNT && --sd->sshfp_count);
1854 1f1faf13 2014-05-11 pjp
1855 1f1faf13 2014-05-11 pjp if (q->edns0len) {
1856 1f1faf13 2014-05-11 pjp /* tag on edns0 opt record */
1857 1f1faf13 2014-05-11 pjp NTOHS(odh->additional);
1858 1f1faf13 2014-05-11 pjp odh->additional++;
1859 1f1faf13 2014-05-11 pjp HTONS(odh->additional);
1860 1f1faf13 2014-05-11 pjp
1861 1f1faf13 2014-05-11 pjp outlen = additional_opt(q, reply, replysize, outlen);
1862 1f1faf13 2014-05-11 pjp }
1863 1f1faf13 2014-05-11 pjp
1864 1f1faf13 2014-05-11 pjp out:
1865 1f1faf13 2014-05-11 pjp if (sreply->sr != NULL) {
1866 a2b189d4 2014-10-08 pjp retlen = reply_raw2(so, reply, outlen, sreply->sr);
1867 1f1faf13 2014-05-11 pjp } else {
1868 1f1faf13 2014-05-11 pjp if (istcp) {
1869 1f1faf13 2014-05-11 pjp char *tmpbuf;
1870 1f1faf13 2014-05-11 pjp
1871 1f1faf13 2014-05-11 pjp tmpbuf = malloc(outlen + 2);
1872 1f1faf13 2014-05-11 pjp if (tmpbuf == NULL) {
1873 1f1faf13 2014-05-11 pjp dolog(LOG_INFO, "malloc: %s\n", strerror(errno));
1874 1f1faf13 2014-05-11 pjp }
1875 1f1faf13 2014-05-11 pjp plen = (u_int16_t *)tmpbuf;
1876 1f1faf13 2014-05-11 pjp *plen = htons(outlen);
1877 1f1faf13 2014-05-11 pjp
1878 1f1faf13 2014-05-11 pjp memcpy(&tmpbuf[2], reply, outlen);
1879 a2b189d4 2014-10-08 pjp if ((retlen = send(so, tmpbuf, outlen + 2, 0)) < 0) {
1880 1f1faf13 2014-05-11 pjp dolog(LOG_INFO, "send: %s\n", strerror(errno));
1881 1f1faf13 2014-05-11 pjp }
1882 1f1faf13 2014-05-11 pjp free(tmpbuf);
1883 1f1faf13 2014-05-11 pjp } else {
1884 a2b189d4 2014-10-08 pjp if ((retlen = sendto(so, reply, outlen, 0, sa, salen)) < 0) {
1885 1f1faf13 2014-05-11 pjp dolog(LOG_INFO, "sendto: %s\n", strerror(errno));
1886 1f1faf13 2014-05-11 pjp }
1887 1f1faf13 2014-05-11 pjp }
1888 1f1faf13 2014-05-11 pjp }
1889 1f1faf13 2014-05-11 pjp
1890 a2b189d4 2014-10-08 pjp return (retlen);
1891 1f1faf13 2014-05-11 pjp }
1892 1f1faf13 2014-05-11 pjp
1893 1f1faf13 2014-05-11 pjp
1894 1f1faf13 2014-05-11 pjp /*
1895 1f1faf13 2014-05-11 pjp * REPLY_NAPTR() - replies a DNS question (*q) on socket (so)
1896 1f1faf13 2014-05-11 pjp * (based on reply_srv)
1897 1f1faf13 2014-05-11 pjp */
1898 1f1faf13 2014-05-11 pjp
1899 1f1faf13 2014-05-11 pjp
1900 a2b189d4 2014-10-08 pjp int
1901 1f1faf13 2014-05-11 pjp reply_naptr(struct sreply *sreply, DB *db)
1902 1f1faf13 2014-05-11 pjp {
1903 1f1faf13 2014-05-11 pjp char *reply = sreply->replybuf;
1904 1f1faf13 2014-05-11 pjp struct dns_header *odh;
1905 1f1faf13 2014-05-11 pjp struct domain *sd0;
1906 1f1faf13 2014-05-11 pjp int naptr_count;
1907 1f1faf13 2014-05-11 pjp u_int16_t *plen;
1908 1f1faf13 2014-05-11 pjp char *name;
1909 1f1faf13 2014-05-11 pjp u_int16_t outlen;
1910 1f1faf13 2014-05-11 pjp u_int16_t namelen;
1911 1f1faf13 2014-05-11 pjp int additional = 0;
1912 1f1faf13 2014-05-11 pjp
1913 1f1faf13 2014-05-11 pjp struct answer {
1914 1f1faf13 2014-05-11 pjp char name[2];
1915 1f1faf13 2014-05-11 pjp u_int16_t type;
1916 1f1faf13 2014-05-11 pjp u_int16_t class;
1917 1f1faf13 2014-05-11 pjp u_int32_t ttl;
1918 1f1faf13 2014-05-11 pjp u_int16_t rdlength; /* 12 */
1919 1f1faf13 2014-05-11 pjp u_int16_t naptr_order;
1920 1f1faf13 2014-05-11 pjp u_int16_t naptr_preference;
1921 1f1faf13 2014-05-11 pjp char rest;
1922 1f1faf13 2014-05-11 pjp } __attribute__((packed));
1923 1f1faf13 2014-05-11 pjp
1924 1f1faf13 2014-05-11 pjp struct answer *answer;
1925 1f1faf13 2014-05-11 pjp
1926 1f1faf13 2014-05-11 pjp int so = sreply->so;
1927 1f1faf13 2014-05-11 pjp char *buf = sreply->buf;
1928 1f1faf13 2014-05-11 pjp int len = sreply->len;
1929 1f1faf13 2014-05-11 pjp struct question *q = sreply->q;
1930 1f1faf13 2014-05-11 pjp struct sockaddr *sa = sreply->sa;
1931 1f1faf13 2014-05-11 pjp int salen = sreply->salen;
1932 1f1faf13 2014-05-11 pjp struct domain *sd = sreply->sd1;
1933 1f1faf13 2014-05-11 pjp int istcp = sreply->istcp;
1934 1f1faf13 2014-05-11 pjp int wildcard = sreply->wildcard;
1935 1f1faf13 2014-05-11 pjp int replysize = 512;
1936 1f1faf13 2014-05-11 pjp int tmplen, savelen;
1937 1f1faf13 2014-05-11 pjp char *p;
1938 a2b189d4 2014-10-08 pjp int retlen = -1;
1939 1f1faf13 2014-05-11 pjp
1940 1f1faf13 2014-05-11 pjp if (istcp) {
1941 1f1faf13 2014-05-11 pjp replysize = 65535;
1942 1f1faf13 2014-05-11 pjp }
1943 1f1faf13 2014-05-11 pjp
1944 1f1faf13 2014-05-11 pjp if (q->edns0len > 512)
1945 1f1faf13 2014-05-11 pjp replysize = q->edns0len;
1946 1f1faf13 2014-05-11 pjp
1947 1f1faf13 2014-05-11 pjp odh = (struct dns_header *)&reply[0];
1948 1f1faf13 2014-05-11 pjp
1949 1f1faf13 2014-05-11 pjp outlen = sizeof(struct dns_header);
1950 1f1faf13 2014-05-11 pjp
1951 1f1faf13 2014-05-11 pjp if (len > replysize) {
1952 a2b189d4 2014-10-08 pjp return (retlen);
1953 1f1faf13 2014-05-11 pjp }
1954 1f1faf13 2014-05-11 pjp
1955 1f1faf13 2014-05-11 pjp memcpy(reply, buf, sizeof(struct dns_header) + q->hdr->namelen + 4);
1956 1f1faf13 2014-05-11 pjp memset((char *)&odh->query, 0, sizeof(u_int16_t));
1957 1f1faf13 2014-05-11 pjp
1958 1f1faf13 2014-05-11 pjp outlen += (q->hdr->namelen + 4);
1959 1f1faf13 2014-05-11 pjp
1960 1f1faf13 2014-05-11 pjp SET_DNS_REPLY(odh);
1961 1f1faf13 2014-05-11 pjp
1962 1f1faf13 2014-05-11 pjp if (sreply->sr == NULL) {
1963 1f1faf13 2014-05-11 pjp SET_DNS_AUTHORITATIVE(odh);
1964 1f1faf13 2014-05-11 pjp } else
1965 1f1faf13 2014-05-11 pjp SET_DNS_RECURSION_AVAIL(odh);
1966 1f1faf13 2014-05-11 pjp
1967 1f1faf13 2014-05-11 pjp HTONS(odh->query);
1968 1f1faf13 2014-05-11 pjp
1969 1f1faf13 2014-05-11 pjp odh->question = htons(1);
1970 1f1faf13 2014-05-11 pjp odh->answer = htons(sd->naptr_count);
1971 1f1faf13 2014-05-11 pjp odh->nsrr = 0;
1972 1f1faf13 2014-05-11 pjp odh->additional = 0;
1973 1f1faf13 2014-05-11 pjp
1974 1f1faf13 2014-05-11 pjp /* skip dns header, question name, qtype and qclass */
1975 1f1faf13 2014-05-11 pjp answer = (struct answer *)(&reply[0] + sizeof(struct dns_header) +
1976 1f1faf13 2014-05-11 pjp q->hdr->namelen + 4);
1977 1f1faf13 2014-05-11 pjp
1978 1f1faf13 2014-05-11 pjp naptr_count = 0;
1979 1f1faf13 2014-05-11 pjp do {
1980 1f1faf13 2014-05-11 pjp savelen = outlen;
1981 1f1faf13 2014-05-11 pjp answer->name[0] = 0xc0;
1982 1f1faf13 2014-05-11 pjp answer->name[1] = 0x0c;
1983 1f1faf13 2014-05-11 pjp answer->type = q->hdr->qtype;
1984 1f1faf13 2014-05-11 pjp answer->class = q->hdr->qclass;
1985 1f1faf13 2014-05-11 pjp if (sreply->sr != NULL)
1986 1f1faf13 2014-05-11 pjp answer->ttl = htonl(sd->ttl - (time(NULL) - sd->created));
1987 1f1faf13 2014-05-11 pjp else
1988 1f1faf13 2014-05-11 pjp answer->ttl = htonl(sd->ttl);
1989 1f1faf13 2014-05-11 pjp
1990 1f1faf13 2014-05-11 pjp answer->naptr_order = htons(sd->naptr[naptr_count].order);
1991 1f1faf13 2014-05-11 pjp answer->naptr_preference = htons(sd->naptr[naptr_count].preference);
1992 1f1faf13 2014-05-11 pjp
1993 1f1faf13 2014-05-11 pjp p = (char *)&answer->rest;
1994 1f1faf13 2014-05-11 pjp
1995 1f1faf13 2014-05-11 pjp *p = sd->naptr[naptr_count].flagslen;
1996 1f1faf13 2014-05-11 pjp memcpy((p + 1), sd->naptr[naptr_count].flags, sd->naptr[naptr_count].flagslen);
1997 1f1faf13 2014-05-11 pjp p += (sd->naptr[naptr_count].flagslen + 1);
1998 1f1faf13 2014-05-11 pjp outlen += (1 + sd->naptr[naptr_count].flagslen);
1999 1f1faf13 2014-05-11 pjp
2000 1f1faf13 2014-05-11 pjp /* services */
2001 1f1faf13 2014-05-11 pjp *p = sd->naptr[naptr_count].serviceslen;
2002 1f1faf13 2014-05-11 pjp memcpy((p + 1), sd->naptr[naptr_count].services, sd->naptr[naptr_count].serviceslen);
2003 1f1faf13 2014-05-11 pjp p += (sd->naptr[naptr_count].serviceslen + 1);
2004 1f1faf13 2014-05-11 pjp outlen += (1 + sd->naptr[naptr_count].serviceslen);
2005 1f1faf13 2014-05-11 pjp
2006 1f1faf13 2014-05-11 pjp /* regexp */
2007 1f1faf13 2014-05-11 pjp *p = sd->naptr[naptr_count].regexplen;
2008 1f1faf13 2014-05-11 pjp memcpy((p + 1), sd->naptr[naptr_count].regexp, sd->naptr[naptr_count].regexplen);
2009 1f1faf13 2014-05-11 pjp p += (sd->naptr[naptr_count].regexplen + 1);
2010 1f1faf13 2014-05-11 pjp outlen += (1 + sd->naptr[naptr_count].regexplen);
2011 1f1faf13 2014-05-11 pjp
2012 1f1faf13 2014-05-11 pjp /* replacement */
2013 1f1faf13 2014-05-11 pjp
2014 1f1faf13 2014-05-11 pjp memcpy((char *)p, (char *)sd->naptr[naptr_count].replacement, sd->naptr[naptr_count].replacementlen);
2015 1f1faf13 2014-05-11 pjp
2016 1f1faf13 2014-05-11 pjp name = sd->naptr[naptr_count].replacement;
2017 1f1faf13 2014-05-11 pjp namelen = sd->naptr[naptr_count].replacementlen;
2018 1f1faf13 2014-05-11 pjp
2019 1f1faf13 2014-05-11 pjp outlen += (12 + 4 + sd->naptr[naptr_count].replacementlen);
2020 1f1faf13 2014-05-11 pjp
2021 1f1faf13 2014-05-11 pjp /* compress the label if possible */
2022 1f1faf13 2014-05-11 pjp if ((tmplen = compress_label((u_char*)reply, outlen, namelen)) > 0) {
2023 1f1faf13 2014-05-11 pjp outlen = tmplen;
2024 1f1faf13 2014-05-11 pjp }
2025 df34d218 2014-04-21 pjp
2026 1f1faf13 2014-05-11 pjp answer->rdlength = htons(outlen - (savelen + 12));
2027 1f1faf13 2014-05-11 pjp
2028 1f1faf13 2014-05-11 pjp
2029 1f1faf13 2014-05-11 pjp sd0 = Lookup_zone(db, name, namelen, htons(DNS_TYPE_A), wildcard);
2030 1f1faf13 2014-05-11 pjp if (sd0 != NULL) {
2031 1f1faf13 2014-05-11 pjp cn1 = malloc(sizeof(struct collects));
2032 1f1faf13 2014-05-11 pjp if (cn1 != NULL) {
2033 1f1faf13 2014-05-11 pjp cn1->name = malloc(namelen);
2034 1f1faf13 2014-05-11 pjp if (cn1->name != NULL) {
2035 1f1faf13 2014-05-11 pjp memcpy(cn1->name, name, namelen);
2036 1f1faf13 2014-05-11 pjp cn1->namelen = namelen;
2037 1f1faf13 2014-05-11 pjp cn1->sd = sd0;
2038 1f1faf13 2014-05-11 pjp cn1->type = DNS_TYPE_A;
2039 1f1faf13 2014-05-11 pjp
2040 1f1faf13 2014-05-11 pjp SLIST_INSERT_HEAD(&collectshead, cn1, collect_entry);
2041 1f1faf13 2014-05-11 pjp }
2042 1f1faf13 2014-05-11 pjp }
2043 1f1faf13 2014-05-11 pjp }
2044 1f1faf13 2014-05-11 pjp sd0 = Lookup_zone(db, name, namelen, htons(DNS_TYPE_AAAA), wildcard);
2045 1f1faf13 2014-05-11 pjp if (sd0 != NULL) {
2046 1f1faf13 2014-05-11 pjp cn1 = malloc(sizeof(struct collects));
2047 1f1faf13 2014-05-11 pjp if (cn1 != NULL) {
2048 1f1faf13 2014-05-11 pjp cn1->name = malloc(namelen);
2049 1f1faf13 2014-05-11 pjp if (cn1->name != NULL) {
2050 1f1faf13 2014-05-11 pjp memcpy(cn1->name, name, namelen);
2051 1f1faf13 2014-05-11 pjp cn1->namelen = namelen;
2052 1f1faf13 2014-05-11 pjp cn1->sd = sd0;
2053 1f1faf13 2014-05-11 pjp cn1->type = DNS_TYPE_AAAA;
2054 1f1faf13 2014-05-11 pjp
2055 1f1faf13 2014-05-11 pjp SLIST_INSERT_HEAD(&collectshead, cn1, collect_entry);
2056 1f1faf13 2014-05-11 pjp }
2057 1f1faf13 2014-05-11 pjp }
2058 1f1faf13 2014-05-11 pjp }
2059 1f1faf13 2014-05-11 pjp
2060 1f1faf13 2014-05-11 pjp
2061 1f1faf13 2014-05-11 pjp /* can we afford to write another header? if no truncate */
2062 1f1faf13 2014-05-11 pjp if (sd->naptr_count > naptr_count && (outlen + 12 + 4 + sd->naptr[naptr_count + 1].replacementlen + sd->naptr[naptr_count + 1].flagslen + 1 + sd->naptr[naptr_count + 1].serviceslen + 1 + sd->naptr[naptr_count + 1].regexplen + 1) > replysize) {
2063 1f1faf13 2014-05-11 pjp NTOHS(odh->query);
2064 1f1faf13 2014-05-11 pjp SET_DNS_TRUNCATION(odh);
2065 1f1faf13 2014-05-11 pjp HTONS(odh->query);
2066 1f1faf13 2014-05-11 pjp goto out;
2067 1f1faf13 2014-05-11 pjp }
2068 1f1faf13 2014-05-11 pjp
2069 1f1faf13 2014-05-11 pjp /* set new offset for answer */
2070 1f1faf13 2014-05-11 pjp answer = (struct answer *)&reply[outlen];
2071 1f1faf13 2014-05-11 pjp } while (++naptr_count < RECORD_COUNT && --sd->naptr_count);
2072 1f1faf13 2014-05-11 pjp
2073 1f1faf13 2014-05-11 pjp /* write additional */
2074 1f1faf13 2014-05-11 pjp
2075 1f1faf13 2014-05-11 pjp SLIST_FOREACH(cnp, &collectshead, collect_entry) {
2076 1f1faf13 2014-05-11 pjp int addcount;
2077 1f1faf13 2014-05-11 pjp int tmplen;
2078 1f1faf13 2014-05-11 pjp
2079 1f1faf13 2014-05-11 pjp switch (cnp->type) {
2080 1f1faf13 2014-05-11 pjp case DNS_TYPE_A:
2081 1f1faf13 2014-05-11 pjp tmplen = additional_a(cnp->name, cnp->namelen, cnp->sd, reply, replysize, outlen, &addcount);
2082 1f1faf13 2014-05-11 pjp additional += addcount;
2083 1f1faf13 2014-05-11 pjp break;
2084 1f1faf13 2014-05-11 pjp case DNS_TYPE_AAAA:
2085 1f1faf13 2014-05-11 pjp tmplen = additional_aaaa(cnp->name, cnp->namelen, cnp->sd, reply, replysize, outlen, &addcount);
2086 1f1faf13 2014-05-11 pjp additional += addcount;
2087 1f1faf13 2014-05-11 pjp break;
2088 1f1faf13 2014-05-11 pjp }
2089 1f1faf13 2014-05-11 pjp
2090 1f1faf13 2014-05-11 pjp if (tmplen > 0) {
2091 1f1faf13 2014-05-11 pjp outlen = tmplen;
2092 1f1faf13 2014-05-11 pjp }
2093 1f1faf13 2014-05-11 pjp }
2094 1f1faf13 2014-05-11 pjp
2095 1f1faf13 2014-05-11 pjp odh->additional = htons(additional);
2096 1f1faf13 2014-05-11 pjp
2097 1f1faf13 2014-05-11 pjp while (!SLIST_EMPTY(&collectshead)) {
2098 1f1faf13 2014-05-11 pjp cn1 = SLIST_FIRST(&collectshead);
2099 1f1faf13 2014-05-11 pjp SLIST_REMOVE_HEAD(&collectshead, collect_entry);
2100 1f1faf13 2014-05-11 pjp free(cn1->name);
2101 1f1faf13 2014-05-11 pjp free(cn1->sd);
2102 1f1faf13 2014-05-11 pjp free(cn1);
2103 1f1faf13 2014-05-11 pjp }
2104 1f1faf13 2014-05-11 pjp
2105 cd18f393 2014-05-10 pjp if (q->edns0len) {
2106 cd18f393 2014-05-10 pjp /* tag on edns0 opt record */
2107 cd18f393 2014-05-10 pjp NTOHS(odh->additional);
2108 cd18f393 2014-05-10 pjp odh->additional++;
2109 cd18f393 2014-05-10 pjp HTONS(odh->additional);
2110 cd18f393 2014-05-10 pjp
2111 cd18f393 2014-05-10 pjp outlen = additional_opt(q, reply, replysize, outlen);
2112 cd18f393 2014-05-10 pjp }
2113 cd18f393 2014-05-10 pjp
2114 df34d218 2014-04-21 pjp out:
2115 df34d218 2014-04-21 pjp if (sreply->sr != NULL) {
2116 a2b189d4 2014-10-08 pjp retlen = reply_raw2(so, reply, outlen, sreply->sr);
2117 df34d218 2014-04-21 pjp } else {
2118 df34d218 2014-04-21 pjp if (istcp) {
2119 df34d218 2014-04-21 pjp char *tmpbuf;
2120 df34d218 2014-04-21 pjp
2121 df34d218 2014-04-21 pjp tmpbuf = malloc(outlen + 2);
2122 df34d218 2014-04-21 pjp if (tmpbuf == NULL) {
2123 df34d218 2014-04-21 pjp dolog(LOG_INFO, "malloc: %s\n", strerror(errno));
2124 df34d218 2014-04-21 pjp }
2125 df34d218 2014-04-21 pjp plen = (u_int16_t *)tmpbuf;
2126 df34d218 2014-04-21 pjp *plen = htons(outlen);
2127 df34d218 2014-04-21 pjp
2128 df34d218 2014-04-21 pjp memcpy(&tmpbuf[2], reply, outlen);
2129 a2b189d4 2014-10-08 pjp if ((retlen = send(so, tmpbuf, outlen + 2, 0)) < 0) {
2130 df34d218 2014-04-21 pjp dolog(LOG_INFO, "send: %s\n", strerror(errno));
2131 df34d218 2014-04-21 pjp }
2132 df34d218 2014-04-21 pjp free(tmpbuf);
2133 df34d218 2014-04-21 pjp } else {
2134 a2b189d4 2014-10-08 pjp if ((retlen = sendto(so, reply, outlen, 0, sa, salen)) < 0) {
2135 df34d218 2014-04-21 pjp dolog(LOG_INFO, "sendto: %s\n", strerror(errno));
2136 df34d218 2014-04-21 pjp }
2137 df34d218 2014-04-21 pjp }
2138 df34d218 2014-04-21 pjp }
2139 df34d218 2014-04-21 pjp
2140 a2b189d4 2014-10-08 pjp return (retlen);
2141 df34d218 2014-04-21 pjp }
2142 df34d218 2014-04-21 pjp
2143 df34d218 2014-04-21 pjp
2144 6f8190d3 2012-04-30 pbug /*
2145 6f8190d3 2012-04-30 pbug * REPLY_SRV() - replies a DNS question (*q) on socket (so)
2146 6f8190d3 2012-04-30 pbug * (based on reply_mx)
2147 6f8190d3 2012-04-30 pbug */
2148 6f8190d3 2012-04-30 pbug
2149 6f8190d3 2012-04-30 pbug
2150 a2b189d4 2014-10-08 pjp int
2151 6f8190d3 2012-04-30 pbug reply_srv(struct sreply *sreply, DB *db)
2152 6f8190d3 2012-04-30 pbug {
2153 df34d218 2014-04-21 pjp char *reply = sreply->replybuf;
2154 6f8190d3 2012-04-30 pbug struct dns_header *odh;
2155 6f8190d3 2012-04-30 pbug struct domain *sd0;
2156 6f8190d3 2012-04-30 pbug int srv_count;
2157 6f8190d3 2012-04-30 pbug u_int16_t *plen;
2158 6f8190d3 2012-04-30 pbug char *name;
2159 6f8190d3 2012-04-30 pbug u_int16_t outlen;
2160 6f8190d3 2012-04-30 pbug u_int16_t namelen;
2161 6f8190d3 2012-04-30 pbug int additional = 0;
2162 6f8190d3 2012-04-30 pbug
2163 6f8190d3 2012-04-30 pbug struct answer {
2164 6f8190d3 2012-04-30 pbug char name[2];
2165 6f8190d3 2012-04-30 pbug u_int16_t type;
2166 6f8190d3 2012-04-30 pbug u_int16_t class;
2167 6f8190d3 2012-04-30 pbug u_int32_t ttl;
2168 6f8190d3 2012-04-30 pbug u_int16_t rdlength; /* 12 */
2169 6f8190d3 2012-04-30 pbug u_int16_t srv_priority;
2170 6f8190d3 2012-04-30 pbug u_int16_t srv_weight;
2171 6f8190d3 2012-04-30 pbug u_int16_t srv_port;
2172 6f8190d3 2012-04-30 pbug char target;
2173 6f8190d3 2012-04-30 pbug } __attribute__((packed));
2174 6f8190d3 2012-04-30 pbug
2175 6f8190d3 2012-04-30 pbug struct answer *answer;
2176 6f8190d3 2012-04-30 pbug
2177 6f8190d3 2012-04-30 pbug int so = sreply->so;
2178 6f8190d3 2012-04-30 pbug char *buf = sreply->buf;
2179 6f8190d3 2012-04-30 pbug int len = sreply->len;
2180 6f8190d3 2012-04-30 pbug struct question *q = sreply->q;
2181 6f8190d3 2012-04-30 pbug struct sockaddr *sa = sreply->sa;
2182 6f8190d3 2012-04-30 pbug int salen = sreply->salen;
2183 6f8190d3 2012-04-30 pbug struct domain *sd = sreply->sd1;
2184 6f8190d3 2012-04-30 pbug int istcp = sreply->istcp;
2185 6f8190d3 2012-04-30 pbug int wildcard = sreply->wildcard;
2186 df34d218 2014-04-21 pjp int replysize = 512;
2187 a2b189d4 2014-10-08 pjp int retlen = -1;
2188 df34d218 2014-04-21 pjp
2189 df34d218 2014-04-21 pjp if (istcp) {
2190 df34d218 2014-04-21 pjp replysize = 65535;
2191 df34d218 2014-04-21 pjp }
2192 6f8190d3 2012-04-30 pbug
2193 cd18f393 2014-05-10 pjp if (q->edns0len > 512)
2194 cd18f393 2014-05-10 pjp replysize = q->edns0len;
2195 6f8190d3 2012-04-30 pbug
2196 6f8190d3 2012-04-30 pbug odh = (struct dns_header *)&reply[0];
2197 6f8190d3 2012-04-30 pbug
2198 6f8190d3 2012-04-30 pbug outlen = sizeof(struct dns_header);
2199 6f8190d3 2012-04-30 pbug
2200 df34d218 2014-04-21 pjp if (len > replysize) {
2201 a2b189d4 2014-10-08 pjp return (retlen);
2202 6f8190d3 2012-04-30 pbug }
2203 6f8190d3 2012-04-30 pbug
2204 df34d218 2014-04-21 pjp memcpy(reply, buf, sizeof(struct dns_header) + q->hdr->namelen + 4);
2205 6f8190d3 2012-04-30 pbug memset((char *)&odh->query, 0, sizeof(u_int16_t));
2206 6f8190d3 2012-04-30 pbug
2207 6f8190d3 2012-04-30 pbug outlen += (q->hdr->namelen + 4);
2208 6f8190d3 2012-04-30 pbug
2209 6f8190d3 2012-04-30 pbug SET_DNS_REPLY(odh);
2210 6f8190d3 2012-04-30 pbug
2211 6f8190d3 2012-04-30 pbug if (sreply->sr == NULL) {
2212 6f8190d3 2012-04-30 pbug SET_DNS_AUTHORITATIVE(odh);
2213 6f8190d3 2012-04-30 pbug } else
2214 6f8190d3 2012-04-30 pbug SET_DNS_RECURSION_AVAIL(odh);
2215 6f8190d3 2012-04-30 pbug
2216 6f8190d3 2012-04-30 pbug HTONS(odh->query);
2217 fe42904f 2010-03-27 pbug
2218 6f8190d3 2012-04-30 pbug odh->question = htons(1);
2219 6f8190d3 2012-04-30 pbug odh->answer = htons(sd->srv_count);
2220 6f8190d3 2012-04-30 pbug odh->nsrr = 0;
2221 6f8190d3 2012-04-30 pbug odh->additional = 0;
2222 6f8190d3 2012-04-30 pbug
2223 6f8190d3 2012-04-30 pbug /* skip dns header, question name, qtype and qclass */
2224 6f8190d3 2012-04-30 pbug answer = (struct answer *)(&reply[0] + sizeof(struct dns_header) +
2225 6f8190d3 2012-04-30 pbug q->hdr->namelen + 4);
2226 6f8190d3 2012-04-30 pbug
2227 6f8190d3 2012-04-30 pbug srv_count = 0;
2228 6f8190d3 2012-04-30 pbug do {
2229 6f8190d3 2012-04-30 pbug answer->name[0] = 0xc0;
2230 6f8190d3 2012-04-30 pbug answer->name[1] = 0x0c;
2231 6f8190d3 2012-04-30 pbug answer->type = q->hdr->qtype;
2232 6f8190d3 2012-04-30 pbug answer->class = q->hdr->qclass;
2233 6f8190d3 2012-04-30 pbug if (sreply->sr != NULL)
2234 6f8190d3 2012-04-30 pbug answer->ttl = htonl(sd->ttl - (time(NULL) - sd->created));
2235 6f8190d3 2012-04-30 pbug else
2236 6f8190d3 2012-04-30 pbug answer->ttl = htonl(sd->ttl);
2237 6f8190d3 2012-04-30 pbug
2238 6f8190d3 2012-04-30 pbug answer->rdlength = htons((3 * sizeof(u_int16_t)) + sd->srv[srv_count].targetlen);
2239 6f8190d3 2012-04-30 pbug
2240 6f8190d3 2012-04-30 pbug answer->srv_priority = htons(sd->srv[srv_count].priority);
2241 6f8190d3 2012-04-30 pbug answer->srv_weight = htons(sd->srv[srv_count].weight);
2242 6f8190d3 2012-04-30 pbug answer->srv_port = htons(sd->srv[srv_count].port);
2243 6f8190d3 2012-04-30 pbug
2244 6f8190d3 2012-04-30 pbug memcpy((char *)&answer->target, (char *)sd->srv[srv_count].target, sd->srv[srv_count].targetlen);
2245 6f8190d3 2012-04-30 pbug
2246 6f8190d3 2012-04-30 pbug name = sd->srv[srv_count].target;
2247 6f8190d3 2012-04-30 pbug namelen = sd->srv[srv_count].targetlen;
2248 6f8190d3 2012-04-30 pbug
2249 6f8190d3 2012-04-30 pbug sd0 = Lookup_zone(db, name, namelen, htons(DNS_TYPE_A), wildcard);
2250 6f8190d3 2012-04-30 pbug if (sd0 != NULL) {
2251 6f8190d3 2012-04-30 pbug cn1 = malloc(sizeof(struct collects));
2252 6f8190d3 2012-04-30 pbug if (cn1 != NULL) {
2253 6f8190d3 2012-04-30 pbug cn1->name = malloc(namelen);
2254 6f8190d3 2012-04-30 pbug if (cn1->name != NULL) {
2255 6f8190d3 2012-04-30 pbug memcpy(cn1->name, name, namelen);
2256 6f8190d3 2012-04-30 pbug cn1->namelen = namelen;
2257 6f8190d3 2012-04-30 pbug cn1->sd = sd0;
2258 6f8190d3 2012-04-30 pbug cn1->type = DNS_TYPE_A;
2259 6f8190d3 2012-04-30 pbug
2260 c0963faf 2014-05-01 pjp SLIST_INSERT_HEAD(&collectshead, cn1, collect_entry);
2261 6f8190d3 2012-04-30 pbug }
2262 6f8190d3 2012-04-30 pbug }
2263 6f8190d3 2012-04-30 pbug }
2264 6f8190d3 2012-04-30 pbug sd0 = Lookup_zone(db, name, namelen, htons(DNS_TYPE_AAAA), wildcard);
2265 6f8190d3 2012-04-30 pbug if (sd0 != NULL) {
2266 6f8190d3 2012-04-30 pbug cn1 = malloc(sizeof(struct collects));
2267 6f8190d3 2012-04-30 pbug if (cn1 != NULL) {
2268 6f8190d3 2012-04-30 pbug cn1->name = malloc(namelen);
2269 6f8190d3 2012-04-30 pbug if (cn1->name != NULL) {
2270 6f8190d3 2012-04-30 pbug memcpy(cn1->name, name, namelen);
2271 6f8190d3 2012-04-30 pbug cn1->namelen = namelen;
2272 6f8190d3 2012-04-30 pbug cn1->sd = sd0;
2273 6f8190d3 2012-04-30 pbug cn1->type = DNS_TYPE_AAAA;
2274 6f8190d3 2012-04-30 pbug
2275 c0963faf 2014-05-01 pjp SLIST_INSERT_HEAD(&collectshead, cn1, collect_entry);
2276 6f8190d3 2012-04-30 pbug }
2277 6f8190d3 2012-04-30 pbug }
2278 6f8190d3 2012-04-30 pbug }
2279 6f8190d3 2012-04-30 pbug
2280 6f8190d3 2012-04-30 pbug outlen += (12 + 6 + sd->srv[srv_count].targetlen);
2281 6f8190d3 2012-04-30 pbug
2282 6f8190d3 2012-04-30 pbug /* can we afford to write another header? if no truncate */
2283 1f1faf13 2014-05-11 pjp if (sd->srv_count > 1 && (outlen + 12 + 6 + sd->srv[srv_count].targetlen) > replysize) {
2284 6f8190d3 2012-04-30 pbug NTOHS(odh->query);
2285 6f8190d3 2012-04-30 pbug SET_DNS_TRUNCATION(odh);
2286 6f8190d3 2012-04-30 pbug HTONS(odh->query);
2287 6f8190d3 2012-04-30 pbug goto out;
2288 6f8190d3 2012-04-30 pbug }
2289 6f8190d3 2012-04-30 pbug
2290 6f8190d3 2012-04-30 pbug /* set new offset for answer */
2291 6f8190d3 2012-04-30 pbug answer = (struct answer *)&reply[outlen];
2292 6f8190d3 2012-04-30 pbug } while (++srv_count < RECORD_COUNT && --sd->srv_count);
2293 6f8190d3 2012-04-30 pbug
2294 6f8190d3 2012-04-30 pbug /* write additional */
2295 6f8190d3 2012-04-30 pbug
2296 c0963faf 2014-05-01 pjp SLIST_FOREACH(cnp, &collectshead, collect_entry) {
2297 6f8190d3 2012-04-30 pbug int addcount;
2298 6f8190d3 2012-04-30 pbug int tmplen;
2299 6f8190d3 2012-04-30 pbug
2300 6f8190d3 2012-04-30 pbug switch (cnp->type) {
2301 6f8190d3 2012-04-30 pbug case DNS_TYPE_A:
2302 df34d218 2014-04-21 pjp tmplen = additional_a(cnp->name, cnp->namelen, cnp->sd, reply, replysize, outlen, &addcount);
2303 6f8190d3 2012-04-30 pbug additional += addcount;
2304 6f8190d3 2012-04-30 pbug break;
2305 6f8190d3 2012-04-30 pbug case DNS_TYPE_AAAA:
2306 df34d218 2014-04-21 pjp tmplen = additional_aaaa(cnp->name, cnp->namelen, cnp->sd, reply, replysize, outlen, &addcount);
2307 6f8190d3 2012-04-30 pbug additional += addcount;
2308 6f8190d3 2012-04-30 pbug break;
2309 6f8190d3 2012-04-30 pbug }
2310 6f8190d3 2012-04-30 pbug
2311 6f8190d3 2012-04-30 pbug if (tmplen > 0) {
2312 6f8190d3 2012-04-30 pbug outlen = tmplen;
2313 6f8190d3 2012-04-30 pbug }
2314 6f8190d3 2012-04-30 pbug }
2315 6f8190d3 2012-04-30 pbug
2316 6f8190d3 2012-04-30 pbug odh->additional = htons(additional);
2317 6f8190d3 2012-04-30 pbug
2318 6f8190d3 2012-04-30 pbug while (!SLIST_EMPTY(&collectshead)) {
2319 6f8190d3 2012-04-30 pbug cn1 = SLIST_FIRST(&collectshead);
2320 c0963faf 2014-05-01 pjp SLIST_REMOVE_HEAD(&collectshead, collect_entry);
2321 6f8190d3 2012-04-30 pbug free(cn1->name);
2322 6f8190d3 2012-04-30 pbug free(cn1->sd);
2323 6f8190d3 2012-04-30 pbug free(cn1);
2324 cd18f393 2014-05-10 pjp }
2325 cd18f393 2014-05-10 pjp
2326 cd18f393 2014-05-10 pjp if (q->edns0len) {
2327 cd18f393 2014-05-10 pjp /* tag on edns0 opt record */
2328 cd18f393 2014-05-10 pjp NTOHS(odh->additional);
2329 cd18f393 2014-05-10 pjp odh->additional++;
2330 cd18f393 2014-05-10 pjp HTONS(odh->additional);
2331 cd18f393 2014-05-10 pjp
2332 cd18f393 2014-05-10 pjp outlen = additional_opt(q, reply, replysize, outlen);
2333 6f8190d3 2012-04-30 pbug }
2334 6f8190d3 2012-04-30 pbug
2335 6f8190d3 2012-04-30 pbug out:
2336 6f8190d3 2012-04-30 pbug if (sreply->sr != NULL) {
2337 a2b189d4 2014-10-08 pjp retlen = reply_raw2(so, reply, outlen, sreply->sr);
2338 6f8190d3 2012-04-30 pbug } else {
2339 6f8190d3 2012-04-30 pbug if (istcp) {
2340 6f8190d3 2012-04-30 pbug char *tmpbuf;
2341 6f8190d3 2012-04-30 pbug
2342 6f8190d3 2012-04-30 pbug tmpbuf = malloc(outlen + 2);
2343 6f8190d3 2012-04-30 pbug if (tmpbuf == NULL) {
2344 dd869383 2013-02-16 pjp dolog(LOG_INFO, "malloc: %s\n", strerror(errno));
2345 6f8190d3 2012-04-30 pbug }
2346 6f8190d3 2012-04-30 pbug plen = (u_int16_t *)tmpbuf;
2347 6f8190d3 2012-04-30 pbug *plen = htons(outlen);
2348 6f8190d3 2012-04-30 pbug
2349 6f8190d3 2012-04-30 pbug memcpy(&tmpbuf[2], reply, outlen);
2350 a2b189d4 2014-10-08 pjp if ((retlen = send(so, tmpbuf, outlen + 2, 0)) < 0) {
2351 dd869383 2013-02-16 pjp dolog(LOG_INFO, "send: %s\n", strerror(errno));
2352 6f8190d3 2012-04-30 pbug }
2353 6f8190d3 2012-04-30 pbug free(tmpbuf);
2354 6f8190d3 2012-04-30 pbug } else {
2355 a2b189d4 2014-10-08 pjp if ((retlen = sendto(so, reply, outlen, 0, sa, salen)) < 0) {
2356 dd869383 2013-02-16 pjp dolog(LOG_INFO, "sendto: %s\n", strerror(errno));
2357 6f8190d3 2012-04-30 pbug }
2358 6f8190d3 2012-04-30 pbug }
2359 6f8190d3 2012-04-30 pbug }
2360 6f8190d3 2012-04-30 pbug
2361 a2b189d4 2014-10-08 pjp return (retlen);
2362 6f8190d3 2012-04-30 pbug }
2363 6f8190d3 2012-04-30 pbug
2364 6f8190d3 2012-04-30 pbug
2365 c45084ea 2005-11-29 pbug /*
2366 c45084ea 2005-11-29 pbug * REPLY_NOTIMPL - reply "Not Implemented"
2367 c45084ea 2005-11-29 pbug *
2368 c45084ea 2005-11-29 pbug */
2369 c45084ea 2005-11-29 pbug
2370 6f8190d3 2012-04-30 pbug
2371 a2b189d4 2014-10-08 pjp int
2372 c45084ea 2005-11-29 pbug reply_notimpl(struct sreply *sreply)
2373 c45084ea 2005-11-29 pbug {
2374 df34d218 2014-04-21 pjp char *reply = sreply->replybuf;
2375 c45084ea 2005-11-29 pbug struct dns_header *odh;
2376 b6dc64dc 2010-04-15 pbug u_int16_t outlen;
2377 c45084ea 2005-11-29 pbug
2378 c45084ea 2005-11-29 pbug int so = sreply->so;
2379 c45084ea 2005-11-29 pbug char *buf = sreply->buf;
2380 c45084ea 2005-11-29 pbug int len = sreply->len;
2381 c45084ea 2005-11-29 pbug struct sockaddr *sa = sreply->sa;
2382 c45084ea 2005-11-29 pbug int salen = sreply->salen;
2383 f1e3cfca 2010-03-12 pbug int istcp = sreply->istcp;
2384 df34d218 2014-04-21 pjp int replysize = 512;
2385 a2b189d4 2014-10-08 pjp int retlen = -1;
2386 c45084ea 2005-11-29 pbug
2387 df34d218 2014-04-21 pjp if (istcp) {
2388 df34d218 2014-04-21 pjp replysize = 65535;
2389 df34d218 2014-04-21 pjp }
2390 df34d218 2014-04-21 pjp
2391 c45084ea 2005-11-29 pbug #if 0
2392 c45084ea 2005-11-29 pbug struct domain *sd = sreply->sd1;
2393 c45084ea 2005-11-29 pbug struct question *q = sreply->q;
2394 c45084ea 2005-11-29 pbug #endif
2395 c45084ea 2005-11-29 pbug
2396 959d1769 2010-04-05 pbug odh = (struct dns_header *)&reply[0];
2397 f1e3cfca 2010-03-12 pbug
2398 c45084ea 2005-11-29 pbug outlen = sizeof(struct dns_header);
2399 c45084ea 2005-11-29 pbug
2400 df34d218 2014-04-21 pjp if (len > replysize) {
2401 a2b189d4 2014-10-08 pjp return (retlen);
2402 c45084ea 2005-11-29 pbug }
2403 c45084ea 2005-11-29 pbug
2404 df34d218 2014-04-21 pjp memcpy(reply, buf, len);
2405 f1e3cfca 2010-03-12 pbug
2406 c45084ea 2005-11-29 pbug memset((char *)&odh->query, 0, sizeof(u_int16_t));
2407 c45084ea 2005-11-29 pbug
2408 c45084ea 2005-11-29 pbug SET_DNS_REPLY(odh);
2409 c45084ea 2005-11-29 pbug SET_DNS_RCODE_NOTIMPL(odh);
2410 c45084ea 2005-11-29 pbug
2411 c45084ea 2005-11-29 pbug HTONS(odh->query);
2412 c45084ea 2005-11-29 pbug
2413 959d1769 2010-04-05 pbug
2414 f1e3cfca 2010-03-12 pbug if (istcp) {
2415 959d1769 2010-04-05 pbug char *tmpbuf;
2416 959d1769 2010-04-05 pbug u_int16_t *plen;
2417 959d1769 2010-04-05 pbug
2418 959d1769 2010-04-05 pbug tmpbuf = malloc(outlen + 2);
2419 959d1769 2010-04-05 pbug if (tmpbuf == NULL) {
2420 dd869383 2013-02-16 pjp dolog(LOG_INFO, "malloc: %s\n", strerror(errno));
2421 959d1769 2010-04-05 pbug }
2422 959d1769 2010-04-05 pbug plen = (u_int16_t *)tmpbuf;
2423 959d1769 2010-04-05 pbug *plen = htons(outlen);
2424 959d1769 2010-04-05 pbug
2425 959d1769 2010-04-05 pbug memcpy(&tmpbuf[2], reply, outlen);
2426 959d1769 2010-04-05 pbug
2427 a2b189d4 2014-10-08 pjp if ((retlen = send(so, tmpbuf, outlen + 2, 0)) < 0) {
2428 dd869383 2013-02-16 pjp dolog(LOG_INFO, "send: %s\n", strerror(errno));
2429 f1e3cfca 2010-03-12 pbug }
2430 959d1769 2010-04-05 pbug free(tmpbuf);
2431 f1e3cfca 2010-03-12 pbug } else {
2432 a2b189d4 2014-10-08 pjp if ((retlen = sendto(so, reply, len, 0, sa, salen)) < 0) {
2433 dd869383 2013-02-16 pjp dolog(LOG_INFO, "sendto: %s\n", strerror(errno));
2434 f1e3cfca 2010-03-12 pbug }
2435 c45084ea 2005-11-29 pbug }
2436 c45084ea 2005-11-29 pbug
2437 a2b189d4 2014-10-08 pjp return (retlen);
2438 c45084ea 2005-11-29 pbug }
2439 c45084ea 2005-11-29 pbug
2440 c45084ea 2005-11-29 pbug /*
2441 c45084ea 2005-11-29 pbug * REPLY_NXDOMAIN() - replies a DNS question (*q) on socket (so)
2442 c45084ea 2005-11-29 pbug *
2443 c45084ea 2005-11-29 pbug */
2444 c45084ea 2005-11-29 pbug
2445 a2b189d4 2014-10-08 pjp int
2446 c45084ea 2005-11-29 pbug reply_nxdomain(struct sreply *sreply)
2447 c45084ea 2005-11-29 pbug {
2448 df34d218 2014-04-21 pjp char *reply = sreply->replybuf;
2449 c45084ea 2005-11-29 pbug struct dns_header *odh;
2450 b6dc64dc 2010-04-15 pbug u_int16_t outlen;
2451 d6a24f1e 2008-07-24 pbug char *p;
2452 d6a24f1e 2008-07-24 pbug u_int32_t *soa_val;
2453 d6a24f1e 2008-07-24 pbug int i, tmplen;
2454 d6a24f1e 2008-07-24 pbug int labellen;
2455 d6a24f1e 2008-07-24 pbug char *label, *plabel;
2456 c45084ea 2005-11-29 pbug
2457 d6a24f1e 2008-07-24 pbug struct answer {
2458 d6a24f1e 2008-07-24 pbug char name[2];
2459 d6a24f1e 2008-07-24 pbug u_int16_t type;
2460 d6a24f1e 2008-07-24 pbug u_int16_t class;
2461 d6a24f1e 2008-07-24 pbug u_int32_t ttl;
2462 d6a24f1e 2008-07-24 pbug u_int16_t rdlength; /* 12 */
2463 d6a24f1e 2008-07-24 pbug char rdata;
2464 d6a24f1e 2008-07-24 pbug } __attribute__((packed));
2465 d6a24f1e 2008-07-24 pbug
2466 d6a24f1e 2008-07-24 pbug struct soa {
2467 d6a24f1e 2008-07-24 pbug char *nsserver;
2468 d6a24f1e 2008-07-24 pbug char *responsible_person;
2469 d6a24f1e 2008-07-24 pbug u_int32_t serial;
2470 d6a24f1e 2008-07-24 pbug u_int32_t refresh;
2471 d6a24f1e 2008-07-24 pbug u_int32_t retry;
2472 d6a24f1e 2008-07-24 pbug u_int32_t expire;
2473 d6a24f1e 2008-07-24 pbug u_int32_t minttl;
2474 d6a24f1e 2008-07-24 pbug };
2475 d6a24f1e 2008-07-24 pbug
2476 d6a24f1e 2008-07-24 pbug
2477 d6a24f1e 2008-07-24 pbug struct answer *answer;
2478 d6a24f1e 2008-07-24 pbug
2479 c45084ea 2005-11-29 pbug int so = sreply->so;
2480 c45084ea 2005-11-29 pbug char *buf = sreply->buf;
2481 c45084ea 2005-11-29 pbug int len = sreply->len;
2482 d6a24f1e 2008-07-24 pbug struct question *q = sreply->q;
2483 c45084ea 2005-11-29 pbug struct sockaddr *sa = sreply->sa;
2484 c45084ea 2005-11-29 pbug int salen = sreply->salen;
2485 c45084ea 2005-11-29 pbug struct domain *sd = sreply->sd1;
2486 f1e3cfca 2010-03-12 pbug int istcp = sreply->istcp;
2487 df34d218 2014-04-21 pjp int replysize = 512;
2488 a2b189d4 2014-10-08 pjp int retlen = -1;
2489 df34d218 2014-04-21 pjp
2490 df34d218 2014-04-21 pjp if (istcp) {
2491 df34d218 2014-04-21 pjp replysize = 65535;
2492 df34d218 2014-04-21 pjp }
2493 c45084ea 2005-11-29 pbug
2494 c45084ea 2005-11-29 pbug odh = (struct dns_header *)&reply[0];
2495 c45084ea 2005-11-29 pbug outlen = sizeof(struct dns_header);
2496 c45084ea 2005-11-29 pbug
2497 df34d218 2014-04-21 pjp if (len > replysize) {
2498 a2b189d4 2014-10-08 pjp return (retlen);
2499 d6a24f1e 2008-07-24 pbug
2500 c45084ea 2005-11-29 pbug }
2501 c45084ea 2005-11-29 pbug
2502 d6a24f1e 2008-07-24 pbug /*
2503 d6a24f1e 2008-07-24 pbug * no SOA, use the old code
2504 d6a24f1e 2008-07-24 pbug */
2505 d6a24f1e 2008-07-24 pbug
2506 d6a24f1e 2008-07-24 pbug if ((sd->flags & DOMAIN_HAVE_SOA) != DOMAIN_HAVE_SOA) {
2507 d6a24f1e 2008-07-24 pbug
2508 df34d218 2014-04-21 pjp memcpy(reply, buf, len);
2509 d6a24f1e 2008-07-24 pbug memset((char *)&odh->query, 0, sizeof(u_int16_t));
2510 d6a24f1e 2008-07-24 pbug
2511 d6a24f1e 2008-07-24 pbug SET_DNS_REPLY(odh);
2512 df7b3e7e 2010-09-25 pbug #if 1
2513 df7b3e7e 2010-09-25 pbug if (sreply->sr != NULL) {
2514 df7b3e7e 2010-09-25 pbug SET_DNS_RECURSION_AVAIL(odh);
2515 df7b3e7e 2010-09-25 pbug }
2516 df7b3e7e 2010-09-25 pbug #endif
2517 d6a24f1e 2008-07-24 pbug SET_DNS_RCODE_NAMEERR(odh);
2518 d6a24f1e 2008-07-24 pbug
2519 df7b3e7e 2010-09-25 pbug
2520 df7b3e7e 2010-09-25 pbug
2521 d6a24f1e 2008-07-24 pbug HTONS(odh->query);
2522 df7b3e7e 2010-09-25 pbug if (sreply->sr != NULL) {
2523 a2b189d4 2014-10-08 pjp retlen = reply_raw2(so, reply, len, sreply->sr);
2524 df7b3e7e 2010-09-25 pbug } else {
2525 df7b3e7e 2010-09-25 pbug if (istcp) {
2526 df7b3e7e 2010-09-25 pbug char *tmpbuf;
2527 df7b3e7e 2010-09-25 pbug u_int16_t *plen;
2528 d6a24f1e 2008-07-24 pbug
2529 df7b3e7e 2010-09-25 pbug tmpbuf = malloc(len + 2);
2530 df7b3e7e 2010-09-25 pbug if (tmpbuf == NULL) {
2531 dd869383 2013-02-16 pjp dolog(LOG_INFO, "malloc: %s\n", strerror(errno));
2532 df7b3e7e 2010-09-25 pbug }
2533 df7b3e7e 2010-09-25 pbug plen = (u_int16_t *)tmpbuf;
2534 df7b3e7e 2010-09-25 pbug *plen = htons(len);
2535 df7b3e7e 2010-09-25 pbug
2536 df7b3e7e 2010-09-25 pbug memcpy(&tmpbuf[2], reply, len);
2537 f1e3cfca 2010-03-12 pbug
2538 a2b189d4 2014-10-08 pjp if ((retlen = send(so, tmpbuf, len + 2, 0)) < 0) {
2539 dd869383 2013-02-16 pjp dolog(LOG_INFO, "send: %s\n", strerror(errno));
2540 df7b3e7e 2010-09-25 pbug }
2541 df7b3e7e 2010-09-25 pbug free(tmpbuf);
2542 df7b3e7e 2010-09-25 pbug } else {
2543 a2b189d4 2014-10-08 pjp if ((retlen = sendto(so, reply, len, 0, sa, salen)) < 0) {
2544 dd869383 2013-02-16 pjp dolog(LOG_INFO, "sendto: %s\n", strerror(errno));
2545 df7b3e7e 2010-09-25 pbug }
2546 f1e3cfca 2010-03-12 pbug }
2547 d6a24f1e 2008-07-24 pbug }
2548 d6a24f1e 2008-07-24 pbug
2549 a2b189d4 2014-10-08 pjp return (retlen);
2550 d6a24f1e 2008-07-24 pbug }
2551 d6a24f1e 2008-07-24 pbug
2552 d6a24f1e 2008-07-24 pbug /* copy question to reply */
2553 df34d218 2014-04-21 pjp memcpy(reply, buf, sizeof(struct dns_header) + q->hdr->namelen + 4);
2554 d6a24f1e 2008-07-24 pbug /* blank query */
2555 c45084ea 2005-11-29 pbug memset((char *)&odh->query, 0, sizeof(u_int16_t));
2556 c45084ea 2005-11-29 pbug
2557 d6a24f1e 2008-07-24 pbug outlen += (q->hdr->namelen + 4);
2558 d6a24f1e 2008-07-24 pbug
2559 c45084ea 2005-11-29 pbug SET_DNS_REPLY(odh);
2560 df7b3e7e 2010-09-25 pbug if (sreply->sr != NULL)
2561 df7b3e7e 2010-09-25 pbug SET_DNS_RECURSION_AVAIL(odh);
2562 df7b3e7e 2010-09-25 pbug else
2563 df7b3e7e 2010-09-25 pbug SET_DNS_AUTHORITATIVE(odh);
2564 df7b3e7e 2010-09-25 pbug
2565 c45084ea 2005-11-29 pbug SET_DNS_RCODE_NAMEERR(odh);
2566 d6a24f1e 2008-07-24 pbug
2567 d6a24f1e 2008-07-24 pbug NTOHS(odh->query);
2568 c45084ea 2005-11-29 pbug
2569 5841985a 2010-03-18 pbug odh->question = htons(1);
2570 d6a24f1e 2008-07-24 pbug odh->answer = 0;
2571 5841985a 2010-03-18 pbug odh->nsrr = htons(1);
2572 d6a24f1e 2008-07-24 pbug odh->additional = 0;
2573 c45084ea 2005-11-29 pbug
2574 d6a24f1e 2008-07-24 pbug answer = (struct answer *)(&reply[0] + sizeof(struct dns_header) +
2575 d6a24f1e 2008-07-24 pbug q->hdr->namelen + 4);
2576 d6a24f1e 2008-07-24 pbug
2577 d6a24f1e 2008-07-24 pbug answer->name[0] = 0xc0;
2578 d6a24f1e 2008-07-24 pbug answer->name[1] = 0x0c;
2579 d6a24f1e 2008-07-24 pbug answer->type = htons(DNS_TYPE_SOA);
2580 d6a24f1e 2008-07-24 pbug answer->class = q->hdr->qclass;
2581 df7b3e7e 2010-09-25 pbug if (sreply->sr != NULL)
2582 df7b3e7e 2010-09-25 pbug answer->ttl = htonl(sd->ttl - (time(NULL) - sd->created));
2583 df7b3e7e 2010-09-25 pbug else
2584 df7b3e7e 2010-09-25 pbug answer->ttl = htonl(sd->ttl);
2585 d6a24f1e 2008-07-24 pbug
2586 d6a24f1e 2008-07-24 pbug outlen += 12; /* up to rdata length */
2587 d6a24f1e 2008-07-24 pbug
2588 d6a24f1e 2008-07-24 pbug p = (char *)&answer->rdata;
2589 d6a24f1e 2008-07-24 pbug
2590 d6a24f1e 2008-07-24 pbug #if 0
2591 f98bb34d 2011-09-19 pbug label = dns_label((char *)mysoa.nsserver, &labellen);
2592 d6a24f1e 2008-07-24 pbug if (label == NULL)
2593 a2b189d4 2014-10-08 pjp return (retlen);
2594 d6a24f1e 2008-07-24 pbug #endif
2595 d6a24f1e 2008-07-24 pbug
2596 f98bb34d 2011-09-19 pbug label = &sd->soa.nsserver[0];
2597 f98bb34d 2011-09-19 pbug labellen = sd->soa.nsserver_len;
2598 d6a24f1e 2008-07-24 pbug
2599 d6a24f1e 2008-07-24 pbug plabel = label;
2600 d6a24f1e 2008-07-24 pbug
2601 d6a24f1e 2008-07-24 pbug /* copy label to reply */
2602 df34d218 2014-04-21 pjp for (i = outlen; i < replysize; i++) {
2603 d6a24f1e 2008-07-24 pbug if (i - outlen == labellen)
2604 d6a24f1e 2008-07-24 pbug break;
2605 d6a24f1e 2008-07-24 pbug
2606 d6a24f1e 2008-07-24 pbug reply[i] = *plabel++;
2607 d6a24f1e 2008-07-24 pbug }
2608 d6a24f1e 2008-07-24 pbug
2609 df34d218 2014-04-21 pjp if (i >= replysize) {
2610 a2b189d4 2014-10-08 pjp return (retlen);
2611 d6a24f1e 2008-07-24 pbug }
2612 d6a24f1e 2008-07-24 pbug
2613 d6a24f1e 2008-07-24 pbug outlen = i;
2614 d6a24f1e 2008-07-24 pbug
2615 d6a24f1e 2008-07-24 pbug /* compress the label if possible */
2616 c5bcfb5c 2010-07-27 pbug if ((tmplen = compress_label((u_char*)reply, outlen, labellen)) > 0) {
2617 d6a24f1e 2008-07-24 pbug outlen = tmplen;
2618 d6a24f1e 2008-07-24 pbug }
2619 d6a24f1e 2008-07-24 pbug
2620 f98bb34d 2011-09-19 pbug label = sd->soa.responsible_person;
2621 f98bb34d 2011-09-19 pbug labellen = sd->soa.rp_len;
2622 d6a24f1e 2008-07-24 pbug plabel = label;
2623 d6a24f1e 2008-07-24 pbug
2624 df34d218 2014-04-21 pjp for (i = outlen; i < replysize; i++) {
2625 d6a24f1e 2008-07-24 pbug if (i - outlen == labellen)
2626 d6a24f1e 2008-07-24 pbug break;
2627 d6a24f1e 2008-07-24 pbug
2628 d6a24f1e 2008-07-24 pbug reply[i] = *plabel++;
2629 d6a24f1e 2008-07-24 pbug }
2630 d6a24f1e 2008-07-24 pbug
2631 df34d218 2014-04-21 pjp if (i >= replysize) {
2632 a2b189d4 2014-10-08 pjp return (retlen);
2633 d6a24f1e 2008-07-24 pbug }
2634 d6a24f1e 2008-07-24 pbug
2635 d6a24f1e 2008-07-24 pbug outlen = i;
2636 d6a24f1e 2008-07-24 pbug
2637 d6a24f1e 2008-07-24 pbug /* 2 compress the label if possible */
2638 d6a24f1e 2008-07-24 pbug
2639 c5bcfb5c 2010-07-27 pbug if ((tmplen = compress_label((u_char*)reply, outlen, labellen)) > 0) {
2640 d6a24f1e 2008-07-24 pbug outlen = tmplen;
2641 d6a24f1e 2008-07-24 pbug }
2642 d6a24f1e 2008-07-24 pbug
2643 d6a24f1e 2008-07-24 pbug
2644 1a591502 2010-03-28 pbug /* XXX */
2645 df34d218 2014-04-21 pjp if ((outlen + sizeof(sd->soa.serial)) > replysize) {
2646 d6a24f1e 2008-07-24 pbug /* XXX server error reply? */
2647 a2b189d4 2014-10-08 pjp return (retlen);
2648 d6a24f1e 2008-07-24 pbug }
2649 d6a24f1e 2008-07-24 pbug soa_val = (u_int32_t *)&reply[outlen];
2650 f98bb34d 2011-09-19 pbug *soa_val = htonl(sd->soa.serial);
2651 f98bb34d 2011-09-19 pbug outlen += sizeof(sd->soa.serial);
2652 d6a24f1e 2008-07-24 pbug
2653 df34d218 2014-04-21 pjp if ((outlen + sizeof(sd->soa.refresh)) > replysize) {
2654 a2b189d4 2014-10-08 pjp return (retlen);
2655 d6a24f1e 2008-07-24 pbug }
2656 d6a24f1e 2008-07-24 pbug soa_val = (u_int32_t *)&reply[outlen];
2657 f98bb34d 2011-09-19 pbug *soa_val = htonl(sd->soa.refresh);
2658 f98bb34d 2011-09-19 pbug outlen += sizeof(sd->soa.refresh);
2659 d6a24f1e 2008-07-24 pbug
2660 df34d218 2014-04-21 pjp if ((outlen + sizeof(sd->soa.retry)) > replysize) {
2661 a2b189d4 2014-10-08 pjp return (retlen);
2662 d6a24f1e 2008-07-24 pbug }
2663 d6a24f1e 2008-07-24 pbug soa_val = (u_int32_t *)&reply[outlen];
2664 f98bb34d 2011-09-19 pbug *soa_val = htonl(sd->soa.retry);
2665 f98bb34d 2011-09-19 pbug outlen += sizeof(sd->soa.retry);
2666 d6a24f1e 2008-07-24 pbug
2667 df34d218 2014-04-21 pjp if ((outlen + sizeof(sd->soa.expire)) > replysize) {
2668 a2b189d4 2014-10-08 pjp return (retlen);
2669 d6a24f1e 2008-07-24 pbug }
2670 d6a24f1e 2008-07-24 pbug soa_val = (u_int32_t *)&reply[outlen];
2671 f98bb34d 2011-09-19 pbug *soa_val = htonl(sd->soa.expire);
2672 f98bb34d 2011-09-19 pbug outlen += sizeof(sd->soa.expire);
2673 d6a24f1e 2008-07-24 pbug
2674 df34d218 2014-04-21 pjp if ((outlen + sizeof(sd->soa.minttl)) > replysize) {
2675 a2b189d4 2014-10-08 pjp return (retlen);
2676 d6a24f1e 2008-07-24 pbug }
2677 d6a24f1e 2008-07-24 pbug soa_val = (u_int32_t *)&reply[outlen];
2678 f98bb34d 2011-09-19 pbug *soa_val = htonl(sd->soa.minttl);
2679 f98bb34d 2011-09-19 pbug outlen += sizeof(sd->soa.minttl);
2680 d6a24f1e 2008-07-24 pbug
2681 d6a24f1e 2008-07-24 pbug answer->rdlength = htons(&reply[outlen] - &answer->rdata);
2682 df7b3e7e 2010-09-25 pbug
2683 df7b3e7e 2010-09-25 pbug if (sreply->sr != NULL) {
2684 a2b189d4 2014-10-08 pjp retlen = reply_raw2(so, reply, outlen, sreply->sr);
2685 df7b3e7e 2010-09-25 pbug } else {
2686 d6a24f1e 2008-07-24 pbug
2687 df7b3e7e 2010-09-25 pbug if (istcp) {
2688 df7b3e7e 2010-09-25 pbug char *tmpbuf;
2689 df7b3e7e 2010-09-25 pbug u_int16_t *plen;
2690 f1e3cfca 2010-03-12 pbug
2691 df7b3e7e 2010-09-25 pbug tmpbuf = malloc(outlen + 2);
2692 df7b3e7e 2010-09-25 pbug if (tmpbuf == NULL) {
2693 dd869383 2013-02-16 pjp dolog(LOG_INFO, "malloc: %s\n", strerror(errno));
2694 df7b3e7e 2010-09-25 pbug }
2695 df7b3e7e 2010-09-25 pbug plen = (u_int16_t *)tmpbuf;
2696 df7b3e7e 2010-09-25 pbug *plen = htons(outlen);
2697 df7b3e7e 2010-09-25 pbug
2698 df7b3e7e 2010-09-25 pbug memcpy(&tmpbuf[2], reply, outlen);
2699 f1e3cfca 2010-03-12 pbug
2700 a2b189d4 2014-10-08 pjp if ((retlen = send(so, tmpbuf, outlen + 2, 0)) < 0) {
2701 dd869383 2013-02-16 pjp dolog(LOG_INFO, "send: %s\n", strerror(errno));
2702 df7b3e7e 2010-09-25 pbug }
2703 df7b3e7e 2010-09-25 pbug free(tmpbuf);
2704 df7b3e7e 2010-09-25 pbug } else {
2705 a2b189d4 2014-10-08 pjp if ((retlen = sendto(so, reply, outlen, 0, sa, salen)) < 0) {
2706 dd869383 2013-02-16 pjp dolog(LOG_INFO, "sendto: %s\n", strerror(errno));
2707 df7b3e7e 2010-09-25 pbug }
2708 f1e3cfca 2010-03-12 pbug }
2709 df7b3e7e 2010-09-25 pbug } /* sreply->sr.. */
2710 f665f992 2005-12-01 pbug
2711 a2b189d4 2014-10-08 pjp return (retlen);
2712 f665f992 2005-12-01 pbug }
2713 f665f992 2005-12-01 pbug
2714 f665f992 2005-12-01 pbug /*
2715 c0963faf 2014-05-01 pjp * REPLY_REFUSED() - replies a DNS question (*q) on socket (so)
2716 c0963faf 2014-05-01 pjp *
2717 c0963faf 2014-05-01 pjp */
2718 c0963faf 2014-05-01 pjp
2719 a2b189d4 2014-10-08 pjp int
2720 c0963faf 2014-05-01 pjp reply_refused(struct sreply *sreply)
2721 c0963faf 2014-05-01 pjp {
2722 c0963faf 2014-05-01 pjp char *reply = sreply->replybuf;
2723 c0963faf 2014-05-01 pjp struct dns_header *odh;
2724 c0963faf 2014-05-01 pjp u_int16_t outlen;
2725 c0963faf 2014-05-01 pjp
2726 c0963faf 2014-05-01 pjp int so = sreply->so;
2727 c0963faf 2014-05-01 pjp int len = sreply->len;
2728 c0963faf 2014-05-01 pjp char *buf = sreply->buf;
2729 c0963faf 2014-05-01 pjp struct sockaddr *sa = sreply->sa;
2730 c0963faf 2014-05-01 pjp int salen = sreply->salen;
2731 c0963faf 2014-05-01 pjp int istcp = sreply->istcp;
2732 c0963faf 2014-05-01 pjp int replysize = 512;
2733 a2b189d4 2014-10-08 pjp int retlen = -1;
2734 c0963faf 2014-05-01 pjp
2735 c0963faf 2014-05-01 pjp if (istcp) {
2736 c0963faf 2014-05-01 pjp replysize = 65535;
2737 c0963faf 2014-05-01 pjp }
2738 c0963faf 2014-05-01 pjp
2739 c0963faf 2014-05-01 pjp memset(reply, 0, replysize);
2740 c0963faf 2014-05-01 pjp
2741 c0963faf 2014-05-01 pjp odh = (struct dns_header *)&reply[0];
2742 c0963faf 2014-05-01 pjp
2743 c0963faf 2014-05-01 pjp outlen = sizeof(struct dns_header);
2744 c0963faf 2014-05-01 pjp
2745 c0963faf 2014-05-01 pjp if (len > replysize) {
2746 a2b189d4 2014-10-08 pjp return (retlen);
2747 c0963faf 2014-05-01 pjp }
2748 c0963faf 2014-05-01 pjp
2749 c0963faf 2014-05-01 pjp memcpy((char *)&odh->id, buf, sizeof(u_int16_t));
2750 c0963faf 2014-05-01 pjp memset((char *)&odh->query, 0, sizeof(u_int16_t));
2751 c0963faf 2014-05-01 pjp
2752 c0963faf 2014-05-01 pjp SET_DNS_REPLY(odh);
2753 c0963faf 2014-05-01 pjp SET_DNS_RCODE_REFUSED(odh);
2754 c0963faf 2014-05-01 pjp
2755 c0963faf 2014-05-01 pjp HTONS(odh->query);
2756 c0963faf 2014-05-01 pjp
2757 c0963faf 2014-05-01 pjp if (istcp) {
2758 c0963faf 2014-05-01 pjp char *tmpbuf;
2759 c0963faf 2014-05-01 pjp u_int16_t *plen;
2760 c0963faf 2014-05-01 pjp
2761 c0963faf 2014-05-01 pjp tmpbuf = malloc(outlen + 2);
2762 c0963faf 2014-05-01 pjp if (tmpbuf == NULL) {
2763 c0963faf 2014-05-01 pjp dolog(LOG_INFO, "malloc: %s\n", strerror(errno));
2764 c0963faf 2014-05-01 pjp }
2765 c0963faf 2014-05-01 pjp plen = (u_int16_t *)tmpbuf;
2766 c0963faf 2014-05-01 pjp *plen = htons(outlen);
2767 c0963faf 2014-05-01 pjp
2768 c0963faf 2014-05-01 pjp memcpy(&tmpbuf[2], reply, outlen);
2769 c0963faf 2014-05-01 pjp
2770 a2b189d4 2014-10-08 pjp if ((retlen = send(so, tmpbuf, outlen + 2, 0)) < 0) {
2771 c0963faf 2014-05-01 pjp dolog(LOG_INFO, "send: %s\n", strerror(errno));
2772 c0963faf 2014-05-01 pjp }
2773 c0963faf 2014-05-01 pjp free(tmpbuf);
2774 c0963faf 2014-05-01 pjp } else {
2775 a2b189d4 2014-10-08 pjp if ((retlen = sendto(so, reply, sizeof(struct dns_header), 0, sa, salen)) < 0) {
2776 c0963faf 2014-05-01 pjp dolog(LOG_INFO, "sendto: %s\n", strerror(errno));
2777 c0963faf 2014-05-01 pjp }
2778 c0963faf 2014-05-01 pjp }
2779 c0963faf 2014-05-01 pjp
2780 a2b189d4 2014-10-08 pjp return (retlen);
2781 c0963faf 2014-05-01 pjp }
2782 c0963faf 2014-05-01 pjp
2783 c0963faf 2014-05-01 pjp /*
2784 f665f992 2005-12-01 pbug * REPLY_FMTERROR() - replies a DNS question (*q) on socket (so)
2785 f665f992 2005-12-01 pbug *
2786 f665f992 2005-12-01 pbug */
2787 f665f992 2005-12-01 pbug
2788 a2b189d4 2014-10-08 pjp int
2789 f665f992 2005-12-01 pbug reply_fmterror(struct sreply *sreply)
2790 f665f992 2005-12-01 pbug {
2791 df34d218 2014-04-21 pjp char *reply = sreply->replybuf;
2792 f665f992 2005-12-01 pbug struct dns_header *odh;
2793 b6dc64dc 2010-04-15 pbug u_int16_t outlen;
2794 f665f992 2005-12-01 pbug
2795 f665f992 2005-12-01 pbug int so = sreply->so;
2796 f665f992 2005-12-01 pbug int len = sreply->len;
2797 f665f992 2005-12-01 pbug char *buf = sreply->buf;
2798 f665f992 2005-12-01 pbug struct sockaddr *sa = sreply->sa;
2799 f665f992 2005-12-01 pbug int salen = sreply->salen;
2800 f1e3cfca 2010-03-12 pbug int istcp = sreply->istcp;
2801 df34d218 2014-04-21 pjp int replysize = 512;
2802 a2b189d4 2014-10-08 pjp int retlen = -1;
2803 f665f992 2005-12-01 pbug
2804 df34d218 2014-04-21 pjp if (istcp) {
2805 df34d218 2014-04-21 pjp replysize = 65535;
2806 df34d218 2014-04-21 pjp }
2807 f1e3cfca 2010-03-12 pbug
2808 df34d218 2014-04-21 pjp memset(reply, 0, replysize);
2809 df34d218 2014-04-21 pjp
2810 959d1769 2010-04-05 pbug odh = (struct dns_header *)&reply[0];
2811 f1e3cfca 2010-03-12 pbug
2812 f665f992 2005-12-01 pbug outlen = sizeof(struct dns_header);
2813 f665f992 2005-12-01 pbug
2814 df34d218 2014-04-21 pjp if (len > replysize) {
2815 a2b189d4 2014-10-08 pjp return (retlen);
2816 f665f992 2005-12-01 pbug }
2817 f665f992 2005-12-01 pbug
2818 f665f992 2005-12-01 pbug memcpy((char *)&odh->id, buf, sizeof(u_int16_t));
2819 f665f992 2005-12-01 pbug memset((char *)&odh->query, 0, sizeof(u_int16_t));
2820 f665f992 2005-12-01 pbug
2821 f665f992 2005-12-01 pbug SET_DNS_REPLY(odh);
2822 f665f992 2005-12-01 pbug SET_DNS_RCODE_FORMATERR(odh);
2823 f665f992 2005-12-01 pbug
2824 f665f992 2005-12-01 pbug HTONS(odh->query);
2825 f665f992 2005-12-01 pbug
2826 f1e3cfca 2010-03-12 pbug if (istcp) {
2827 959d1769 2010-04-05 pbug char *tmpbuf;
2828 959d1769 2010-04-05 pbug u_int16_t *plen;
2829 959d1769 2010-04-05 pbug
2830 959d1769 2010-04-05 pbug tmpbuf = malloc(outlen + 2);
2831 959d1769 2010-04-05 pbug if (tmpbuf == NULL) {
2832 dd869383 2013-02-16 pjp dolog(LOG_INFO, "malloc: %s\n", strerror(errno));
2833 959d1769 2010-04-05 pbug }
2834 959d1769 2010-04-05 pbug plen = (u_int16_t *)tmpbuf;
2835 959d1769 2010-04-05 pbug *plen = htons(outlen);
2836 959d1769 2010-04-05 pbug
2837 959d1769 2010-04-05 pbug memcpy(&tmpbuf[2], reply, outlen);
2838 959d1769 2010-04-05 pbug
2839 a2b189d4 2014-10-08 pjp if ((retlen = send(so, tmpbuf, outlen + 2, 0)) < 0) {
2840 dd869383 2013-02-16 pjp dolog(LOG_INFO, "send: %s\n", strerror(errno));
2841 f1e3cfca 2010-03-12 pbug }
2842 959d1769 2010-04-05 pbug free(tmpbuf);
2843 f1e3cfca 2010-03-12 pbug } else {
2844 a2b189d4 2014-10-08 pjp if ((retlen = sendto(so, reply, sizeof(struct dns_header), 0, sa, salen)) < 0) {
2845 dd869383 2013-02-16 pjp dolog(LOG_INFO, "sendto: %s\n", strerror(errno));
2846 f1e3cfca 2010-03-12 pbug }
2847 8c7bdc7c 2009-03-07 pbug }
2848 8c7bdc7c 2009-03-07 pbug
2849 a2b189d4 2014-10-08 pjp return (retlen);
2850 8c7bdc7c 2009-03-07 pbug }
2851 8c7bdc7c 2009-03-07 pbug
2852 8c7bdc7c 2009-03-07 pbug /*
2853 8c7bdc7c 2009-03-07 pbug * REPLY_NOERROR() - replies a DNS question (*q) on socket (so)
2854 8c7bdc7c 2009-03-07 pbug * based on reply_nxdomain
2855 8c7bdc7c 2009-03-07 pbug *
2856 8c7bdc7c 2009-03-07 pbug */
2857 8c7bdc7c 2009-03-07 pbug
2858 a2b189d4 2014-10-08 pjp int
2859 8c7bdc7c 2009-03-07 pbug reply_noerror(struct sreply *sreply)
2860 8c7bdc7c 2009-03-07 pbug {
2861 df34d218 2014-04-21 pjp char *reply = sreply->replybuf;
2862 8c7bdc7c 2009-03-07 pbug struct dns_header *odh;
2863 b6dc64dc 2010-04-15 pbug u_int16_t outlen;
2864 8c7bdc7c 2009-03-07 pbug char *p;
2865 8c7bdc7c 2009-03-07 pbug u_int32_t *soa_val;
2866 8c7bdc7c 2009-03-07 pbug int i, tmplen;
2867 8c7bdc7c 2009-03-07 pbug int labellen;
2868 8c7bdc7c 2009-03-07 pbug char *label, *plabel;
2869 8c7bdc7c 2009-03-07 pbug
2870 8c7bdc7c 2009-03-07 pbug struct answer {
2871 8c7bdc7c 2009-03-07 pbug char name[2];
2872 8c7bdc7c 2009-03-07 pbug u_int16_t type;
2873 8c7bdc7c 2009-03-07 pbug u_int16_t class;
2874 8c7bdc7c 2009-03-07 pbug u_int32_t ttl;
2875 8c7bdc7c 2009-03-07 pbug u_int16_t rdlength; /* 12 */
2876 8c7bdc7c 2009-03-07 pbug char rdata;
2877 8c7bdc7c 2009-03-07 pbug } __attribute__((packed));
2878 8c7bdc7c 2009-03-07 pbug
2879 8c7bdc7c 2009-03-07 pbug struct soa {
2880 8c7bdc7c 2009-03-07 pbug char *nsserver;
2881 8c7bdc7c 2009-03-07 pbug char *responsible_person;
2882 8c7bdc7c 2009-03-07 pbug u_int32_t serial;
2883 8c7bdc7c 2009-03-07 pbug u_int32_t refresh;
2884 8c7bdc7c 2009-03-07 pbug u_int32_t retry;
2885 8c7bdc7c 2009-03-07 pbug u_int32_t expire;
2886 8c7bdc7c 2009-03-07 pbug u_int32_t minttl;
2887 8c7bdc7c 2009-03-07 pbug };
2888 8c7bdc7c 2009-03-07 pbug
2889 8c7bdc7c 2009-03-07 pbug
2890 8c7bdc7c 2009-03-07 pbug struct answer *answer;
2891 8c7bdc7c 2009-03-07 pbug
2892 8c7bdc7c 2009-03-07 pbug int so = sreply->so;
2893 8c7bdc7c 2009-03-07 pbug char *buf = sreply->buf;
2894 8c7bdc7c 2009-03-07 pbug int len = sreply->len;
2895 8c7bdc7c 2009-03-07 pbug struct question *q = sreply->q;
2896 8c7bdc7c 2009-03-07 pbug struct sockaddr *sa = sreply->sa;
2897 8c7bdc7c 2009-03-07 pbug int salen = sreply->salen;
2898 8c7bdc7c 2009-03-07 pbug struct domain *sd = sreply->sd1;
2899 f1e3cfca 2010-03-12 pbug int istcp = sreply->istcp;
2900 df34d218 2014-04-21 pjp int replysize = 512;
2901 a2b189d4 2014-10-08 pjp int retlen = -1;
2902 df34d218 2014-04-21 pjp
2903 df34d218 2014-04-21 pjp if (istcp) {
2904 df34d218 2014-04-21 pjp replysize = 65535;
2905 df34d218 2014-04-21 pjp }
2906 cd18f393 2014-05-10 pjp
2907 cd18f393 2014-05-10 pjp if (q->edns0len > 512)
2908 cd18f393 2014-05-10 pjp replysize = q->edns0len;
2909 8c7bdc7c 2009-03-07 pbug
2910 8c7bdc7c 2009-03-07 pbug odh = (struct dns_header *)&reply[0];
2911 8c7bdc7c 2009-03-07 pbug outlen = sizeof(struct dns_header);
2912 8c7bdc7c 2009-03-07 pbug
2913 df34d218 2014-04-21 pjp if (len > replysize) {
2914 a2b189d4 2014-10-08 pjp return (retlen);
2915 8c7bdc7c 2009-03-07 pbug
2916 8c7bdc7c 2009-03-07 pbug }
2917 8c7bdc7c 2009-03-07 pbug
2918 8c7bdc7c 2009-03-07 pbug /*
2919 8c7bdc7c 2009-03-07 pbug * no SOA, use the old code
2920 8c7bdc7c 2009-03-07 pbug */
2921 8c7bdc7c 2009-03-07 pbug
2922 8c7bdc7c 2009-03-07 pbug if ((sd->flags & DOMAIN_HAVE_SOA) != DOMAIN_HAVE_SOA) {
2923 8c7bdc7c 2009-03-07 pbug
2924 df34d218 2014-04-21 pjp memcpy(reply, buf, len);
2925 8c7bdc7c 2009-03-07 pbug memset((char *)&odh->query, 0, sizeof(u_int16_t));
2926 8c7bdc7c 2009-03-07 pbug
2927 8c7bdc7c 2009-03-07 pbug SET_DNS_REPLY(odh);
2928 8c7bdc7c 2009-03-07 pbug #if 0
2929 8c7bdc7c 2009-03-07 pbug SET_DNS_RCODE_NAMEERR(odh);
2930 8c7bdc7c 2009-03-07 pbug #endif
2931 8c7bdc7c 2009-03-07 pbug
2932 8c7bdc7c 2009-03-07 pbug HTONS(odh->query);
2933 8c7bdc7c 2009-03-07 pbug
2934 f1e3cfca 2010-03-12 pbug if (istcp) {
2935 f1e3cfca 2010-03-12 pbug char *tmpbuf;
2936 f1e3cfca 2010-03-12 pbug u_int16_t *plen;
2937 f1e3cfca 2010-03-12 pbug
2938 f1e3cfca 2010-03-12 pbug tmpbuf = malloc(len + 2);
2939 f1e3cfca 2010-03-12 pbug if (tmpbuf == NULL) {
2940 dd869383 2013-02-16 pjp dolog(LOG_INFO, "malloc: %s\n", strerror(errno));
2941 f1e3cfca 2010-03-12 pbug }
2942 f1e3cfca 2010-03-12 pbug plen = (u_int16_t *)tmpbuf;
2943 f1e3cfca 2010-03-12 pbug *plen = htons(len);
2944 f1e3cfca 2010-03-12 pbug
2945 f1e3cfca 2010-03-12 pbug memcpy(&tmpbuf[2], reply, len);
2946 f1e3cfca 2010-03-12 pbug
2947 a2b189d4 2014-10-08 pjp if ((retlen = send(so, tmpbuf, len + 2, 0)) < 0) {
2948 dd869383 2013-02-16 pjp dolog(LOG_INFO, "send: %s\n", strerror(errno));
2949 f1e3cfca 2010-03-12 pbug }
2950 f1e3cfca 2010-03-12 pbug free(tmpbuf);
2951 f1e3cfca 2010-03-12 pbug } else {
2952 a2b189d4 2014-10-08 pjp if ((retlen = sendto(so, reply, len, 0, sa, salen)) < 0) {
2953 dd869383 2013-02-16 pjp dolog(LOG_INFO, "sendto: %s\n", strerror(errno));
2954 f1e3cfca 2010-03-12 pbug }
2955 8c7bdc7c 2009-03-07 pbug }
2956 8c7bdc7c 2009-03-07 pbug
2957 a2b189d4 2014-10-08 pjp return (retlen);
2958 8c7bdc7c 2009-03-07 pbug }
2959 8c7bdc7c 2009-03-07 pbug
2960 8c7bdc7c 2009-03-07 pbug /* copy question to reply */
2961 df34d218 2014-04-21 pjp memcpy(reply, buf, sizeof(struct dns_header) + q->hdr->namelen + 4);
2962 8c7bdc7c 2009-03-07 pbug /* blank query */
2963 8c7bdc7c 2009-03-07 pbug memset((char *)&odh->query, 0, sizeof(u_int16_t));
2964 8c7bdc7c 2009-03-07 pbug
2965 8c7bdc7c 2009-03-07 pbug outlen += (q->hdr->namelen + 4);
2966 8c7bdc7c 2009-03-07 pbug
2967 8c7bdc7c 2009-03-07 pbug SET_DNS_REPLY(odh);
2968 b36746d8 2010-09-25 pbug
2969 b36746d8 2010-09-25 pbug if (sreply->sr == NULL)
2970 b36746d8 2010-09-25 pbug SET_DNS_AUTHORITATIVE(odh);
2971 b36746d8 2010-09-25 pbug else
2972 b36746d8 2010-09-25 pbug SET_DNS_RECURSION_AVAIL(odh);
2973 8c7bdc7c 2009-03-07 pbug
2974 8c7bdc7c 2009-03-07 pbug NTOHS(odh->query);
2975 8c7bdc7c 2009-03-07 pbug
2976 5841985a 2010-03-18 pbug odh->question = htons(1);
2977 8c7bdc7c 2009-03-07 pbug odh->answer = 0;
2978 5841985a 2010-03-18 pbug odh->nsrr = htons(1);
2979 8c7bdc7c 2009-03-07 pbug odh->additional = 0;
2980 8c7bdc7c 2009-03-07 pbug
2981 8c7bdc7c 2009-03-07 pbug answer = (struct answer *)(&reply[0] + sizeof(struct dns_header) +
2982 8c7bdc7c 2009-03-07 pbug q->hdr->namelen + 4);
2983 8c7bdc7c 2009-03-07 pbug
2984 8c7bdc7c 2009-03-07 pbug answer->name[0] = 0xc0;
2985 8c7bdc7c 2009-03-07 pbug answer->name[1] = 0x0c;
2986 8c7bdc7c 2009-03-07 pbug answer->type = htons(DNS_TYPE_SOA);
2987 8c7bdc7c 2009-03-07 pbug answer->class = q->hdr->qclass;
2988 b36746d8 2010-09-25 pbug if (sreply->sr != NULL)
2989 b36746d8 2010-09-25 pbug answer->ttl = htonl(sd->ttl - (time(NULL) - sd->created));
2990 b36746d8 2010-09-25 pbug else
2991 b36746d8 2010-09-25 pbug answer->ttl = htonl(sd->ttl);
2992 8c7bdc7c 2009-03-07 pbug
2993 8c7bdc7c 2009-03-07 pbug outlen += 12; /* up to rdata length */
2994 8c7bdc7c 2009-03-07 pbug
2995 8c7bdc7c 2009-03-07 pbug p = (char *)&answer->rdata;
2996 8c7bdc7c 2009-03-07 pbug
2997 f98bb34d 2011-09-19 pbug label = sd->soa.nsserver;
2998 f98bb34d 2011-09-19 pbug labellen = sd->soa.nsserver_len;
2999 8c7bdc7c 2009-03-07 pbug
3000 8c7bdc7c 2009-03-07 pbug plabel = label;
3001 8c7bdc7c 2009-03-07 pbug
3002 8c7bdc7c 2009-03-07 pbug /* copy label to reply */
3003 df34d218 2014-04-21 pjp for (i = outlen; i < replysize; i++) {
3004 8c7bdc7c 2009-03-07 pbug if (i - outlen == labellen)
3005 8c7bdc7c 2009-03-07 pbug break;
3006 8c7bdc7c 2009-03-07 pbug
3007 8c7bdc7c 2009-03-07 pbug reply[i] = *plabel++;
3008 8c7bdc7c 2009-03-07 pbug }
3009 8c7bdc7c 2009-03-07 pbug
3010 df34d218 2014-04-21 pjp if (i >= replysize) {
3011 a2b189d4 2014-10-08 pjp return (retlen);
3012 8c7bdc7c 2009-03-07 pbug }
3013 8c7bdc7c 2009-03-07 pbug
3014 8c7bdc7c 2009-03-07 pbug outlen = i;
3015 8c7bdc7c 2009-03-07 pbug
3016 8c7bdc7c 2009-03-07 pbug /* compress the label if possible */
3017 c5bcfb5c 2010-07-27 pbug if ((tmplen = compress_label((u_char*)reply, outlen, labellen)) > 0) {
3018 8c7bdc7c 2009-03-07 pbug outlen = tmplen;
3019 8c7bdc7c 2009-03-07 pbug }
3020 8c7bdc7c 2009-03-07 pbug
3021 f98bb34d 2011-09-19 pbug label = &sd->soa.responsible_person[0];
3022 f98bb34d 2011-09-19 pbug labellen = sd->soa.rp_len;
3023 8c7bdc7c 2009-03-07 pbug plabel = label;
3024 8c7bdc7c 2009-03-07 pbug
3025 df34d218 2014-04-21 pjp for (i = outlen; i < replysize; i++) {
3026 8c7bdc7c 2009-03-07 pbug if (i - outlen == labellen)
3027 8c7bdc7c 2009-03-07 pbug break;
3028 8c7bdc7c 2009-03-07 pbug
3029 8c7bdc7c 2009-03-07 pbug reply[i] = *plabel++;
3030 8c7bdc7c 2009-03-07 pbug }
3031 8c7bdc7c 2009-03-07 pbug
3032 df34d218 2014-04-21 pjp if (i >= replysize) {
3033 a2b189d4 2014-10-08 pjp return (retlen);
3034 8c7bdc7c 2009-03-07 pbug }
3035 8c7bdc7c 2009-03-07 pbug
3036 8c7bdc7c 2009-03-07 pbug outlen = i;
3037 8c7bdc7c 2009-03-07 pbug
3038 8c7bdc7c 2009-03-07 pbug /* 2 compress the label if possible */
3039 8c7bdc7c 2009-03-07 pbug
3040 c5bcfb5c 2010-07-27 pbug if ((tmplen = compress_label((u_char*)reply, outlen, labellen)) > 0) {
3041 8c7bdc7c 2009-03-07 pbug outlen = tmplen;
3042 8c7bdc7c 2009-03-07 pbug }
3043 8c7bdc7c 2009-03-07 pbug
3044 8c7bdc7c 2009-03-07 pbug
3045 1a591502 2010-03-28 pbug /* XXX */
3046 df34d218 2014-04-21 pjp if ((outlen + sizeof(sd->soa.serial)) > replysize) {
3047 8c7bdc7c 2009-03-07 pbug /* XXX server error reply? */
3048 a2b189d4 2014-10-08 pjp return (retlen);
3049 8c7bdc7c 2009-03-07 pbug }
3050 8c7bdc7c 2009-03-07 pbug soa_val = (u_int32_t *)&r