Blame
Date:
Sat Nov 8 20:28:31 2014 UTC
Message:
0.9.0 is the last version of Wildcarddnsd, the succeeding project is called Delphinusdnsd and will have its first release around November 15th, 2015. The new project page is at http://delphinusdns.centroid.eu.
0001
2005-11-29
pbug
/*
0002
2014-04-13
pjp
* Copyright (c) 2005-2014 Peter J. Philipp
0003
2005-11-29
pbug
* All rights reserved.
0004
2005-11-29
pbug
*
0005
2005-11-29
pbug
* Redistribution and use in source and binary forms, with or without
0006
2005-11-29
pbug
* modification, are permitted provided that the following conditions
0007
2005-11-29
pbug
* are met:
0008
2005-11-29
pbug
* 1. Redistributions of source code must retain the above copyright
0009
2005-11-29
pbug
* notice, this list of conditions and the following disclaimer.
0010
2005-11-29
pbug
* 2. Redistributions in binary form must reproduce the above copyright
0011
2005-11-29
pbug
* notice, this list of conditions and the following disclaimer in the
0012
2005-11-29
pbug
* documentation and/or other materials provided with the distribution.
0013
2005-11-29
pbug
* 3. The name of the author may not be used to endorse or promote products
0014
2005-11-29
pbug
* derived from this software without specific prior written permission
0015
2005-11-29
pbug
*
0016
2005-11-29
pbug
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
0017
2005-11-29
pbug
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
0018
2005-11-29
pbug
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
0019
2005-11-29
pbug
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
0020
2005-11-29
pbug
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
0021
2005-11-29
pbug
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
0022
2005-11-29
pbug
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
0023
2005-11-29
pbug
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
0024
2005-11-29
pbug
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
0025
2005-11-29
pbug
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0026
2005-11-29
pbug
*
0027
2005-11-29
pbug
*/
0028
2005-11-29
pbug
#include "include.h"
0029
2005-11-29
pbug
#include "dns.h"
0030
2005-11-29
pbug
#include "db.h"
0031
2005-11-29
pbug
0032
2014-05-18
pjp
/* prototypes */
0033
2005-11-29
pbug
0034
2014-05-18
pjp
extern int additional_a(char *, int, struct domain *, char *, int, int, int *);
0035
2014-05-18
pjp
extern int additional_aaaa(char *, int, struct domain *, char *, int, int, int *);
0036
2014-05-18
pjp
extern int additional_mx(char *, int, struct domain *, char *, int, int, int *);
0037
2014-05-18
pjp
extern int additional_ptr(char *, int, struct domain *, char *, int, int, int *);
0038
2014-05-18
pjp
extern int additional_opt(struct question *, char *, int, int);
0039
2014-05-18
pjp
extern struct question *build_fake_question(char *, int, u_int16_t);
0040
2014-05-18
pjp
extern int compress_label(u_char *, int, int);
0041
2014-05-18
pjp
extern void dolog(int, char *, ...);
0042
2014-05-18
pjp
extern int free_question(struct question *);
0043
2014-05-18
pjp
extern int lookup_zone(DB *, struct question *, struct domain *, int *, char *, int);
0044
2014-05-18
pjp
extern void slave_shutdown(void);
0045
2005-11-29
pbug
0046
2005-11-29
pbug
0047
2014-05-18
pjp
struct domain *Lookup_zone(DB *, char *, u_int16_t, u_int16_t, int);
0048
2014-05-18
pjp
void collects_init(void);
0049
2014-05-18
pjp
u_int16_t create_anyreply(struct sreply *, char *, int, int, int);
0050
2014-05-18
pjp
u_short in_cksum(const u_short *, register int, int);
0051
2014-10-08
pjp
int reply_a(struct sreply *, DB *);
0052
2014-10-08
pjp
int reply_aaaa(struct sreply *, DB *);
0053
2014-10-08
pjp
int reply_mx(struct sreply *, DB *);
0054
2014-10-08
pjp
int reply_ns(struct sreply *, DB *);
0055
2014-10-08
pjp
int reply_notimpl(struct sreply *);
0056
2014-10-08
pjp
int reply_nxdomain(struct sreply *);
0057
2014-10-08
pjp
int reply_noerror(struct sreply *);
0058
2014-10-08
pjp
int reply_soa(struct sreply *);
0059
2014-10-08
pjp
int reply_ptr(struct sreply *);
0060
2014-10-08
pjp
int reply_txt(struct sreply *);
0061
2014-10-08
pjp
int reply_spf(struct sreply *);
0062
2014-10-08
pjp
int reply_srv(struct sreply *, DB *);
0063
2014-10-08
pjp
int reply_naptr(struct sreply *, DB *);
0064
2014-10-08
pjp
int reply_sshfp(struct sreply *);
0065
2014-10-08
pjp
int reply_cname(struct sreply *);
0066
2014-10-08
pjp
int reply_any(struct sreply *);
0067
2014-10-08
pjp
int reply_refused(struct sreply *);
0068
2014-10-08
pjp
int reply_fmterror(struct sreply *);
0069
2014-10-08
pjp
int reply_raw2(int, char *, int, struct recurses *);
0070
2014-10-08
pjp
int reply_raw6(int, char *, int, struct recurses *);
0071
2014-05-18
pjp
void update_db(DB *, struct domain *);
0072
2009-11-03
pbug
0073
2010-09-25
pbug
#ifdef __linux__
0074
2014-05-18
pjp
static int udp_cksum(const struct iphdr *, const struct udphdr *, int);
0075
2010-09-25
pbug
#else
0076
2014-05-18
pjp
static int udp_cksum(const struct ip *, const struct udphdr *, int);
0077
2010-09-25
pbug
#endif
0078
2010-03-19
pbug
0079
2010-03-19
pbug
SLIST_HEAD(listhead, collects) collectshead;
0080
2010-03-19
pbug
0081
2010-03-19
pbug
struct collects {
0082
2010-03-19
pbug
char *name;
0083
2010-04-15
pbug
u_int16_t namelen;
0084
2010-03-19
pbug
u_int16_t type;
0085
2010-03-19
pbug
struct domain *sd;
0086
2014-05-01
pjp
SLIST_ENTRY(collects) collect_entry;
0087
2010-03-19
pbug
} *cn1, *cn2, *cnp;
0088
2010-03-19
pbug
0089
2013-02-16
pjp
extern int debug, verbose;
0090
2010-03-19
pbug
0091
2010-03-19
pbug
0092
2014-10-08
pjp
static const char rcsid[] = "$Id: reply.c,v 1.60 2014/10/08 21:00:55 pjp Exp $";
0093
2013-02-16
pjp
0094
2005-11-29
pbug
/*
0095
2005-11-29
pbug
* REPLY_A() - replies a DNS question (*q) on socket (so)
0096
2005-11-29
pbug
*
0097
2005-11-29
pbug
*/
0098
2005-11-29
pbug
0099
2014-10-08
pjp
int
0100
2009-11-03
pbug
reply_a(struct sreply *sreply, DB *db)
0101
2005-11-29
pbug
{
0102
2014-04-21
pjp
char *reply = sreply->replybuf;
0103
2005-11-29
pbug
struct dns_header *odh;
0104
2010-04-15
pbug
u_int16_t outlen;
0105
2005-11-29
pbug
int a_count;
0106
2009-11-03
pbug
int mod, pos;
0107
2010-03-09
pbug
int ttlhack = 0;
0108
2005-11-29
pbug
0109
2005-11-29
pbug
struct answer {
0110
2005-11-29
pbug
char name[2];
0111
2005-11-29
pbug
u_int16_t type;
0112
2005-11-29
pbug
u_int16_t class;
0113
2005-11-29
pbug
u_int32_t ttl;
0114
2005-11-29
pbug
u_int16_t rdlength; /* 12 */
0115
2005-11-29
pbug
in_addr_t rdata; /* 16 */
0116
2005-11-29
pbug
} __attribute__((packed));
0117
2005-11-29
pbug
0118
2005-11-29
pbug
struct answer *answer;
0119
2005-11-29
pbug
0120
2005-11-29
pbug
int so = sreply->so;
0121
2005-11-29
pbug
char *buf = sreply->buf;
0122
2005-11-29
pbug
int len = sreply->len;
0123
2005-11-29
pbug
struct question *q = sreply->q;
0124
2005-11-29
pbug
struct sockaddr *sa = sreply->sa;
0125
2005-11-29
pbug
int salen = sreply->salen;
0126
2005-11-29
pbug
struct domain *sd = sreply->sd1;
0127
2005-11-29
pbug
0128
2010-03-09
pbug
u_int8_t region = sreply->region;
0129
2010-03-12
pbug
int istcp = sreply->istcp;
0130
2014-04-21
pjp
int replysize = 512;
0131
2014-10-08
pjp
int retlen = -1;
0132
2005-11-29
pbug
0133
2014-04-21
pjp
if (istcp) {
0134
2014-04-21
pjp
replysize = 65535;
0135
2014-04-21
pjp
}
0136
2014-05-10
pjp
0137
2014-05-10
pjp
if (q->edns0len > 512)
0138
2014-05-10
pjp
replysize = q->edns0len;
0139
2014-04-21
pjp
0140
2010-04-05
pbug
odh = (struct dns_header *)&reply[0];
0141
2010-04-05
pbug
0142
2005-11-29
pbug
outlen = sizeof(struct dns_header);
0143
2005-11-29
pbug
0144
2014-04-21
pjp
if (len > replysize) {
0145
2014-10-08
pjp
return (retlen);
0146
2005-11-29
pbug
}
0147
2005-11-29
pbug
0148
2014-04-21
pjp
memcpy(reply, buf, sizeof(struct dns_header) + q->hdr->namelen + 4);
0149
2005-11-29
pbug
memset((char *)&odh->query, 0, sizeof(u_int16_t));
0150
2005-11-29
pbug
0151
2005-11-29
pbug
outlen += (q->hdr->namelen + 4);
0152
2005-11-29
pbug
0153
2005-11-29
pbug
SET_DNS_REPLY(odh);
0154
2010-09-19
pbug
if (sreply->sr == NULL)
0155
2010-09-19
pbug
SET_DNS_AUTHORITATIVE(odh);
0156
2010-09-19
pbug
else
0157
2010-09-19
pbug
SET_DNS_RECURSION_AVAIL(odh);
0158
2010-09-19
pbug
0159
2005-11-29
pbug
HTONS(odh->query);
0160
2005-11-29
pbug
0161
2010-03-18
pbug
odh->question = htons(1);
0162
2010-03-18
pbug
odh->answer = htons(sd->a_count);
0163
2005-11-29
pbug
odh->nsrr = 0;
0164
2005-11-29
pbug
odh->additional = 0;
0165
2005-11-29
pbug
0166
2005-11-29
pbug
/* skip dns header, question name, qtype and qclass */
0167
2010-04-05
pbug
answer = (struct answer *)(&reply[0] + sizeof(struct dns_header) +
0168
2005-11-29
pbug
q->hdr->namelen + 4);
0169
2005-11-29
pbug
0170
2010-03-09
pbug
/* if we aren't a balance record our region code is 0xff so check */
0171
2010-03-09
pbug
if (sd->region[sd->a_ptr] != 0xff) {
0172
2010-03-09
pbug
ttlhack = 1;
0173
2010-03-09
pbug
}
0174
2010-03-09
pbug
0175
2005-11-29
pbug
a_count = 0;
0176
2009-11-03
pbug
pos = sd->a_ptr;
0177
2009-11-03
pbug
mod = sd->a_count;
0178
2009-11-03
pbug
0179
2005-11-29
pbug
do {
0180
2008-07-24
pbug
/*
0181
2010-03-09
pbug
* skip records that are not in the needed region
0182
2010-03-09
pbug
*/
0183
2010-03-09
pbug
if (ttlhack && sd->region[pos % mod] != region) {
0184
2010-03-09
pbug
pos++;
0185
2010-03-09
pbug
continue;
0186
2010-03-09
pbug
}
0187
2010-03-09
pbug
0188
2010-03-09
pbug
/*
0189
2008-07-24
pbug
* answer->name is a pointer to the request (0xc00c)
0190
2008-07-24
pbug
*/
0191
2005-11-29
pbug
0192
2008-07-24
pbug
answer->name[0] = 0xc0; /* 1 byte */
0193
2008-07-24
pbug
answer->name[1] = 0x0c; /* 2 bytes */
0194
2008-07-24
pbug
answer->type = q->hdr->qtype; /* 4 bytes */
0195
2008-07-24
pbug
answer->class = q->hdr->qclass; /* 6 bytes */
0196
2010-09-21
pbug
if (sreply->sr != NULL)
0197
2010-09-21
pbug
answer->ttl = htonl(sd->ttl - (time(NULL) - sd->created));
0198
2010-09-21
pbug
else
0199
2010-09-21
pbug
answer->ttl = htonl(sd->ttl); /* 10 bytes */
0200
2008-07-24
pbug
0201
2008-07-24
pbug
answer->rdlength = htons(sizeof(in_addr_t)); /* 12 bytes */
0202
2008-07-24
pbug
0203
2009-11-03
pbug
memcpy((char *)&answer->rdata, (char *)&sd->a[pos++ % mod],
0204
2008-07-24
pbug
sizeof(in_addr_t)); /* 16 bytes */
0205
2009-11-03
pbug
0206
2009-11-03
pbug
a_count++;
0207
2005-11-29
pbug
outlen += 16;
0208
2005-11-29
pbug
0209
2005-11-29
pbug
/* can we afford to write another header? if no truncate */
0210
2014-05-11
pjp
if (sd->a_count > 1 && outlen + 16 > replysize) {
0211
2005-11-29
pbug
NTOHS(odh->query);
0212
2005-11-29
pbug
SET_DNS_TRUNCATION(odh);
0213
2005-11-29
pbug
HTONS(odh->query);
0214
2005-11-29
pbug
goto out;
0215
2005-11-29
pbug
}
0216
2005-11-29
pbug
0217
2010-03-09
pbug
0218
2005-11-29
pbug
/* set new offset for answer */
0219
2005-11-29
pbug
answer = (struct answer *)&reply[outlen];
0220
2010-04-01
pbug
} while (a_count < RECORD_COUNT && --sd->a_count);
0221
2005-11-29
pbug
0222
2010-03-09
pbug
if (ttlhack) {
0223
2010-03-18
pbug
odh->answer = htons(a_count);
0224
2005-11-29
pbug
}
0225
2005-11-29
pbug
0226
2014-05-10
pjp
if (q->edns0len) {
0227
2014-05-10
pjp
/* tag on edns0 opt record */
0228
2014-05-10
pjp
odh->additional = htons(1);
0229
2014-05-10
pjp
outlen = additional_opt(q, reply, replysize, outlen);
0230
2014-05-10
pjp
}
0231
2014-05-10
pjp
0232
2010-03-09
pbug
out:
0233
2010-09-19
pbug
if (sreply->sr != NULL) {
0234
2014-10-08
pjp
retlen = reply_raw2(so, reply, outlen, sreply->sr);
0235
2010-09-19
pbug
} else {
0236
2010-09-19
pbug
if (istcp) {
0237
2010-09-19
pbug
char *tmpbuf;
0238
2010-09-19
pbug
u_int16_t *plen;
0239
2010-04-05
pbug
0240
2010-09-19
pbug
tmpbuf = malloc(outlen + 2);
0241
2010-09-19
pbug
if (tmpbuf == NULL) {
0242
2013-02-16
pjp
dolog(LOG_INFO, "malloc: %s\n", strerror(errno));
0243
2010-09-19
pbug
}
0244
2010-09-19
pbug
plen = (u_int16_t *)tmpbuf;
0245
2010-09-19
pbug
*plen = htons(outlen);
0246
2010-09-19
pbug
0247
2010-09-19
pbug
memcpy(&tmpbuf[2], reply, outlen);
0248
2010-04-05
pbug
0249
2014-10-08
pjp
if ((retlen = send(so, tmpbuf, outlen + 2, 0)) < 0) {
0250
2013-02-16
pjp
dolog(LOG_INFO, "send: %s\n", strerror(errno));
0251
2010-09-19
pbug
}
0252
2010-09-19
pbug
free(tmpbuf);
0253
2010-09-19
pbug
} else {
0254
2014-10-08
pjp
if ((retlen = sendto(so, reply, outlen, 0, sa, salen)) < 0) {
0255
2013-02-16
pjp
dolog(LOG_INFO, "sendto: %s\n", strerror(errno));
0256
2010-09-19
pbug
}
0257
2010-03-12
pbug
}
0258
2010-03-12
pbug
0259
2010-09-19
pbug
} /* if (->sr) */
0260
2009-11-03
pbug
/*
0261
2009-11-03
pbug
* update a_ptr setting
0262
2009-11-03
pbug
*/
0263
2009-11-03
pbug
0264
2009-11-03
pbug
sd->a_ptr = (sd->a_ptr + 1) % mod;
0265
2009-11-03
pbug
sd->a_count = mod; /* I know I know */
0266
2009-11-03
pbug
update_db(db, sd);
0267
2009-11-03
pbug
0268
2014-10-08
pjp
return (retlen);
0269
2005-11-29
pbug
}
0270
2005-11-29
pbug
0271
2005-11-29
pbug
/*
0272
2005-11-29
pbug
* REPLY_AAAA() - replies a DNS question (*q) on socket (so)
0273
2005-11-29
pbug
*
0274
2005-11-29
pbug
*/
0275
2005-11-29
pbug
0276
2014-10-08
pjp
int
0277
2009-11-03
pbug
reply_aaaa(struct sreply *sreply, DB *db)
0278
2005-11-29
pbug
{
0279
2014-04-21
pjp
char *reply = sreply->replybuf;
0280
2005-11-29
pbug
struct dns_header *odh;
0281
2010-04-15
pbug
u_int16_t outlen;
0282
2005-11-29
pbug
int aaaa_count;
0283
2009-11-03
pbug
int mod, pos;
0284
2005-11-29
pbug
0285
2005-11-29
pbug
struct answer {
0286
2005-11-29
pbug
char name[2];
0287
2005-11-29
pbug
u_int16_t type;
0288
2005-11-29
pbug
u_int16_t class;
0289
2005-11-29
pbug
u_int32_t ttl;
0290
2005-11-29
pbug
u_int16_t rdlength; /* 12 */
0291
2005-11-29
pbug
char rdata; /* 12 + 16 */
0292
2005-11-29
pbug
} __attribute__((packed));
0293
2005-11-29
pbug
0294
2005-11-29
pbug
struct answer *answer;
0295
2005-11-29
pbug
0296
2005-11-29
pbug
int so = sreply->so;
0297
2005-11-29
pbug
char *buf = sreply->buf;
0298
2005-11-29
pbug
int len = sreply->len;
0299
2005-11-29
pbug
struct question *q = sreply->q;
0300
2005-11-29
pbug
struct sockaddr *sa = sreply->sa;
0301
2005-11-29
pbug
int salen = sreply->salen;
0302
2005-11-29
pbug
struct domain *sd = sreply->sd1;
0303
2010-03-12
pbug
int istcp = sreply->istcp;
0304
2014-04-21
pjp
int replysize = 512;
0305
2014-10-08
pjp
int retlen = -1;
0306
2014-04-21
pjp
0307
2014-04-21
pjp
if (istcp) {
0308
2014-04-21
pjp
replysize = 65535;
0309
2014-04-21
pjp
}
0310
2014-05-10
pjp
0311
2014-05-10
pjp
if (q->edns0len > 512)
0312
2014-05-10
pjp
replysize = q->edns0len;
0313
2010-04-05
pbug
0314
2010-04-05
pbug
0315
2010-04-05
pbug
odh = (struct dns_header *)&reply[0];
0316
2010-04-05
pbug
0317
2005-11-29
pbug
outlen = sizeof(struct dns_header);
0318
2005-11-29
pbug
0319
2014-04-21
pjp
if (len > replysize) {
0320
2014-10-08
pjp
return (retlen);
0321
2005-11-29
pbug
}
0322
2005-11-29
pbug
0323
2014-04-21
pjp
memcpy(reply, buf, sizeof(struct dns_header) + q->hdr->namelen + 4);
0324
2005-11-29
pbug
memset((char *)&odh->query, 0, sizeof(u_int16_t));
0325
2005-11-29
pbug
0326
2005-11-29
pbug
outlen += (q->hdr->namelen + 4);
0327
2005-11-29
pbug
0328
2005-11-29
pbug
SET_DNS_REPLY(odh);
0329
2010-09-25
pbug
if (sreply->sr == NULL)
0330
2010-09-25
pbug
SET_DNS_AUTHORITATIVE(odh);
0331
2010-09-25
pbug
else
0332
2010-09-25
pbug
SET_DNS_RECURSION_AVAIL(odh);
0333
2005-11-29
pbug
0334
2005-11-29
pbug
HTONS(odh->query);
0335
2005-11-29
pbug
0336
2010-03-18
pbug
odh->question = htons(1);
0337
2010-03-18
pbug
odh->answer = htons(sd->aaaa_count);
0338
2005-11-29
pbug
odh->nsrr = 0;
0339
2005-11-29
pbug
odh->additional = 0;
0340
2005-11-29
pbug
0341
2005-11-29
pbug
/* skip dns header, question name, qtype and qclass */
0342
2010-04-05
pbug
answer = (struct answer *)(&reply[0] + sizeof(struct dns_header) +
0343
2010-03-12
pbug
q->hdr->namelen + 4);
0344
2010-03-12
pbug
0345
2005-11-29
pbug
0346
2005-11-29
pbug
aaaa_count = 0;
0347
2009-11-03
pbug
pos = sd->aaaa_ptr;
0348
2009-11-03
pbug
mod = sd->aaaa_count;
0349
2005-11-29
pbug
0350
2005-11-29
pbug
do {
0351
2005-11-29
pbug
answer->name[0] = 0xc0;
0352
2005-11-29
pbug
answer->name[1] = 0x0c;
0353
2005-11-29
pbug
answer->type = q->hdr->qtype;
0354
2005-11-29
pbug
answer->class = q->hdr->qclass;
0355
2010-09-25
pbug
if (sreply->sr != NULL)
0356
2010-09-25
pbug
answer->ttl = htonl(sd->ttl - (time(NULL) - sd->created));
0357
2010-09-25
pbug
else
0358
2010-09-25
pbug
answer->ttl = htonl(sd->ttl); /* 10 bytes */
0359
2005-11-29
pbug
0360
2005-11-29
pbug
answer->rdlength = htons(sizeof(struct in6_addr));
0361
2005-11-29
pbug
0362
2011-09-19
pbug
memcpy((char *)&answer->rdata, (char *)&sd->aaaa[pos++ % mod], sizeof(struct in6_addr));
0363
2005-11-29
pbug
outlen += 28;
0364
2005-11-29
pbug
0365
2005-11-29
pbug
/* can we afford to write another header? if no truncate */
0366
2014-05-11
pjp
if (sd->aaaa_count > 1 && outlen + 28 > replysize) {
0367
2005-11-29
pbug
NTOHS(odh->query);
0368
2005-11-29
pbug
SET_DNS_TRUNCATION(odh);
0369
2005-11-29
pbug
HTONS(odh->query);
0370
2005-11-29
pbug
goto out;
0371
2005-11-29
pbug
}
0372
2005-11-29
pbug
0373
2009-11-03
pbug
aaaa_count++;
0374
2009-11-03
pbug
0375
2005-11-29
pbug
/* set new offset for answer */
0376
2005-11-29
pbug
answer = (struct answer *)&reply[outlen];
0377
2010-04-01
pbug
} while (aaaa_count < RECORD_COUNT && --sd->aaaa_count);
0378
2005-11-29
pbug
0379
2014-05-10
pjp
if (q->edns0len) {
0380
2014-05-10
pjp
/* tag on edns0 opt record */
0381
2014-05-10
pjp
odh->additional = htons(1);
0382
2014-05-10
pjp
outlen = additional_opt(q, reply, replysize, outlen);
0383
2014-05-10
pjp
}
0384
2014-05-10
pjp
0385
2005-11-29
pbug
out:
0386
2010-09-25
pbug
if (sreply->sr != NULL) {
0387
2014-10-08
pjp
retlen = reply_raw2(so, reply, outlen, sreply->sr);
0388
2010-09-25
pbug
} else {
0389
2010-09-25
pbug
if (istcp) {
0390
2010-09-25
pbug
char *tmpbuf;
0391
2010-09-25
pbug
u_int16_t *plen;
0392
2010-04-05
pbug
0393
2010-09-25
pbug
tmpbuf = malloc(outlen + 2);
0394
2010-09-25
pbug
if (tmpbuf == NULL) {
0395
2013-02-16
pjp
dolog(LOG_INFO, "malloc: %s\n", strerror(errno));
0396
2010-09-25
pbug
}
0397
2010-09-25
pbug
plen = (u_int16_t *)tmpbuf;
0398
2010-09-25
pbug
*plen = htons(outlen);
0399
2010-03-12
pbug
0400
2010-09-25
pbug
memcpy(&tmpbuf[2], reply, outlen);
0401
2010-04-05
pbug
0402
2014-10-08
pjp
if ((retlen = send(so, tmpbuf, outlen + 2, 0)) < 0) {
0403
2013-02-16
pjp
dolog(LOG_INFO, "send: %s\n", strerror(errno));
0404
2010-09-25
pbug
}
0405
2010-09-25
pbug
free(tmpbuf);
0406
2010-09-25
pbug
} else {
0407
2014-10-08
pjp
if ((retlen = sendto(so, reply, outlen, 0, sa, salen)) < 0) {
0408
2013-02-16
pjp
dolog(LOG_INFO, "sendto: %s\n", strerror(errno));
0409
2010-09-25
pbug
}
0410
2010-03-12
pbug
}
0411
2005-11-29
pbug
}
0412
2005-11-29
pbug
0413
2009-11-03
pbug
sd->aaaa_ptr = (sd->aaaa_ptr + 1) % mod;
0414
2009-11-03
pbug
sd->aaaa_count = mod;
0415
2009-11-03
pbug
update_db(db, sd);
0416
2009-11-03
pbug
0417
2014-10-08
pjp
return (retlen);
0418
2005-11-29
pbug
}
0419
2005-11-29
pbug
0420
2005-11-29
pbug
/*
0421
2005-11-29
pbug
* REPLY_MX() - replies a DNS question (*q) on socket (so)
0422
2005-11-29
pbug
*
0423
2005-11-29
pbug
*/
0424
2005-11-29
pbug
0425
2014-10-08
pjp
int
0426
2010-03-19
pbug
reply_mx(struct sreply *sreply, DB *db)
0427
2005-11-29
pbug
{
0428
2014-04-21
pjp
char *reply = sreply->replybuf;
0429
2005-11-29
pbug
struct dns_header *odh;
0430
2010-03-19
pbug
struct domain *sd0;
0431
2005-11-29
pbug
int mx_count;
0432
2010-03-12
pbug
u_int16_t *plen;
0433
2010-03-19
pbug
char *name;
0434
2010-04-15
pbug
u_int16_t outlen;
0435
2010-04-15
pbug
u_int16_t namelen;
0436
2010-03-19
pbug
int additional = 0;
0437
2005-11-29
pbug
0438
2005-11-29
pbug
struct answer {
0439
2005-11-29
pbug
char name[2];
0440
2005-11-29
pbug
u_int16_t type;
0441
2005-11-29
pbug
u_int16_t class;
0442
2005-11-29
pbug
u_int32_t ttl;
0443
2005-11-29
pbug
u_int16_t rdlength; /* 12 */
0444
2005-11-29
pbug
u_int16_t mx_priority;
0445
2005-11-29
pbug
char exchange;
0446
2005-11-29
pbug
} __attribute__((packed));
0447
2005-11-29
pbug
0448
2005-11-29
pbug
struct answer *answer;
0449
2005-11-29
pbug
0450
2005-11-29
pbug
int so = sreply->so;
0451
2005-11-29
pbug
char *buf = sreply->buf;
0452
2005-11-29
pbug
int len = sreply->len;
0453
2005-11-29
pbug
struct question *q = sreply->q;
0454
2005-11-29
pbug
struct sockaddr *sa = sreply->sa;
0455
2005-11-29
pbug
int salen = sreply->salen;
0456
2005-11-29
pbug
struct domain *sd = sreply->sd1;
0457
2010-03-12
pbug
int istcp = sreply->istcp;
0458
2010-04-05
pbug
int wildcard = sreply->wildcard;
0459
2014-04-21
pjp
int replysize = 512;
0460
2014-10-08
pjp
int retlen = -1;
0461
2014-04-21
pjp
0462
2014-04-21
pjp
if (istcp) {
0463
2014-04-21
pjp
replysize = 65535;
0464
2014-04-21
pjp
}
0465
2010-03-19
pbug
0466
2014-05-10
pjp
if (q->edns0len > 512)
0467
2014-05-10
pjp
replysize = q->edns0len;
0468
2005-11-29
pbug
0469
2010-03-19
pbug
odh = (struct dns_header *)&reply[0];
0470
2010-03-19
pbug
0471
2005-11-29
pbug
outlen = sizeof(struct dns_header);
0472
2005-11-29
pbug
0473
2014-04-21
pjp
if (len > replysize) {
0474
2014-10-08
pjp
return (retlen);
0475
2005-11-29
pbug
}
0476
2005-11-29
pbug
0477
2014-04-21
pjp
memcpy(reply, buf, sizeof(struct dns_header) + q->hdr->namelen + 4);
0478
2005-11-29
pbug
memset((char *)&odh->query, 0, sizeof(u_int16_t));
0479
2005-11-29
pbug
0480
2005-11-29
pbug
outlen += (q->hdr->namelen + 4);
0481
2005-11-29
pbug
0482
2005-11-29
pbug
SET_DNS_REPLY(odh);
0483
2010-09-26
pbug
0484
2010-09-26
pbug
if (sreply->sr == NULL) {
0485
2010-09-26
pbug
SET_DNS_AUTHORITATIVE(odh);
0486
2010-09-26
pbug
} else
0487
2010-09-26
pbug
SET_DNS_RECURSION_AVAIL(odh);
0488
2005-11-29
pbug
0489
2005-11-29
pbug
HTONS(odh->query);
0490
2005-11-29
pbug
0491
2010-03-18
pbug
odh->question = htons(1);
0492
2010-03-18
pbug
odh->answer = htons(sd->mx_count);
0493
2005-11-29
pbug
odh->nsrr = 0;
0494
2005-11-29
pbug
odh->additional = 0;
0495
2005-11-29
pbug
0496
2005-11-29
pbug
/* skip dns header, question name, qtype and qclass */
0497
2010-03-19
pbug
answer = (struct answer *)(&reply[0] + sizeof(struct dns_header) +
0498
2005-11-29
pbug
q->hdr->namelen + 4);
0499
2005-11-29
pbug
0500
2005-11-29
pbug
mx_count = 0;
0501
2005-11-29
pbug
do {
0502
2005-11-29
pbug
answer->name[0] = 0xc0;
0503
2005-11-29
pbug
answer->name[1] = 0x0c;
0504
2005-11-29
pbug
answer->type = q->hdr->qtype;
0505
2005-11-29
pbug
answer->class = q->hdr->qclass;
0506
2010-09-26
pbug
if (sreply->sr != NULL)
0507
2010-09-26
pbug
answer->ttl = htonl(sd->ttl - (time(NULL) - sd->created));
0508
2010-09-26
pbug
else
0509
2010-09-26
pbug
answer->ttl = htonl(sd->ttl);
0510
2005-11-29
pbug
0511
2011-09-19
pbug
answer->rdlength = htons(sizeof(u_int16_t) + sd->mx[mx_count].exchangelen);
0512
2005-11-29
pbug
0513
2011-09-19
pbug
answer->mx_priority = htons(sd->mx[mx_count].preference);
0514
2011-09-19
pbug
memcpy((char *)&answer->exchange, (char *)sd->mx[mx_count].exchange, sd->mx[mx_count].exchangelen);
0515
2010-03-19
pbug
0516
2011-09-19
pbug
name = sd->mx[mx_count].exchange;
0517
2011-09-19
pbug
namelen = sd->mx[mx_count].exchangelen;
0518
2010-03-19
pbug
0519
2010-04-05
pbug
sd0 = Lookup_zone(db, name, namelen, htons(DNS_TYPE_A), wildcard);
0520
2010-03-19
pbug
if (sd0 != NULL) {
0521
2010-03-19
pbug
cn1 = malloc(sizeof(struct collects));
0522
2010-03-19
pbug
if (cn1 != NULL) {
0523
2010-03-19
pbug
cn1->name = malloc(namelen);
0524
2010-03-19
pbug
if (cn1->name != NULL) {
0525
2010-03-19
pbug
memcpy(cn1->name, name, namelen);
0526
2010-03-19
pbug
cn1->namelen = namelen;
0527
2010-03-19
pbug
cn1->sd = sd0;
0528
2010-03-19
pbug
cn1->type = DNS_TYPE_A;
0529
2010-03-19
pbug
0530
2014-05-01
pjp
SLIST_INSERT_HEAD(&collectshead, cn1, collect_entry);
0531
2010-03-19
pbug
}
0532
2010-03-19
pbug
}
0533
2010-03-19
pbug
}
0534
2010-04-05
pbug
sd0 = Lookup_zone(db, name, namelen, htons(DNS_TYPE_AAAA), wildcard);
0535
2010-03-19
pbug
if (sd0 != NULL) {
0536
2010-03-19
pbug
cn1 = malloc(sizeof(struct collects));
0537
2010-03-19
pbug
if (cn1 != NULL) {
0538
2010-03-19
pbug
cn1->name = malloc(namelen);
0539
2010-03-19
pbug
if (cn1->name != NULL) {
0540
2010-03-19
pbug
memcpy(cn1->name, name, namelen);
0541
2010-03-19
pbug
cn1->namelen = namelen;
0542
2010-03-19
pbug
cn1->sd = sd0;
0543
2010-03-19
pbug
cn1->type = DNS_TYPE_AAAA;
0544
2010-03-19
pbug
0545
2014-05-01
pjp
SLIST_INSERT_HEAD(&collectshead, cn1, collect_entry);
0546
2010-03-19
pbug
}
0547
2010-03-19
pbug
}
0548
2010-03-19
pbug
}
0549
2010-03-19
pbug
0550
2011-09-19
pbug
outlen += (12 + 2 + sd->mx[mx_count].exchangelen);
0551
2005-11-29
pbug
0552
2005-11-29
pbug
/* can we afford to write another header? if no truncate */
0553
2014-05-11
pjp
if (sd->mx_count > 1 && (outlen + 12 + 2 + sd->mx[mx_count].exchangelen) > replysize) {
0554
2005-11-29
pbug
NTOHS(odh->query);
0555
2005-11-29
pbug
SET_DNS_TRUNCATION(odh);
0556
2005-11-29
pbug
HTONS(odh->query);
0557
2005-11-29
pbug
goto out;
0558
2005-11-29
pbug
}
0559
2005-11-29
pbug
0560
2005-11-29
pbug
/* set new offset for answer */
0561
2005-11-29
pbug
answer = (struct answer *)&reply[outlen];
0562
2010-04-01
pbug
} while (++mx_count < RECORD_COUNT && --sd->mx_count);
0563
2005-11-29
pbug
0564
2010-03-19
pbug
/* write additional */
0565
2010-03-19
pbug
0566
2014-05-01
pjp
SLIST_FOREACH(cnp, &collectshead, collect_entry) {
0567
2010-03-19
pbug
int addcount;
0568
2010-03-19
pbug
int tmplen;
0569
2010-03-19
pbug
0570
2010-03-19
pbug
switch (cnp->type) {
0571
2010-03-19
pbug
case DNS_TYPE_A:
0572
2014-04-21
pjp
tmplen = additional_a(cnp->name, cnp->namelen, cnp->sd, reply, replysize, outlen, &addcount);
0573
2010-03-19
pbug
additional += addcount;
0574
2010-03-19
pbug
break;
0575
2010-03-19
pbug
case DNS_TYPE_AAAA:
0576
2014-04-21
pjp
tmplen = additional_aaaa(cnp->name, cnp->namelen, cnp->sd, reply, replysize, outlen, &addcount);
0577
2010-03-19
pbug
additional += addcount;
0578
2010-03-19
pbug
break;
0579
2010-03-12
pbug
}
0580
2010-03-19
pbug
0581
2010-03-19
pbug
if (tmplen > 0) {
0582
2010-03-19
pbug
outlen = tmplen;
0583
2010-03-19
pbug
}
0584
2010-03-19
pbug
}
0585
2010-03-19
pbug
0586
2010-03-19
pbug
odh->additional = htons(additional);
0587
2010-03-19
pbug
0588
2010-03-19
pbug
while (!SLIST_EMPTY(&collectshead)) {
0589
2010-03-19
pbug
cn1 = SLIST_FIRST(&collectshead);
0590
2014-05-01
pjp
SLIST_REMOVE_HEAD(&collectshead, collect_entry);
0591
2010-03-19
pbug
free(cn1->name);
0592
2010-03-19
pbug
free(cn1->sd);
0593
2010-03-19
pbug
free(cn1);
0594
2010-03-19
pbug
}
0595
2010-03-19
pbug
0596
2014-05-10
pjp
if (q->edns0len) {
0597
2014-05-10
pjp
/* tag on edns0 opt record */
0598
2014-05-10
pjp
NTOHS(odh->additional);
0599
2014-05-10
pjp
odh->additional++;
0600
2014-05-10
pjp
HTONS(odh->additional);
0601
2014-05-10
pjp
0602
2014-05-10
pjp
outlen = additional_opt(q, reply, replysize, outlen);
0603
2014-05-10
pjp
}
0604
2014-05-10
pjp
0605
2010-03-19
pbug
out:
0606
2010-09-26
pbug
if (sreply->sr != NULL) {
0607
2014-10-08
pjp
retlen = reply_raw2(so, reply, outlen, sreply->sr);
0608
2010-09-26
pbug
} else {
0609
2010-09-26
pbug
if (istcp) {
0610
2010-09-26
pbug
char *tmpbuf;
0611
2010-03-19
pbug
0612
2010-09-26
pbug
tmpbuf = malloc(outlen + 2);
0613
2010-09-26
pbug
if (tmpbuf == NULL) {
0614
2013-02-16
pjp
dolog(LOG_INFO, "malloc: %s\n", strerror(errno));
0615
2010-09-26
pbug
}
0616
2010-09-26
pbug
plen = (u_int16_t *)tmpbuf;
0617
2010-09-26
pbug
*plen = htons(outlen);
0618
2010-09-26
pbug
0619
2010-09-26
pbug
memcpy(&tmpbuf[2], reply, outlen);
0620
2014-10-08
pjp
if ((retlen = send(so, tmpbuf, outlen + 2, 0)) < 0) {
0621
2013-02-16
pjp
dolog(LOG_INFO, "send: %s\n", strerror(errno));
0622
2010-09-26
pbug
}
0623
2010-09-26
pbug
free(tmpbuf);
0624
2010-09-26
pbug
} else {
0625
2014-10-08
pjp
if ((retlen = sendto(so, reply, outlen, 0, sa, salen)) < 0) {
0626
2013-02-16
pjp
dolog(LOG_INFO, "sendto: %s\n", strerror(errno));
0627
2010-09-26
pbug
}
0628
2010-03-12
pbug
}
0629
2005-11-29
pbug
}
0630
2005-11-29
pbug
0631
2014-10-08
pjp
return (retlen);
0632
2005-11-29
pbug
}
0633
2005-11-29
pbug
0634
2005-11-29
pbug
/*
0635
2005-11-29
pbug
* REPLY_NS() - replies a DNS question (*q) on socket (so)
0636
2005-11-29
pbug
*
0637
2005-11-29
pbug
*/
0638
2005-11-29
pbug
0639
2014-10-08
pjp
int
0640
2009-11-03
pbug
reply_ns(struct sreply *sreply, DB *db)
0641
2005-11-29
pbug
{
0642
2014-04-21
pjp
char *reply = sreply->replybuf;
0643
2005-11-29
pbug
struct dns_header *odh;
0644
2010-03-19
pbug
struct domain *sd0;
0645
2010-04-01
pbug
int tmplen;
0646
2005-11-29
pbug
int ns_count;
0647
2009-11-03
pbug
int mod, pos;
0648
2010-03-12
pbug
u_int16_t *plen;
0649
2010-03-19
pbug
char *name;
0650
2010-04-15
pbug
u_int16_t outlen;
0651
2010-04-15
pbug
u_int16_t namelen;
0652
2010-03-19
pbug
int additional = 0;
0653
2005-11-29
pbug
0654
2005-11-29
pbug
struct answer {
0655
2005-11-29
pbug
char name[2];
0656
2005-11-29
pbug
u_int16_t type;
0657
2005-11-29
pbug
u_int16_t class;
0658
2005-11-29
pbug
u_int32_t ttl;
0659
2005-11-29
pbug
u_int16_t rdlength; /* 12 */
0660
2005-11-29
pbug
char ns;
0661
2005-11-29
pbug
} __attribute__((packed));
0662
2005-11-29
pbug
0663
2005-11-29
pbug
struct answer *answer;
0664
2005-11-29
pbug
0665
2005-11-29
pbug
int so = sreply->so;
0666
2005-11-29
pbug
char *buf = sreply->buf;
0667
2005-11-29
pbug
int len = sreply->len;
0668
2005-11-29
pbug
struct question *q = sreply->q;
0669
2005-11-29
pbug
struct sockaddr *sa = sreply->sa;
0670
2005-11-29
pbug
int salen = sreply->salen;
0671
2005-11-29
pbug
struct domain *sd = sreply->sd1;
0672
2010-03-12
pbug
int istcp = sreply->istcp;
0673
2010-04-05
pbug
int wildcard = sreply->wildcard;
0674
2014-04-21
pjp
int replysize = 512;
0675
2014-10-08
pjp
int retlen = -1;
0676
2005-11-29
pbug
0677
2014-04-21
pjp
if (istcp) {
0678
2014-04-21
pjp
replysize = 65535;
0679
2014-04-21
pjp
}
0680
2014-05-10
pjp
0681
2014-05-10
pjp
if (q->edns0len > 512)
0682
2014-05-10
pjp
replysize = q->edns0len;
0683
2014-04-21
pjp
0684
2010-03-19
pbug
odh = (struct dns_header *)&reply[0];
0685
2010-03-19
pbug
0686
2005-11-29
pbug
outlen = sizeof(struct dns_header);
0687
2005-11-29
pbug
0688
2014-04-21
pjp
if (len > replysize) {
0689
2014-10-08
pjp
return (retlen);
0690
2005-11-29
pbug
}
0691
2005-11-29
pbug
0692
2014-04-21
pjp
memcpy(reply, buf, sizeof(struct dns_header) + q->hdr->namelen + 4);
0693
2010-03-12
pbug
0694
2005-11-29
pbug
memset((char *)&odh->query, 0, sizeof(u_int16_t));
0695
2005-11-29
pbug
0696
2005-11-29
pbug
outlen += (q->hdr->namelen + 4);
0697
2005-11-29
pbug
0698
2005-11-29
pbug
SET_DNS_REPLY(odh);
0699
2010-03-18
pbug
0700
2010-09-25
pbug
if (sreply->sr == NULL) {
0701
2010-09-25
pbug
switch (sd->ns_type) {
0702
2010-09-25
pbug
case 0:
0703
2010-09-25
pbug
SET_DNS_AUTHORITATIVE(odh);
0704
2010-09-25
pbug
break;
0705
2010-09-25
pbug
default:
0706
2010-09-25
pbug
SET_DNS_RECURSION(odh);
0707
2010-09-25
pbug
break;
0708
2010-09-25
pbug
}
0709
2010-09-25
pbug
} else
0710
2010-09-25
pbug
SET_DNS_RECURSION_AVAIL(odh);
0711
2010-04-01
pbug
0712
2005-11-29
pbug
0713
2005-11-29
pbug
HTONS(odh->query);
0714
2005-11-29
pbug
0715
2010-03-18
pbug
odh->question = htons(1);
0716
2010-04-01
pbug
switch (sd->ns_type) {
0717
2010-04-01
pbug
case NS_TYPE_DELEGATE:
0718
2010-03-18
pbug
odh->answer = 0;
0719
2010-03-18
pbug
odh->nsrr = htons(sd->ns_count);
0720
2010-04-01
pbug
break;
0721
2010-04-01
pbug
default:
0722
2010-04-01
pbug
odh->answer = htons(sd->ns_count);
0723
2010-04-01
pbug
odh->nsrr = 0;
0724
2010-04-01
pbug
break;
0725
2010-03-18
pbug
}
0726
2005-11-29
pbug
odh->additional = 0;
0727
2005-11-29
pbug
0728
2005-11-29
pbug
/* skip dns header, question name, qtype and qclass */
0729
2010-03-19
pbug
answer = (struct answer *)(&reply[0] + sizeof(struct dns_header) +
0730
2005-11-29
pbug
q->hdr->namelen + 4);
0731
2005-11-29
pbug
0732
2005-11-29
pbug
ns_count = 0;
0733
2009-11-03
pbug
mod = sd->ns_count;
0734
2009-11-03
pbug
pos = sd->ns_ptr;
0735
2009-11-03
pbug
0736
2005-11-29
pbug
do {
0737
2005-11-29
pbug
answer->name[0] = 0xc0;
0738
2005-11-29
pbug
answer->name[1] = 0x0c;
0739
2010-03-19
pbug
answer->type = htons(DNS_TYPE_NS);
0740
2005-11-29
pbug
answer->class = q->hdr->qclass;
0741
2010-09-25
pbug
if (sreply->sr != NULL)
0742
2010-09-25
pbug
answer->ttl = htonl(sd->ttl - (time(NULL) - sd->created));
0743
2010-09-25
pbug
else
0744
2010-09-25
pbug
answer->ttl = htonl(sd->ttl);
0745
2005-11-29
pbug
0746
2011-09-19
pbug
name = sd->ns[pos % mod].nsserver;
0747
2011-09-19
pbug
namelen = sd->ns[pos % mod].nslen;
0748
2005-11-29
pbug
0749
2010-03-19
pbug
answer->rdlength = htons(namelen);
0750
2005-11-29
pbug
0751
2010-03-19
pbug
memcpy((char *)&answer->ns, (char *)name, namelen);
0752
2009-11-03
pbug
0753
2010-04-05
pbug
sd0 = Lookup_zone(db, name, namelen, htons(DNS_TYPE_A), wildcard);
0754
2010-03-19
pbug
if (sd0 != NULL) {
0755
2010-03-19
pbug
cn1 = malloc(sizeof(struct collects));
0756
2010-03-19
pbug
if (cn1 != NULL) {
0757
2010-03-19
pbug
cn1->name = malloc(namelen);
0758
2010-03-19
pbug
if (cn1->name != NULL) {
0759
2010-03-19
pbug
memcpy(cn1->name, name, namelen);
0760
2010-03-19
pbug
cn1->namelen = namelen;
0761
2010-03-19
pbug
cn1->sd = sd0;
0762
2010-03-19
pbug
cn1->type = DNS_TYPE_A;
0763
2010-03-19
pbug
0764
2014-05-01
pjp
SLIST_INSERT_HEAD(&collectshead, cn1, collect_entry);
0765
2010-03-19
pbug
}
0766
2010-03-19
pbug
}
0767
2010-03-19
pbug
0768
2010-03-19
pbug
}
0769
2010-04-05
pbug
sd0 = Lookup_zone(db, name, namelen, htons(DNS_TYPE_AAAA), wildcard);
0770
2010-03-19
pbug
if (sd0 != NULL) {
0771
2010-03-19
pbug
cn1 = malloc(sizeof(struct collects));
0772
2010-03-19
pbug
if (cn1 != NULL) {
0773
2010-03-19
pbug
cn1->name = malloc(namelen);
0774
2010-03-19
pbug
if (cn1->name != NULL) {
0775
2010-03-19
pbug
memcpy(cn1->name, name, namelen);
0776
2010-03-19
pbug
cn1->namelen = namelen;
0777
2010-03-19
pbug
cn1->sd = sd0;
0778
2010-03-19
pbug
cn1->type = DNS_TYPE_AAAA;
0779
2010-03-19
pbug
0780
2014-05-01
pjp
SLIST_INSERT_HEAD(&collectshead, cn1, collect_entry);
0781
2010-03-19
pbug
0782
2010-03-19
pbug
}
0783
2010-03-19
pbug
}
0784
2010-03-19
pbug
0785
2010-03-19
pbug
}
0786
2010-03-19
pbug
0787
2010-03-19
pbug
outlen += (12 + namelen);
0788
2010-03-19
pbug
0789
2010-04-01
pbug
/* compress the label if possible */
0790
2010-07-27
pbug
if ((tmplen = compress_label((u_char*)reply, outlen, namelen)) > 0) {
0791
2010-04-01
pbug
/* XXX */
0792
2010-04-01
pbug
outlen = tmplen;
0793
2010-04-01
pbug
}
0794
2010-03-19
pbug
0795
2010-04-01
pbug
answer->rdlength = htons(&reply[outlen] - &answer->ns);
0796
2010-04-01
pbug
0797
2010-04-01
pbug
0798
2005-11-29
pbug
/* can we afford to write another header? if no truncate */
0799
2014-05-11
pjp
if (sd->ns_count > 1 && (outlen + 12 + sd->ns[pos % mod].nslen) > replysize) {
0800
2005-11-29
pbug
NTOHS(odh->query);
0801
2005-11-29
pbug
SET_DNS_TRUNCATION(odh);
0802
2005-11-29
pbug
HTONS(odh->query);
0803
2005-11-29
pbug
goto out;
0804
2005-11-29
pbug
}
0805
2005-11-29
pbug
0806
2009-11-03
pbug
pos++;
0807
2005-11-29
pbug
/* set new offset for answer */
0808
2005-11-29
pbug
answer = (struct answer *)&reply[outlen];
0809
2010-04-01
pbug
} while (++ns_count < RECORD_COUNT && --sd->ns_count);
0810
2005-11-29
pbug
0811
2010-03-19
pbug
/* shuffle through our linked collect structure and add additional */
0812
2010-03-19
pbug
0813
2014-05-01
pjp
SLIST_FOREACH(cnp, &collectshead, collect_entry) {
0814
2010-03-19
pbug
int addcount;
0815
2010-03-19
pbug
int tmplen;
0816
2010-03-19
pbug
0817
2010-03-19
pbug
switch (cnp->type) {
0818
2010-03-19
pbug
case DNS_TYPE_A:
0819
2014-04-21
pjp
tmplen = additional_a(cnp->name, cnp->namelen, cnp->sd, reply, replysize, outlen, &addcount);
0820
2010-03-19
pbug
additional += addcount;
0821
2010-03-19
pbug
break;
0822
2010-03-19
pbug
case DNS_TYPE_AAAA:
0823
2014-04-21
pjp
tmplen = additional_aaaa(cnp->name, cnp->namelen, cnp->sd, reply, replysize, outlen, &addcount);
0824
2010-03-19
pbug
additional += addcount;
0825
2010-03-19
pbug
break;
0826
2010-03-12
pbug
}
0827
2010-03-19
pbug
0828
2010-03-19
pbug
if (tmplen > 0) {
0829
2010-03-19
pbug
outlen = tmplen;
0830
2010-03-19
pbug
}
0831
2010-03-19
pbug
}
0832
2010-03-19
pbug
0833
2010-03-19
pbug
odh->additional = htons(additional);
0834
2010-03-19
pbug
0835
2010-03-19
pbug
while (!SLIST_EMPTY(&collectshead)) {
0836
2010-03-19
pbug
cn1 = SLIST_FIRST(&collectshead);
0837
2014-05-01
pjp
SLIST_REMOVE_HEAD(&collectshead, collect_entry);
0838
2010-03-19
pbug
free(cn1->name);
0839
2010-03-19
pbug
free(cn1->sd);
0840
2010-03-19
pbug
free(cn1);
0841
2010-03-19
pbug
}
0842
2010-03-19
pbug
0843
2014-05-10
pjp
if (q->edns0len) {
0844
2014-05-10
pjp
/* tag on edns0 opt record */
0845
2014-05-10
pjp
NTOHS(odh->additional);
0846
2014-05-10
pjp
odh->additional++;
0847
2014-05-10
pjp
HTONS(odh->additional);
0848
2014-05-10
pjp
0849
2014-05-10
pjp
outlen = additional_opt(q, reply, replysize, outlen);
0850
2014-05-10
pjp
}
0851
2014-05-10
pjp
0852
2010-03-19
pbug
out:
0853
2010-09-25
pbug
if (sreply->sr != NULL) {
0854
2014-10-08
pjp
retlen = reply_raw2(so, reply, outlen, sreply->sr);
0855
2010-09-25
pbug
} else {
0856
2010-09-25
pbug
if (istcp) {
0857
2010-09-25
pbug
char *tmpbuf;
0858
2010-03-19
pbug
0859
2010-09-25
pbug
tmpbuf = malloc(outlen + 2);
0860
2010-09-25
pbug
if (tmpbuf == NULL) {
0861
2013-02-16
pjp
dolog(LOG_INFO, "malloc: %s\n", strerror(errno));
0862
2010-09-25
pbug
}
0863
2010-09-25
pbug
plen = (u_int16_t *)tmpbuf;
0864
2010-09-25
pbug
*plen = htons(outlen);
0865
2010-09-25
pbug
0866
2010-09-25
pbug
memcpy(&tmpbuf[2], reply, outlen);
0867
2014-10-08
pjp
if ((retlen = send(so, tmpbuf, outlen + 2, 0)) < 0) {
0868
2013-02-16
pjp
dolog(LOG_INFO, "send: %s\n", strerror(errno));
0869
2010-09-25
pbug
}
0870
2010-09-25
pbug
free(tmpbuf);
0871
2010-09-25
pbug
} else {
0872
2014-10-08
pjp
if ((retlen = sendto(so, reply, outlen, 0, sa, salen)) < 0) {
0873
2013-02-16
pjp
dolog(LOG_INFO, "sendto: %s\n", strerror(errno));
0874
2010-09-25
pbug
}
0875
2010-03-12
pbug
}
0876
2005-11-29
pbug
}
0877
2005-11-29
pbug
0878
2009-11-03
pbug
sd->ns_ptr = (sd->ns_ptr + 1) % mod;
0879
2009-11-03
pbug
sd->ns_count = mod;
0880
2009-11-03
pbug
0881
2009-11-03
pbug
update_db(db, sd);
0882
2009-11-03
pbug
0883
2014-10-08
pjp
return (retlen);
0884
2005-11-29
pbug
}
0885
2005-11-29
pbug
0886
2005-11-29
pbug
0887
2005-11-29
pbug
/*
0888
2005-11-29
pbug
* REPLY_CNAME() - replies a DNS question (*q) on socket (so)
0889
2005-11-29
pbug
*
0890
2005-11-29
pbug
*/
0891
2005-11-29
pbug
0892
2005-11-29
pbug
0893
2014-10-08
pjp
int
0894
2005-11-29
pbug
reply_cname(struct sreply *sreply)
0895
2005-11-29
pbug
{
0896
2014-04-21
pjp
char *reply = sreply->replybuf;
0897
2005-11-29
pbug
struct dns_header *odh;
0898
2010-04-15
pbug
u_int16_t outlen;
0899
2005-11-29
pbug
char *p;
0900
2005-11-29
pbug
int i, tmplen;
0901
2005-11-29
pbug
int labellen;
0902
2005-11-29
pbug
char *label, *plabel;
0903
2005-11-29
pbug
int addcount;
0904
2010-03-12
pbug
u_int16_t *plen;
0905
2005-11-29
pbug
0906
2005-11-29
pbug
struct answer {
0907
2005-11-29
pbug
char name[2];
0908
2005-11-29
pbug
u_int16_t type;
0909
2005-11-29
pbug
u_int16_t class;
0910
2005-11-29
pbug
u_int32_t ttl;
0911
2005-11-29
pbug
u_int16_t rdlength; /* 12 */
0912
2005-11-29
pbug
char rdata;
0913
2005-11-29
pbug
} __attribute__((packed));
0914
2005-11-29
pbug
0915
2005-11-29
pbug
struct answer *answer;
0916
2005-11-29
pbug
0917
2005-11-29
pbug
int so = sreply->so;
0918
2005-11-29
pbug
char *buf = sreply->buf;
0919
2005-11-29
pbug
int len = sreply->len;
0920
2005-11-29
pbug
struct question *q = sreply->q;
0921
2005-11-29
pbug
struct sockaddr *sa = sreply->sa;
0922
2005-11-29
pbug
int salen = sreply->salen;
0923
2005-11-29
pbug
struct domain *sd = sreply->sd1;
0924
2005-11-29
pbug
struct domain *sd1 = sreply->sd2;
0925
2010-03-12
pbug
int istcp = sreply->istcp;
0926
2014-04-21
pjp
int replysize = 512;
0927
2014-10-08
pjp
int retlen = -1;
0928
2005-11-29
pbug
0929
2014-04-21
pjp
if (istcp) {
0930
2014-04-21
pjp
replysize = 65535;
0931
2014-04-21
pjp
}
0932
2014-04-21
pjp
0933
2014-05-10
pjp
if (q->edns0len > 512)
0934
2014-05-10
pjp
replysize = q->edns0len;
0935
2014-05-10
pjp
0936
2005-11-29
pbug
odh = (struct dns_header *)&reply[0];
0937
2005-11-29
pbug
outlen = sizeof(struct dns_header);
0938
2005-11-29
pbug
0939
2014-04-21
pjp
if (len > replysize) {
0940
2014-10-08
pjp
return (retlen);
0941
2005-11-29
pbug
}
0942
2005-11-29
pbug
0943
2005-11-29
pbug
/* copy question to reply */
0944
2014-04-21
pjp
memcpy(reply, buf, sizeof(struct dns_header) + q->hdr->namelen + 4);
0945
2010-03-12
pbug
0946
2005-11-29
pbug
/* blank query */
0947
2005-11-29
pbug
memset((char *)&odh->query, 0, sizeof(u_int16_t));
0948
2005-11-29
pbug
0949
2005-11-29
pbug
outlen += (q->hdr->namelen + 4);
0950
2005-11-29
pbug
0951
2005-11-29
pbug
SET_DNS_REPLY(odh);
0952
2010-09-26
pbug
if (sreply->sr == NULL)
0953
2010-09-26
pbug
SET_DNS_AUTHORITATIVE(odh);
0954
2010-09-26
pbug
else
0955
2010-09-26
pbug
SET_DNS_RECURSION_AVAIL(odh);
0956
2005-11-29
pbug
0957
2005-11-29
pbug
HTONS(odh->query);
0958
2005-11-29
pbug
0959
2005-11-29
pbug
odh->question = htons(1);
0960
2005-11-29
pbug
odh->answer = htons(1);
0961
2005-11-29
pbug
odh->nsrr = 0;
0962
2005-11-29
pbug
odh->additional = 0;
0963
2005-11-29
pbug
0964
2005-11-29
pbug
answer = (struct answer *)(&reply[0] + sizeof(struct dns_header) +
0965
2005-11-29
pbug
q->hdr->namelen + 4);
0966
2005-11-29
pbug
0967
2005-11-29
pbug
answer->name[0] = 0xc0;
0968
2005-11-29
pbug
answer->name[1] = 0x0c;
0969
2010-03-18
pbug
answer->type = htons(DNS_TYPE_CNAME);
0970
2005-11-29
pbug
answer->class = q->hdr->qclass;
0971
2010-09-26
pbug
if (sreply->sr != NULL)
0972
2010-09-26
pbug
answer->ttl = htonl(sd->ttl - (time(NULL) - sd->created));
0973
2010-09-26
pbug
else
0974
2010-09-26
pbug
answer->ttl = htonl(sd->ttl);
0975
2005-11-29
pbug
0976
2005-11-29
pbug
outlen += 12; /* up to rdata length */
0977
2005-11-29
pbug
0978
2005-11-29
pbug
p = (char *)&answer->rdata;
0979
2005-11-29
pbug
0980
2005-11-29
pbug
label = &sd->cname[0];
0981
2005-11-29
pbug
labellen = sd->cnamelen;
0982
2005-11-29
pbug
0983
2005-11-29
pbug
plabel = label;
0984
2005-11-29
pbug
0985
2005-11-29
pbug
/* copy label to reply */
0986
2014-04-21
pjp
for (i = outlen; i < replysize; i++) {
0987
2005-11-29
pbug
if (i - outlen == labellen)
0988
2005-11-29
pbug
break;
0989
2005-11-29
pbug
0990
2005-11-29
pbug
reply[i] = *plabel++;
0991
2005-11-29
pbug
}
0992
2005-11-29
pbug
0993
2014-04-21
pjp
if (i >= replysize)
0994
2014-10-08
pjp
return (retlen);
0995
2005-11-29
pbug
0996
2005-11-29
pbug
outlen = i;
0997
2005-11-29
pbug
0998
2005-11-29
pbug
/* compress the label if possible */
0999
2010-07-27
pbug
if ((tmplen = compress_label((u_char*)reply, outlen, labellen)) > 0) {
1000
2005-11-29
pbug
/* XXX */
1001
2005-11-29
pbug
outlen = tmplen;
1002
2005-11-29
pbug
}
1003
2005-11-29
pbug
1004
2005-11-29
pbug
answer->rdlength = htons(&reply[outlen] - &answer->rdata);
1005
2005-11-29
pbug
1006
2010-03-12
pbug
1007
2005-11-29
pbug
if (ntohs(q->hdr->qtype) == DNS_TYPE_A && sd1 != NULL) {
1008
2014-04-21
pjp
tmplen = additional_a(sd->cname, sd->cnamelen, sd1, reply, replysize, outlen, &addcount);
1009
2010-03-12
pbug
1010
2005-11-29
pbug
if (tmplen > 0)
1011
2005-11-29
pbug
outlen = tmplen;
1012
2005-11-29
pbug
1013
2005-11-29
pbug
NTOHS(odh->answer);
1014
2005-11-29
pbug
odh->answer += addcount;
1015
2005-11-29
pbug
HTONS(odh->answer);
1016
2005-11-29
pbug
} else if (ntohs(q->hdr->qtype) == DNS_TYPE_AAAA && sd1 != NULL) {
1017
2014-04-21
pjp
tmplen = additional_aaaa(sd->cname, sd->cnamelen, sd1, reply, replysize, outlen, &addcount);
1018
2010-03-12
pbug
1019
2005-11-29
pbug
if (tmplen > 0)
1020
2005-11-29
pbug
outlen = tmplen;
1021
2005-11-29
pbug
1022
2005-11-29
pbug
NTOHS(odh->answer);
1023
2005-11-29
pbug
odh->answer += addcount;
1024
2005-11-29
pbug
HTONS(odh->answer);
1025
2005-11-29
pbug
} else if (ntohs(q->hdr->qtype) == DNS_TYPE_MX && sd1 != NULL) {
1026
2014-04-21
pjp
tmplen = additional_mx(sd->cname, sd->cnamelen, sd1, reply, replysize, outlen, &addcount);
1027
2010-03-12
pbug
1028
2005-11-29
pbug
if (tmplen > 0)
1029
2005-11-29
pbug
outlen = tmplen;
1030
2005-11-29
pbug
1031
2005-11-29
pbug
NTOHS(odh->answer);
1032
2005-11-29
pbug
odh->answer += addcount;
1033
2005-11-29
pbug
HTONS(odh->answer);
1034
2005-11-29
pbug
} else if (ntohs(q->hdr->qtype) == DNS_TYPE_PTR && sd1 != NULL) {
1035
2014-04-21
pjp
tmplen = additional_ptr(sd->cname, sd->cnamelen, sd1, reply, replysize, outlen, &addcount);
1036
2010-03-12
pbug
1037
2005-11-29
pbug
if (tmplen > 0)
1038
2005-11-29
pbug
outlen = tmplen;
1039
2005-11-29
pbug
1040
2005-11-29
pbug
NTOHS(odh->answer);
1041
2005-11-29
pbug
odh->answer += addcount;
1042
2005-11-29
pbug
HTONS(odh->answer);
1043
2005-11-29
pbug
}
1044
2010-03-12
pbug
1045
2014-05-10
pjp
if (q->edns0len) {
1046
2014-05-10
pjp
/* tag on edns0 opt record */
1047
2014-05-10
pjp
NTOHS(odh->additional);
1048
2014-05-10
pjp
odh->additional++;
1049
2014-05-10
pjp
HTONS(odh->additional);
1050
2014-05-10
pjp
1051
2014-05-10
pjp
outlen = additional_opt(q, reply, replysize, outlen);
1052
2014-05-10
pjp
}
1053
2014-05-10
pjp
1054
2010-09-26
pbug
if (sreply->sr != NULL) {
1055
2014-10-08
pjp
retlen = reply_raw2(so, reply, outlen, sreply->sr);
1056
2010-03-12
pbug
} else {
1057
2010-09-26
pbug
if (istcp) {
1058
2010-09-26
pbug
char *tmpbuf;
1059
2010-09-26
pbug
1060
2010-09-26
pbug
tmpbuf = malloc(outlen + 2);
1061
2010-09-26
pbug
if (tmpbuf == NULL) {
1062
2013-02-16
pjp
dolog(LOG_INFO, "malloc: %s\n", strerror(errno));
1063
2010-09-26
pbug
}
1064
2010-09-26
pbug
plen = (u_int16_t *)tmpbuf;
1065
2010-09-26
pbug
*plen = htons(outlen);
1066
2010-09-26
pbug
1067
2010-09-26
pbug
memcpy(&tmpbuf[2], reply, outlen);
1068
2010-09-26
pbug
1069
2014-10-08
pjp
if ((retlen = send(so, tmpbuf, outlen + 2, 0)) < 0) {
1070
2013-02-16
pjp
dolog(LOG_INFO, "send: %s\n", strerror(errno));
1071
2010-09-26
pbug
}
1072
2010-09-26
pbug
free(tmpbuf);
1073
2010-09-26
pbug
} else {
1074
2014-10-08
pjp
if ((retlen = sendto(so, reply, outlen, 0, sa, salen)) < 0) {
1075
2013-02-16
pjp
dolog(LOG_INFO, "sendto: %s\n", strerror(errno));
1076
2010-09-26
pbug
}
1077
2010-03-12
pbug
}
1078
2010-03-12
pbug
}
1079
2010-03-12
pbug
1080
2014-10-08
pjp
return (retlen);
1081
2005-11-29
pbug
}
1082
2005-11-29
pbug
1083
2005-11-29
pbug
/*
1084
2005-11-29
pbug
* REPLY_PTR() - replies a DNS question (*q) on socket (so)
1085
2005-11-29
pbug
*
1086
2005-11-29
pbug
*/
1087
2005-11-29
pbug
1088
2014-10-08
pjp
int
1089
2005-11-29
pbug
reply_ptr(struct sreply *sreply)
1090
2005-11-29
pbug
{
1091
2014-04-21
pjp
char *reply = sreply->replybuf;
1092
2005-11-29
pbug
struct dns_header *odh;
1093
2010-04-15
pbug
u_int16_t outlen;
1094
2005-11-29
pbug
char *p;
1095
2005-11-29
pbug
int i, tmplen;
1096
2005-11-29
pbug
int labellen;
1097
2005-11-29
pbug
char *label, *plabel;
1098
2005-11-29
pbug
1099
2005-11-29
pbug
struct answer {
1100
2005-11-29
pbug
char name[2];
1101
2005-11-29
pbug
u_int16_t type;
1102
2005-11-29
pbug
u_int16_t class;
1103
2005-11-29
pbug
u_int32_t ttl;
1104
2005-11-29
pbug
u_int16_t rdlength; /* 12 */
1105
2005-11-29
pbug
char rdata;
1106
2005-11-29
pbug
} __attribute__((packed));
1107
2005-11-29
pbug
1108
2005-11-29
pbug
struct answer *answer;
1109
2005-11-29
pbug
1110
2005-11-29
pbug
int so = sreply->so;
1111
2005-11-29
pbug
char *buf = sreply->buf;
1112
2005-11-29
pbug
int len = sreply->len;
1113
2005-11-29
pbug
struct question *q = sreply->q;
1114
2005-11-29
pbug
struct sockaddr *sa = sreply->sa;
1115
2005-11-29
pbug
int salen = sreply->salen;
1116
2005-11-29
pbug
struct domain *sd = sreply->sd1;
1117
2010-03-12
pbug
int istcp = sreply->istcp;
1118
2014-04-21
pjp
int replysize = 512;
1119
2014-10-08
pjp
int retlen = -1;
1120
2014-04-21
pjp
1121
2014-04-21
pjp
if (istcp) {
1122
2014-04-21
pjp
replysize = 65535;
1123
2014-04-21
pjp
}
1124
2014-05-10
pjp
1125
2014-05-10
pjp
if (q->edns0len > 512)
1126
2014-05-10
pjp
replysize = q->edns0len;
1127
2005-11-29
pbug
1128
2005-11-29
pbug
odh = (struct dns_header *)&reply[0];
1129
2005-11-29
pbug
outlen = sizeof(struct dns_header);
1130
2005-11-29
pbug
1131
2005-11-29
pbug
1132
2014-04-21
pjp
if (len > replysize) {
1133
2014-10-08
pjp
return (retlen);
1134
2005-11-29
pbug
}
1135
2005-11-29
pbug
1136
2005-11-29
pbug
/* copy question to reply */
1137
2014-04-21
pjp
memcpy(reply, buf, sizeof(struct dns_header) + q->hdr->namelen + 4);
1138
2005-11-29
pbug
/* blank query */
1139
2005-11-29
pbug
memset((char *)&odh->query, 0, sizeof(u_int16_t));
1140
2005-11-29
pbug
1141
2005-11-29
pbug
outlen += (q->hdr->namelen + 4);
1142
2005-11-29
pbug
1143
2005-11-29
pbug
SET_DNS_REPLY(odh);
1144
2010-09-26
pbug
if (sreply->sr == NULL)
1145
2010-09-26
pbug
SET_DNS_AUTHORITATIVE(odh);
1146
2010-09-26
pbug
else
1147
2010-09-26
pbug
SET_DNS_RECURSION_AVAIL(odh);
1148
2005-11-29
pbug
1149
2005-11-29
pbug
HTONS(odh->query);
1150
2005-11-29
pbug
1151
2010-03-18
pbug
odh->question = htons(1);
1152
2010-03-18
pbug
odh->answer = htons(1);
1153
2005-11-29
pbug
odh->nsrr = 0;
1154
2005-11-29
pbug
odh->additional = 0;
1155
2005-11-29
pbug
1156
2005-11-29
pbug
answer = (struct answer *)(&reply[0] + sizeof(struct dns_header) +
1157
2005-11-29
pbug
q->hdr->namelen + 4);
1158
2005-11-29
pbug
1159
2005-11-29
pbug
answer->name[0] = 0xc0;
1160
2005-11-29
pbug
answer->name[1] = 0x0c;
1161
2005-11-29
pbug
answer->type = q->hdr->qtype;
1162
2005-11-29
pbug
answer->class = q->hdr->qclass;
1163
2010-09-26
pbug
if (sreply->sr != NULL)
1164
2010-09-26
pbug
answer->ttl = htonl(sd->ttl - (time(NULL) - sd->created));
1165
2010-09-26
pbug
else
1166
2010-09-26
pbug
answer->ttl = htonl(sd->ttl);
1167
2005-11-29
pbug
1168
2005-11-29
pbug
outlen += 12; /* up to rdata length */
1169
2005-11-29
pbug
1170
2005-11-29
pbug
p = (char *)&answer->rdata;
1171
2005-11-29
pbug
1172
2005-11-29
pbug
label = &sd->ptr[0];
1173
2005-11-29
pbug
labellen = sd->ptrlen;
1174
2005-11-29
pbug
1175
2005-11-29
pbug
plabel = label;
1176
2005-11-29
pbug
1177
2005-11-29
pbug
/* copy label to reply */
1178
2014-04-21
pjp
for (i = outlen; i < replysize; i++) {
1179
2005-11-29
pbug
if (i - outlen == labellen)
1180
2005-11-29
pbug
break;
1181
2005-11-29
pbug
1182
2005-11-29
pbug
reply[i] = *plabel++;
1183
2005-11-29
pbug
}
1184
2005-11-29
pbug
1185
2014-04-21
pjp
if (i >= replysize) {
1186
2014-10-08
pjp
return (retlen);
1187
2005-11-29
pbug
}
1188
2005-11-29
pbug
1189
2005-11-29
pbug
outlen = i;
1190
2005-11-29
pbug
1191
2005-11-29
pbug
/* compress the label if possible */
1192
2010-07-27
pbug
if ((tmplen = compress_label((u_char*)reply, outlen, labellen)) > 0) {
1193
2005-11-29
pbug
outlen = tmplen;
1194
2005-11-29
pbug
}
1195
2005-11-29
pbug
1196
2005-11-29
pbug
answer->rdlength = htons(&reply[outlen] - &answer->rdata);
1197
2014-05-10
pjp
1198
2014-05-10
pjp
if (q->edns0len) {
1199
2014-05-10
pjp
/* tag on edns0 opt record */
1200
2014-05-10
pjp
NTOHS(odh->additional);
1201
2014-05-10
pjp
odh->additional++;
1202
2014-05-10
pjp
HTONS(odh->additional);
1203
2014-05-10
pjp
1204
2014-05-10
pjp
outlen = additional_opt(q, reply, replysize, outlen);
1205
2014-05-10
pjp
}
1206
2005-11-29
pbug
1207
2010-09-26
pbug
if (sreply->sr != NULL) {
1208
2014-10-08
pjp
retlen = reply_raw2(so, reply, outlen, sreply->sr);
1209
2010-09-26
pbug
} else {
1210
2010-09-26
pbug
if (istcp) {
1211
2010-09-26
pbug
char *tmpbuf;
1212
2010-09-26
pbug
u_int16_t *plen;
1213
2010-03-12
pbug
1214
2010-09-26
pbug
tmpbuf = malloc(outlen + 2);
1215
2010-09-26
pbug
if (tmpbuf == NULL) {
1216
2013-02-16
pjp
dolog(LOG_INFO, "malloc: %s\n", strerror(errno));
1217
2010-09-26
pbug
}
1218
2010-09-26
pbug
plen = (u_int16_t *)tmpbuf;
1219
2010-09-26
pbug
*plen = htons(outlen);
1220
2010-09-26
pbug
1221
2010-09-26
pbug
memcpy(&tmpbuf[2], reply, outlen);
1222
2010-03-12
pbug
1223
2014-10-08
pjp
if ((retlen = send(so, tmpbuf, outlen + 2, 0)) < 0) {
1224
2013-02-16
pjp
dolog(LOG_INFO, "send: %s\n", strerror(errno));
1225
2010-09-26
pbug
}
1226
2010-09-26
pbug
free(tmpbuf);
1227
2010-09-26
pbug
} else {
1228
2014-10-08
pjp
if ((retlen = sendto(so, reply, outlen, 0, sa, salen)) < 0) {
1229
2013-02-16
pjp
dolog(LOG_INFO, "sendto: %s\n", strerror(errno));
1230
2010-09-26
pbug
}
1231
2010-03-12
pbug
}
1232
2005-11-29
pbug
}
1233
2005-11-29
pbug
1234
2014-10-08
pjp
return (retlen);
1235
2005-11-29
pbug
}
1236
2005-11-29
pbug
1237
2005-11-29
pbug
/*
1238
2005-11-29
pbug
* REPLY_SOA() - replies a DNS question (*q) on socket (so)
1239
2005-11-29
pbug
*
1240
2005-11-29
pbug
*/
1241
2005-11-29
pbug
1242
2005-11-29
pbug
1243
2014-10-08
pjp
int
1244
2005-11-29
pbug
reply_soa(struct sreply *sreply)
1245
2005-11-29
pbug
{
1246
2014-04-21
pjp
char *reply = sreply->replybuf;
1247
2005-11-29
pbug
struct dns_header *odh;
1248
2010-04-15
pbug
u_int16_t outlen;
1249
2005-11-29
pbug
char *p;
1250
2005-11-29
pbug
u_int32_t *soa_val;
1251
2005-11-29
pbug
int i, tmplen;
1252
2005-11-29
pbug
int labellen;
1253
2005-11-29
pbug
char *label, *plabel;
1254
2005-11-29
pbug
1255
2005-11-29
pbug
struct answer {
1256
2005-11-29
pbug
char name[2];
1257
2005-11-29
pbug
u_int16_t type;
1258
2005-11-29
pbug
u_int16_t class;
1259
2005-11-29
pbug
u_int32_t ttl;
1260
2005-11-29
pbug
u_int16_t rdlength; /* 12 */
1261
2005-11-29
pbug
char rdata;
1262
2005-11-29
pbug
} __attribute__((packed));
1263
2005-11-29
pbug
1264
2005-11-29
pbug
struct soa {
1265
2005-11-29
pbug
char *nsserver;
1266
2005-11-29
pbug
char *responsible_person;
1267
2005-11-29
pbug
u_int32_t serial;
1268
2005-11-29
pbug
u_int32_t refresh;
1269
2005-11-29
pbug
u_int32_t retry;
1270
2005-11-29
pbug
u_int32_t expire;
1271
2005-11-29
pbug
u_int32_t minttl;
1272
2005-11-29
pbug
};
1273
2005-11-29
pbug
1274
2005-11-29
pbug
1275
2005-11-29
pbug
struct answer *answer;
1276
2005-11-29
pbug
1277
2005-11-29
pbug
int so = sreply->so;
1278
2005-11-29
pbug
char *buf = sreply->buf;
1279
2005-11-29
pbug
int len = sreply->len;
1280
2005-11-29
pbug
struct question *q = sreply->q;
1281
2005-11-29
pbug
struct sockaddr *sa = sreply->sa;
1282
2005-11-29
pbug
int salen = sreply->salen;
1283
2005-11-29
pbug
struct domain *sd = sreply->sd1;
1284
2010-03-12
pbug
int istcp = sreply->istcp;
1285
2014-04-21
pjp
int replysize = 512;
1286
2014-10-08
pjp
int retlen = -1;
1287
2014-04-21
pjp
1288
2014-04-21
pjp
if (istcp) {
1289
2014-04-21
pjp
replysize = 65535;
1290
2014-04-21
pjp
}
1291
2014-05-10
pjp
1292
2014-05-10
pjp
if (q->edns0len > 512)
1293
2014-05-10
pjp
replysize = q->edns0len;
1294
2010-03-28
pbug
1295
2010-03-28
pbug
/* st */
1296
2005-11-29
pbug
1297
2005-11-29
pbug
odh = (struct dns_header *)&reply[0];
1298
2005-11-29
pbug
outlen = sizeof(struct dns_header);
1299
2005-11-29
pbug
1300
2014-04-21
pjp
if (len > replysize) {
1301
2014-10-08
pjp
return (retlen);
1302
2005-11-29
pbug
}
1303
2005-11-29
pbug
1304
2005-11-29
pbug
/* copy question to reply */
1305
2014-04-21
pjp
memcpy(reply, buf, sizeof(struct dns_header) + q->hdr->namelen + 4);
1306
2005-11-29
pbug
/* blank query */
1307
2005-11-29
pbug
memset((char *)&odh->query, 0, sizeof(u_int16_t));
1308
2005-11-29
pbug
1309
2005-11-29
pbug
outlen += (q->hdr->namelen + 4);
1310
2005-11-29
pbug
1311
2005-11-29
pbug
SET_DNS_REPLY(odh);
1312
2010-09-26
pbug
if (sreply->sr == NULL)
1313
2010-09-26
pbug
SET_DNS_AUTHORITATIVE(odh);
1314
2010-09-26
pbug
else
1315
2010-09-26
pbug
SET_DNS_RECURSION_AVAIL(odh);
1316
2005-11-29
pbug
1317
2005-11-29
pbug
NTOHS(odh->query);
1318
2005-11-29
pbug
1319
2010-03-18
pbug
odh->question = htons(1);
1320
2010-03-18
pbug
odh->answer = htons(1);
1321
2005-11-29
pbug
odh->nsrr = 0;
1322
2005-11-29
pbug
odh->additional = 0;
1323
2005-11-29
pbug
1324
2005-11-29
pbug
answer = (struct answer *)(&reply[0] + sizeof(struct dns_header) +
1325
2005-11-29
pbug
q->hdr->namelen + 4);
1326
2005-11-29
pbug
1327
2005-11-29
pbug
answer->name[0] = 0xc0;
1328
2005-11-29
pbug
answer->name[1] = 0x0c;
1329
2005-11-29
pbug
answer->type = q->hdr->qtype;
1330
2005-11-29
pbug
answer->class = q->hdr->qclass;
1331
2010-09-26
pbug
if (sreply->sr != NULL)
1332
2010-09-26
pbug
answer->ttl = htonl(sd->ttl - (time(NULL) - sd->created));
1333
2010-09-26
pbug
else
1334
2010-09-26
pbug
answer->ttl = htonl(sd->ttl);
1335
2005-11-29
pbug
1336
2005-11-29
pbug
outlen += 12; /* up to rdata length */
1337
2005-11-29
pbug
1338
2005-11-29
pbug
p = (char *)&answer->rdata;
1339
2005-11-29
pbug
1340
2005-11-29
pbug
1341
2011-09-19
pbug
label = sd->soa.nsserver;
1342
2011-09-19
pbug
labellen = sd->soa.nsserver_len;
1343
2005-11-29
pbug
1344
2005-11-29
pbug
plabel = label;
1345
2005-11-29
pbug
1346
2005-11-29
pbug
/* copy label to reply */
1347
2014-04-21
pjp
for (i = outlen; i < replysize; i++) {
1348
2005-11-29
pbug
if (i - outlen == labellen)
1349
2005-11-29
pbug
break;
1350
2005-11-29
pbug
1351
2005-11-29
pbug
reply[i] = *plabel++;
1352
2005-11-29
pbug
}
1353
2005-11-29
pbug
1354
2014-04-21
pjp
if (i >= replysize) {
1355
2014-10-08
pjp
return (retlen);
1356
2005-11-29
pbug
}
1357
2005-11-29
pbug
1358
2005-11-29
pbug
outlen = i;
1359
2005-11-29
pbug
1360
2005-11-29
pbug
/* compress the label if possible */
1361
2010-07-27
pbug
if ((tmplen = compress_label((u_char*)reply, outlen, labellen)) > 0) {
1362
2005-11-29
pbug
outlen = tmplen;
1363
2005-11-29
pbug
}
1364
2005-11-29
pbug
1365
2011-09-19
pbug
label = sd->soa.responsible_person;
1366
2011-09-19
pbug
labellen = sd->soa.rp_len;
1367
2005-11-29
pbug
plabel = label;
1368
2005-11-29
pbug
1369
2014-04-21
pjp
for (i = outlen; i < replysize; i++) {
1370
2005-11-29
pbug
if (i - outlen == labellen)
1371
2005-11-29
pbug
break;
1372
2005-11-29
pbug
1373
2005-11-29
pbug
reply[i] = *plabel++;
1374
2005-11-29
pbug
}
1375
2005-11-29
pbug
1376
2014-04-21
pjp
if (i >= replysize) {
1377
2014-10-08
pjp
return (retlen);
1378
2005-11-29
pbug
}
1379
2005-11-29
pbug
1380
2005-11-29
pbug
outlen = i;
1381
2005-11-29
pbug
1382
2005-11-29
pbug
/* 2 compress the label if possible */
1383
2005-11-29
pbug
1384
2010-07-27
pbug
if ((tmplen = compress_label((u_char*)reply, outlen, labellen)) > 0) {
1385
2005-11-29
pbug
outlen = tmplen;
1386
2005-11-29
pbug
}
1387
2005-11-29
pbug
1388
2005-11-29
pbug
1389
2010-03-28
pbug
/* XXX */
1390
2014-04-21
pjp
if ((outlen + sizeof(sd->soa.serial)) > replysize) {
1391
2005-11-29
pbug
/* XXX server error reply? */
1392
2014-10-08
pjp
return (retlen);
1393
2005-11-29
pbug
}
1394
2005-11-29
pbug
soa_val = (u_int32_t *)&reply[outlen];
1395
2011-09-19
pbug
*soa_val = htonl(sd->soa.serial);
1396
2011-09-19
pbug
outlen += sizeof(sd->soa.serial); /* XXX */
1397
2005-11-29
pbug
1398
2010-03-28
pbug
/* XXX */
1399
2014-04-21
pjp
if ((outlen + sizeof(sd->soa.refresh)) > replysize) {
1400
2014-10-08
pjp
return (retlen);
1401
2005-11-29
pbug
}
1402
2005-11-29
pbug
soa_val = (u_int32_t *)&reply[outlen];
1403
2011-09-19
pbug
*soa_val = htonl(sd->soa.refresh);
1404
2011-09-19
pbug
outlen += sizeof(sd->soa.refresh); /* XXX */
1405
2005-11-29
pbug
1406
2014-04-21
pjp
if ((outlen + sizeof(sd->soa.retry)) > replysize) {
1407
2014-10-08
pjp
return (retlen);
1408
2005-11-29
pbug
}
1409
2005-11-29
pbug
soa_val = (u_int32_t *)&reply[outlen];
1410
2011-09-19
pbug
*soa_val = htonl(sd->soa.retry);
1411
2011-09-19
pbug
outlen += sizeof(sd->soa.retry); /* XXX */
1412
2005-11-29
pbug
1413
2014-04-21
pjp
if ((outlen + sizeof(sd->soa.expire)) > replysize) {
1414
2014-10-08
pjp
return (retlen);
1415
2005-11-29
pbug
}
1416
2005-11-29
pbug
soa_val = (u_int32_t *)&reply[outlen];
1417
2011-09-19
pbug
*soa_val = htonl(sd->soa.expire);
1418
2011-09-19
pbug
outlen += sizeof(sd->soa.expire);
1419
2005-11-29
pbug
1420
2014-04-21
pjp
if ((outlen + sizeof(sd->soa.minttl)) > replysize) {
1421
2014-10-08
pjp
return (retlen);
1422
2005-11-29
pbug
}
1423
2005-11-29
pbug
soa_val = (u_int32_t *)&reply[outlen];
1424
2011-09-19
pbug
*soa_val = htonl(sd->soa.minttl);
1425
2011-09-19
pbug
outlen += sizeof(sd->soa.minttl);
1426
2005-11-29
pbug
1427
2005-11-29
pbug
answer->rdlength = htons(&reply[outlen] - &answer->rdata);
1428
2014-05-10
pjp
1429
2014-05-10
pjp
if (q->edns0len) {
1430
2014-05-10
pjp
/* tag on edns0 opt record */
1431
2014-05-10
pjp
NTOHS(odh->additional);
1432
2014-05-10
pjp
odh->additional++;
1433
2014-05-10
pjp
HTONS(odh->additional);
1434
2014-05-10
pjp
1435
2014-05-10
pjp
outlen = additional_opt(q, reply, replysize, outlen);
1436
2014-05-10
pjp
}
1437
2005-11-29
pbug
1438
2010-09-26
pbug
if (sreply->sr != NULL) {
1439
2014-10-08
pjp
retlen = reply_raw2(so, reply, outlen, sreply->sr);
1440
2010-09-26
pbug
} else {
1441
2010-09-26
pbug
if (istcp) {
1442
2010-09-26
pbug
char *tmpbuf;
1443
2010-09-26
pbug
u_int16_t *plen;
1444
2010-03-27
pbug
1445
2010-09-26
pbug
tmpbuf = malloc(outlen + 2);
1446
2010-09-26
pbug
if (tmpbuf == NULL) {
1447
2013-02-16
pjp
dolog(LOG_INFO, "malloc: %s\n", strerror(errno));
1448
2010-09-26
pbug
}
1449
2010-09-26
pbug
plen = (u_int16_t *)tmpbuf;
1450
2010-09-26
pbug
*plen = htons(outlen);
1451
2010-09-26
pbug
1452
2010-09-26
pbug
memcpy(&tmpbuf[2], reply, outlen);
1453
2010-03-27
pbug
1454
2014-10-08
pjp
if ((retlen = send(so, tmpbuf, outlen + 2, 0)) < 0) {
1455
2013-02-16
pjp
dolog(LOG_INFO, "send: %s\n", strerror(errno));
1456
2010-09-26
pbug
}
1457
2010-09-26
pbug
free(tmpbuf);
1458
2010-09-26
pbug
} else {
1459
2014-10-08
pjp
if ((retlen = sendto(so, reply, outlen, 0, sa, salen)) < 0) {
1460
2013-02-16
pjp
dolog(LOG_INFO, "sendto: %s\n", strerror(errno));
1461
2010-09-26
pbug
}
1462
2010-03-27
pbug
}
1463
2010-09-26
pbug
}
1464
2010-09-26
pbug
1465
2014-10-08
pjp
return (retlen);
1466
2010-09-26
pbug
}
1467
2010-09-26
pbug
1468
2010-09-26
pbug
/*
1469
2014-04-21
pjp
* REPLY_SPF() - replies a DNS question (*q) on socket (so)
1470
2014-04-21
pjp
* based on reply_txt...
1471
2014-04-21
pjp
*/
1472
2014-04-21
pjp
1473
2014-04-21
pjp
1474
2014-10-08
pjp
int
1475
2014-04-21
pjp
reply_spf(struct sreply *sreply)
1476
2014-04-21
pjp
{
1477
2014-04-21
pjp
char *reply = sreply->replybuf;
1478
2014-04-21
pjp
struct dns_header *odh;
1479
2014-04-21
pjp
u_int16_t outlen;
1480
2014-04-21
pjp
char *p;
1481
2014-04-21
pjp
1482
2014-04-21
pjp
struct answer {
1483
2014-04-21
pjp
char name[2];
1484
2014-04-21
pjp
u_int16_t type;
1485
2014-04-21
pjp
u_int16_t class;
1486
2014-04-21
pjp
u_int32_t ttl;
1487
2014-04-21
pjp
u_int16_t rdlength; /* 12 */
1488
2014-04-21
pjp
char rdata;
1489
2014-04-21
pjp
} __attribute__((packed));
1490
2014-04-21
pjp
1491
2014-04-21
pjp
struct answer *answer;
1492
2014-04-21
pjp
1493
2014-04-21
pjp
int so = sreply->so;
1494
2014-04-21
pjp
char *buf = sreply->buf;
1495
2014-04-21
pjp
int len = sreply->len;
1496
2014-04-21
pjp
struct question *q = sreply->q;
1497
2014-04-21
pjp
struct sockaddr *sa = sreply->sa;
1498
2014-04-21
pjp
int salen = sreply->salen;
1499
2014-04-21
pjp
struct domain *sd = sreply->sd1;
1500
2014-04-21
pjp
int istcp = sreply->istcp;
1501
2014-04-21
pjp
int replysize = 512;
1502
2014-10-08
pjp
int retlen = -1;
1503
2014-04-21
pjp
1504
2014-04-21
pjp
if (istcp) {
1505
2014-04-21
pjp
replysize = 65535;
1506
2014-04-21
pjp
}
1507
2014-04-21
pjp
1508
2014-05-10
pjp
if (q->edns0len > 512)
1509
2014-05-10
pjp
replysize = q->edns0len;
1510
2014-05-10
pjp
1511
2014-04-21
pjp
/* st */
1512
2014-04-21
pjp
1513
2014-04-21
pjp
odh = (struct dns_header *)&reply[0];
1514
2014-04-21
pjp
outlen = sizeof(struct dns_header);
1515
2014-04-21
pjp
1516
2014-04-21
pjp
if (len > replysize) {
1517
2014-10-08
pjp
return (retlen);
1518
2014-04-21
pjp
}
1519
2014-04-21
pjp
1520
2014-04-21
pjp
/* copy question to reply */
1521
2014-04-21
pjp
memcpy(reply, buf, sizeof(struct dns_header) + q->hdr->namelen + 4);
1522
2014-04-21
pjp
/* blank query */
1523
2014-04-21
pjp
memset((char *)&odh->query, 0, sizeof(u_int16_t));
1524
2014-04-21
pjp
1525
2014-04-21
pjp
outlen += (q->hdr->namelen + 4);
1526
2014-04-21
pjp
1527
2014-04-21
pjp
SET_DNS_REPLY(odh);
1528
2014-04-21
pjp
if (sreply->sr == NULL)
1529
2014-04-21
pjp
SET_DNS_AUTHORITATIVE(odh);
1530
2014-04-21
pjp
else
1531
2014-04-21
pjp
SET_DNS_RECURSION_AVAIL(odh);
1532
2014-04-21
pjp
1533
2014-04-21
pjp
HTONS(odh->query);
1534
2014-04-21
pjp
1535
2014-04-21
pjp
odh->question = htons(1);
1536
2014-04-21
pjp
odh->answer = htons(1);
1537
2014-04-21
pjp
odh->nsrr = 0;
1538
2014-04-21
pjp
odh->additional = 0;
1539
2014-04-21
pjp
1540
2014-04-21
pjp
answer = (struct answer *)(&reply[0] + sizeof(struct dns_header) +
1541
2014-04-21
pjp
q->hdr->namelen + 4);
1542
2014-04-21
pjp
1543
2014-04-21
pjp
answer->name[0] = 0xc0;
1544
2014-04-21
pjp
answer->name[1] = 0x0c;
1545
2014-04-21
pjp
answer->type = q->hdr->qtype;
1546
2014-04-21
pjp
answer->class = q->hdr->qclass;
1547
2014-04-21
pjp
if (sreply->sr != NULL)
1548
2014-04-21
pjp
answer->ttl = htonl(sd->ttl - (time(NULL) - sd->created));
1549
2014-04-21
pjp
else
1550
2014-04-21
pjp
answer->ttl = htonl(sd->ttl);
1551
2014-04-21
pjp
1552
2014-04-21
pjp
outlen += 12; /* up to rdata length */
1553
2014-04-21
pjp
1554
2014-04-21
pjp
p = (char *)&answer->rdata;
1555
2014-04-21
pjp
1556
2014-04-21
pjp
*p = sd->spflen;
1557
2014-04-21
pjp
memcpy((p + 1), sd->spf, sd->spflen);
1558
2014-04-21
pjp
outlen += (sd->spflen + 1);
1559
2014-04-21
pjp
1560
2014-04-21
pjp
answer->rdlength = htons(sd->spflen + 1);
1561
2014-04-21
pjp
1562
2014-05-10
pjp
if (q->edns0len) {
1563
2014-05-10
pjp
/* tag on edns0 opt record */
1564
2014-05-10
pjp
NTOHS(odh->additional);
1565
2014-05-10
pjp
odh->additional++;
1566
2014-05-10
pjp
HTONS(odh->additional);
1567
2014-05-10
pjp
1568
2014-05-10
pjp
outlen = additional_opt(q, reply, replysize, outlen);
1569
2014-05-10
pjp
}
1570
2014-05-10
pjp
1571
2014-04-21
pjp
if (sreply->sr != NULL) {
1572
2014-10-08
pjp
retlen = reply_raw2(so, reply, outlen, sreply->sr);
1573
2014-04-21
pjp
} else {
1574
2014-04-21
pjp
if (istcp) {
1575
2014-04-21
pjp
char *tmpbuf;
1576
2014-04-21
pjp
u_int16_t *plen;
1577
2014-04-21
pjp
1578
2014-04-21
pjp
tmpbuf = malloc(outlen + 2);
1579
2014-04-21
pjp
if (tmpbuf == NULL) {
1580
2014-04-21
pjp
dolog(LOG_INFO, "malloc: %s\n", strerror(errno));
1581
2014-04-21
pjp
}
1582
2014-04-21
pjp
plen = (u_int16_t *)tmpbuf;
1583
2014-04-21
pjp
*plen = htons(outlen);
1584
2014-04-21
pjp
1585
2014-04-21
pjp
memcpy(&tmpbuf[2], reply, outlen);
1586
2014-04-21
pjp
1587
2014-10-08
pjp
if ((retlen = send(so, tmpbuf, outlen + 2, 0)) < 0) {
1588
2014-04-21
pjp
dolog(LOG_INFO, "send: %s\n", strerror(errno));
1589
2014-04-21
pjp
}
1590
2014-04-21
pjp
free(tmpbuf);
1591
2014-04-21
pjp
} else {
1592
2014-10-08
pjp
if ((retlen = sendto(so, reply, outlen, 0, sa, salen)) < 0) {
1593
2014-04-21
pjp
dolog(LOG_INFO, "sendto: %s\n", strerror(errno));
1594
2014-04-21
pjp
}
1595
2014-04-21
pjp
}
1596
2014-04-21
pjp
}
1597
2014-04-21
pjp
1598
2014-10-08
pjp
return (retlen);
1599
2014-04-21
pjp
}
1600
2014-04-21
pjp
1601
2014-04-21
pjp
/*
1602
2010-03-27
pbug
* REPLY_TXT() - replies a DNS question (*q) on socket (so)
1603
2010-03-27
pbug
*
1604
2010-03-27
pbug
*/
1605
2010-03-27
pbug
1606
2010-03-27
pbug
1607
2014-10-08
pjp
int
1608
2010-03-27
pbug
reply_txt(struct sreply *sreply)
1609
2010-03-27
pbug
{
1610
2014-04-21
pjp
char *reply = sreply->replybuf;
1611
2010-03-27
pbug
struct dns_header *odh;
1612
2010-04-15
pbug
u_int16_t outlen;
1613
2010-03-27
pbug
char *p;
1614
2010-03-27
pbug
1615
2010-03-27
pbug
struct answer {
1616
2010-03-27
pbug
char name[2];
1617
2010-03-27
pbug
u_int16_t type;
1618
2010-03-27
pbug
u_int16_t class;
1619
2010-03-27
pbug
u_int32_t ttl;
1620
2010-03-27
pbug
u_int16_t rdlength; /* 12 */
1621
2010-03-27
pbug
char rdata;
1622
2010-03-27
pbug
} __attribute__((packed));
1623
2010-03-27
pbug
1624
2010-03-27
pbug
struct answer *answer;
1625
2010-03-27
pbug
1626
2010-03-27
pbug
int so = sreply->so;
1627
2010-03-27
pbug
char *buf = sreply->buf;
1628
2010-03-27
pbug
int len = sreply->len;
1629
2010-03-27
pbug
struct question *q = sreply->q;
1630
2010-03-27
pbug
struct sockaddr *sa = sreply->sa;
1631
2010-03-27
pbug
int salen = sreply->salen;
1632
2010-03-27
pbug
struct domain *sd = sreply->sd1;
1633
2010-03-27
pbug
int istcp = sreply->istcp;
1634
2014-04-21
pjp
int replysize = 512;
1635
2014-10-08
pjp
int retlen = -1;
1636
2014-04-21
pjp
1637
2014-04-21
pjp
if (istcp) {
1638
2014-04-21
pjp
replysize = 65535;
1639
2014-04-21
pjp
}
1640
2014-05-10
pjp
1641
2014-05-10
pjp
if (q->edns0len > 512)
1642
2014-05-10
pjp
replysize = q->edns0len;
1643
2010-03-27
pbug
1644
2010-03-27
pbug
/* st */
1645
2010-03-27
pbug
1646
2010-03-27
pbug
odh = (struct dns_header *)&reply[0];
1647
2010-03-27
pbug
outlen = sizeof(struct dns_header);
1648
2010-03-27
pbug
1649
2014-04-21
pjp
if (len > replysize) {
1650
2014-10-08
pjp
return (retlen);
1651
2010-03-27
pbug
}
1652
2010-03-27
pbug
1653
2010-03-27
pbug
/* copy question to reply */
1654
2014-04-21
pjp
memcpy(reply, buf, sizeof(struct dns_header) + q->hdr->namelen + 4);
1655
2010-03-27
pbug
/* blank query */
1656
2010-03-27
pbug
memset((char *)&odh->query, 0, sizeof(u_int16_t));
1657
2010-03-27
pbug
1658
2010-03-27
pbug
outlen += (q->hdr->namelen + 4);
1659
2010-03-27
pbug
1660
2010-03-27
pbug
SET_DNS_REPLY(odh);
1661
2010-09-26
pbug
if (sreply->sr == NULL)
1662
2010-09-26
pbug
SET_DNS_AUTHORITATIVE(odh);
1663
2010-09-26
pbug
else
1664
2010-09-26
pbug
SET_DNS_RECURSION_AVAIL(odh);
1665
2010-03-27
pbug
1666
2010-03-27
pbug
HTONS(odh->query);
1667
2010-03-27
pbug
1668
2010-03-27
pbug
odh->question = htons(1);
1669
2010-03-27
pbug
odh->answer = htons(1);
1670
2010-03-27
pbug
odh->nsrr = 0;
1671
2010-03-27
pbug
odh->additional = 0;
1672
2010-03-27
pbug
1673
2010-03-27
pbug
answer = (struct answer *)(&reply[0] + sizeof(struct dns_header) +
1674
2010-03-27
pbug
q->hdr->namelen + 4);
1675
2010-03-27
pbug
1676
2010-03-27
pbug
answer->name[0] = 0xc0;
1677
2010-03-27
pbug
answer->name[1] = 0x0c;
1678
2010-03-27
pbug
answer->type = q->hdr->qtype;
1679
2010-03-27
pbug
answer->class = q->hdr->qclass;
1680
2010-09-26
pbug
if (sreply->sr != NULL)
1681
2010-09-26
pbug
answer->ttl = htonl(sd->ttl - (time(NULL) - sd->created));
1682
2010-09-26
pbug
else
1683
2010-09-26
pbug
answer->ttl = htonl(sd->ttl);
1684
2010-03-27
pbug
1685
2010-03-27
pbug
outlen += 12; /* up to rdata length */
1686
2010-03-27
pbug
1687
2010-03-27
pbug
p = (char *)&answer->rdata;
1688
2010-03-27
pbug
1689
2010-03-27
pbug
*p = sd->txtlen;
1690
2010-03-27
pbug
memcpy((p + 1), sd->txt, sd->txtlen);
1691
2010-03-27
pbug
outlen += (sd->txtlen + 1);
1692
2010-03-27
pbug
1693
2010-03-27
pbug
answer->rdlength = htons(sd->txtlen + 1);
1694
2010-03-27
pbug
1695
2014-05-10
pjp
if (q->edns0len) {
1696
2014-05-10
pjp
/* tag on edns0 opt record */
1697
2014-05-10
pjp
NTOHS(odh->additional);
1698
2014-05-10
pjp
odh->additional++;
1699
2014-05-10
pjp
HTONS(odh->additional);
1700
2014-05-10
pjp
1701
2014-05-10
pjp
outlen = additional_opt(q, reply, replysize, outlen);
1702
2014-05-10
pjp
}
1703
2014-05-10
pjp
1704
2010-09-26
pbug
if (sreply->sr != NULL) {
1705
2014-10-08
pjp
retlen = reply_raw2(so, reply, outlen, sreply->sr);
1706
2010-09-26
pbug
} else {
1707
2010-09-26
pbug
if (istcp) {
1708
2010-09-26
pbug
char *tmpbuf;
1709
2010-09-26
pbug
u_int16_t *plen;
1710
2010-09-26
pbug
1711
2010-09-26
pbug
tmpbuf = malloc(outlen + 2);
1712
2010-09-26
pbug
if (tmpbuf == NULL) {
1713
2013-02-16
pjp
dolog(LOG_INFO, "malloc: %s\n", strerror(errno));
1714
2010-09-26
pbug
}
1715
2010-09-26
pbug
plen = (u_int16_t *)tmpbuf;
1716
2010-09-26
pbug
*plen = htons(outlen);
1717
2010-09-26
pbug
1718
2010-09-26
pbug
memcpy(&tmpbuf[2], reply, outlen);
1719
2010-09-26
pbug
1720
2014-10-08
pjp
if ((retlen = send(so, tmpbuf, outlen + 2, 0)) < 0) {
1721
2013-02-16
pjp
dolog(LOG_INFO, "send: %s\n", strerror(errno));
1722
2010-09-26
pbug
}
1723
2010-09-26
pbug
free(tmpbuf);
1724
2010-09-26
pbug
} else {
1725
2014-10-08
pjp
if ((retlen = sendto(so, reply, outlen, 0, sa, salen)) < 0) {
1726
2013-02-16
pjp
dolog(LOG_INFO, "sendto: %s\n", strerror(errno));
1727
2010-09-26
pbug
}
1728
2010-09-26
pbug
}
1729
2010-09-26
pbug
}
1730
2010-09-26
pbug
1731
2014-10-08
pjp
return (retlen);
1732
2010-09-26
pbug
}
1733
2010-09-26
pbug
1734
2014-04-21
pjp
/*
1735
2014-04-21
pjp
* REPLY_SSHFP() - replies a DNS question (*q) on socket (so)
1736
2014-04-21
pjp
* (based on reply_srv)
1737
2014-04-21
pjp
*/
1738
2012-04-30
pbug
1739
2014-04-21
pjp
1740
2014-10-08
pjp
int
1741
2014-04-21
pjp
reply_sshfp(struct sreply *sreply)
1742
2014-04-21
pjp
{
1743
2014-04-21
pjp
char *reply = sreply->replybuf;
1744
2014-04-21
pjp
struct dns_header *odh;
1745
2014-04-21
pjp
int sshfp_count;
1746
2014-04-21
pjp
u_int16_t *plen;
1747
2014-04-21
pjp
u_int16_t outlen;
1748
2014-04-21
pjp
1749
2014-04-21
pjp
struct answer {
1750
2014-04-21
pjp
char name[2];
1751
2014-04-21
pjp
u_int16_t type;
1752
2014-04-21
pjp
u_int16_t class;
1753
2014-04-21
pjp
u_int32_t ttl;
1754
2014-04-21
pjp
u_int16_t rdlength; /* 12 */
1755
2014-04-21
pjp
u_int8_t sshfp_alg;
1756
2014-04-21
pjp
u_int8_t sshfp_type;
1757
2014-04-21
pjp
char target;
1758
2014-04-21
pjp
} __attribute__((packed));
1759
2014-04-21
pjp
1760
2014-04-21
pjp
struct answer *answer;
1761
2014-04-21
pjp
1762
2014-04-21
pjp
int so = sreply->so;
1763
2014-04-21
pjp
char *buf = sreply->buf;
1764
2014-04-21
pjp
int len = sreply->len;
1765
2014-04-21
pjp
struct question *q = sreply->q;
1766
2014-04-21
pjp
struct sockaddr *sa = sreply->sa;
1767
2014-04-21
pjp
int salen = sreply->salen;
1768
2014-04-21
pjp
struct domain *sd = sreply->sd1;
1769
2014-04-21
pjp
int istcp = sreply->istcp;
1770
2014-04-21
pjp
int typelen = 0;
1771
2014-04-21
pjp
int replysize = 512;
1772
2014-10-08
pjp
int retlen = -1;
1773
2014-04-21
pjp
1774
2014-04-21
pjp
if (istcp) {
1775
2014-04-21
pjp
replysize = 65535;
1776
2014-04-21
pjp
}
1777
2014-05-10
pjp
1778
2014-05-10
pjp
if (q->edns0len > 512)
1779
2014-05-10
pjp
replysize = q->edns0len;
1780
2014-04-21
pjp
1781
2014-04-21
pjp
1782
2014-04-21
pjp
odh = (struct dns_header *)&reply[0];
1783
2014-04-21
pjp
1784
2014-04-21
pjp
outlen = sizeof(struct dns_header);
1785
2014-04-21
pjp
1786
2014-04-21
pjp
if (len > replysize) {
1787
2014-10-08
pjp
return (retlen);
1788
2014-04-21
pjp
}
1789
2014-04-21
pjp
1790
2014-04-21
pjp
memcpy(reply, buf, sizeof(struct dns_header) + q->hdr->namelen + 4);
1791
2014-04-21
pjp
memset((char *)&odh->query, 0, sizeof(u_int16_t));
1792
2014-04-21
pjp
1793
2014-04-21
pjp
outlen += (q->hdr->namelen + 4);
1794
2014-04-21
pjp
1795
2014-04-21
pjp
SET_DNS_REPLY(odh);
1796
2014-04-21
pjp
1797
2014-04-21
pjp
if (sreply->sr == NULL) {
1798
2014-04-21
pjp
SET_DNS_AUTHORITATIVE(odh);
1799
2014-04-21
pjp
} else
1800
2014-04-21
pjp
SET_DNS_RECURSION_AVAIL(odh);
1801
2014-04-21
pjp
1802
2014-04-21
pjp
HTONS(odh->query);
1803
2014-04-21
pjp
1804
2014-04-21
pjp
odh->question = htons(1);
1805
2014-04-21
pjp
odh->answer = htons(sd->sshfp_count);
1806
2014-04-21
pjp
odh->nsrr = 0;
1807
2014-04-21
pjp
odh->additional = 0;
1808
2014-04-21
pjp
1809
2014-04-21
pjp
/* skip dns header, question name, qtype and qclass */
1810
2014-04-21
pjp
answer = (struct answer *)(&reply[0] + sizeof(struct dns_header) +
1811
2014-04-21
pjp
q->hdr->namelen + 4);
1812
2014-04-21
pjp
1813
2014-04-21
pjp
sshfp_count = 0;
1814
2014-04-21
pjp
do {
1815
2014-04-21
pjp
answer->name[0] = 0xc0;
1816
2014-04-21
pjp
answer->name[1] = 0x0c;
1817
2014-04-21
pjp
answer->type = q->hdr->qtype;
1818
2014-04-21
pjp
answer->class = q->hdr->qclass;
1819
2014-04-21
pjp
if (sreply->sr != NULL)
1820
2014-04-21
pjp
answer->ttl = htonl(sd->ttl - (time(NULL) - sd->created));
1821
2014-04-21
pjp
else
1822
2014-04-21
pjp
answer->ttl = htonl(sd->ttl);
1823
2014-04-21
pjp
1824
2014-04-21
pjp
switch (sd->sshfp[sshfp_count].fptype) {
1825
2014-04-21
pjp
case 1:
1826
2014-04-21
pjp
typelen = DNS_SSHFP_SIZE_SHA1;
1827
2014-04-21
pjp
break;
1828
2014-04-21
pjp
case 2:
1829
2014-04-21
pjp
typelen = DNS_SSHFP_SIZE_SHA256;
1830
2014-04-21
pjp
break;
1831
2014-04-21
pjp
default:
1832
2014-04-21
pjp
dolog(LOG_ERR, "oops bad sshfp type? not returning a packet!\n");
1833
2014-10-08
pjp
return (retlen);
1834
2014-04-21
pjp
}
1835
2014-04-21
pjp
1836
2014-04-21
pjp
answer->rdlength = htons((2 * sizeof(u_int8_t)) + typelen);
1837
2014-04-21
pjp
answer->sshfp_alg = sd->sshfp[sshfp_count].algorithm;
1838
2014-04-21
pjp
answer->sshfp_type = sd->sshfp[sshfp_count].fptype;
1839
2014-04-21
pjp
1840
2014-04-21
pjp
memcpy((char *)&answer->target, (char *)sd->sshfp[sshfp_count].fingerprint, sd->sshfp[sshfp_count].fplen);
1841
2014-04-21
pjp
1842
2014-04-21
pjp
/* can we afford to write another header? if no truncate */
1843
2014-05-11
pjp
if (sd->sshfp_count > 1 && (outlen + 12 + 2 + sd->sshfp[sshfp_count].fplen) > replysize) {
1844
2014-04-21
pjp
NTOHS(odh->query);
1845
2014-04-21
pjp
SET_DNS_TRUNCATION(odh);
1846
2014-04-21
pjp
HTONS(odh->query);
1847
2014-04-21
pjp
goto out;
1848
2014-04-21
pjp
}
1849
2014-04-21
pjp
1850
2014-04-21
pjp
/* set new offset for answer */
1851
2014-04-21
pjp
outlen += (12 + 2 + sd->sshfp[sshfp_count].fplen);
1852
2014-04-21
pjp
answer = (struct answer *)&reply[outlen];
1853
2014-04-21
pjp
} while (++sshfp_count < RECORD_COUNT && --sd->sshfp_count);
1854
2014-04-21
pjp
1855
2014-05-10
pjp
if (q->edns0len) {
1856
2014-05-10
pjp
/* tag on edns0 opt record */
1857
2014-05-10
pjp
NTOHS(odh->additional);
1858
2014-05-10
pjp
odh->additional++;
1859
2014-05-10
pjp
HTONS(odh->additional);
1860
2014-05-10
pjp
1861
2014-05-10
pjp
outlen = additional_opt(q, reply, replysize, outlen);
1862
2014-05-10
pjp
}
1863
2014-05-10
pjp
1864
2014-04-21
pjp
out:
1865
2014-04-21
pjp
if (sreply->sr != NULL) {
1866
2014-10-08
pjp
retlen = reply_raw2(so, reply, outlen, sreply->sr);
1867
2014-04-21
pjp
} else {
1868
2014-04-21
pjp
if (istcp) {
1869
2014-04-21
pjp
char *tmpbuf;
1870
2014-04-21
pjp
1871
2014-04-21
pjp
tmpbuf = malloc(outlen + 2);
1872
2014-04-21
pjp
if (tmpbuf == NULL) {
1873
2014-04-21
pjp
dolog(LOG_INFO, "malloc: %s\n", strerror(errno));
1874
2014-04-21
pjp
}
1875
2014-04-21
pjp
plen = (u_int16_t *)tmpbuf;
1876
2014-04-21
pjp
*plen = htons(outlen);
1877
2014-04-21
pjp
1878
2014-04-21
pjp
memcpy(&tmpbuf[2], reply, outlen);
1879
2014-10-08
pjp
if ((retlen = send(so, tmpbuf, outlen + 2, 0)) < 0) {
1880
2014-04-21
pjp
dolog(LOG_INFO, "send: %s\n", strerror(errno));
1881
2014-04-21
pjp
}
1882
2014-04-21
pjp
free(tmpbuf);
1883
2014-04-21
pjp
} else {
1884
2014-10-08
pjp
if ((retlen = sendto(so, reply, outlen, 0, sa, salen)) < 0) {
1885
2014-04-21
pjp
dolog(LOG_INFO, "sendto: %s\n", strerror(errno));
1886
2014-04-21
pjp
}
1887
2014-04-21
pjp
}
1888
2014-04-21
pjp
}
1889
2014-04-21
pjp
1890
2014-10-08
pjp
return (retlen);
1891
2014-04-21
pjp
}
1892
2014-04-21
pjp
1893
2014-04-21
pjp
1894
2012-04-30
pbug
/*
1895
2014-05-11
pjp
* REPLY_NAPTR() - replies a DNS question (*q) on socket (so)
1896
2014-05-11
pjp
* (based on reply_srv)
1897
2014-05-11
pjp
*/
1898
2014-05-11
pjp
1899
2014-05-11
pjp
1900
2014-10-08
pjp
int
1901
2014-05-11
pjp
reply_naptr(struct sreply *sreply, DB *db)
1902
2014-05-11
pjp
{
1903
2014-05-11
pjp
char *reply = sreply->replybuf;
1904
2014-05-11
pjp
struct dns_header *odh;
1905
2014-05-11
pjp
struct domain *sd0;
1906
2014-05-11
pjp
int naptr_count;
1907
2014-05-11
pjp
u_int16_t *plen;
1908
2014-05-11
pjp
char *name;
1909
2014-05-11
pjp
u_int16_t outlen;
1910
2014-05-11
pjp
u_int16_t namelen;
1911
2014-05-11
pjp
int additional = 0;
1912
2014-05-11
pjp
1913
2014-05-11
pjp
struct answer {
1914
2014-05-11
pjp
char name[2];
1915
2014-05-11
pjp
u_int16_t type;
1916
2014-05-11
pjp
u_int16_t class;
1917
2014-05-11
pjp
u_int32_t ttl;
1918
2014-05-11
pjp
u_int16_t rdlength; /* 12 */
1919
2014-05-11
pjp
u_int16_t naptr_order;
1920
2014-05-11
pjp
u_int16_t naptr_preference;
1921
2014-05-11
pjp
char rest;
1922
2014-05-11
pjp
} __attribute__((packed));
1923
2014-05-11
pjp
1924
2014-05-11
pjp
struct answer *answer;
1925
2014-05-11
pjp
1926
2014-05-11
pjp
int so = sreply->so;
1927
2014-05-11
pjp
char *buf = sreply->buf;
1928
2014-05-11
pjp
int len = sreply->len;
1929
2014-05-11
pjp
struct question *q = sreply->q;
1930
2014-05-11
pjp
struct sockaddr *sa = sreply->sa;
1931
2014-05-11
pjp
int salen = sreply->salen;
1932
2014-05-11
pjp
struct domain *sd = sreply->sd1;
1933
2014-05-11
pjp
int istcp = sreply->istcp;
1934
2014-05-11
pjp
int wildcard = sreply->wildcard;
1935
2014-05-11
pjp
int replysize = 512;
1936
2014-05-11
pjp
int tmplen, savelen;
1937
2014-05-11
pjp
char *p;
1938
2014-10-08
pjp
int retlen = -1;
1939
2014-05-11
pjp
1940
2014-05-11
pjp
if (istcp) {
1941
2014-05-11
pjp
replysize = 65535;
1942
2014-05-11
pjp
}
1943
2014-05-11
pjp
1944
2014-05-11
pjp
if (q->edns0len > 512)
1945
2014-05-11
pjp
replysize = q->edns0len;
1946
2014-05-11
pjp
1947
2014-05-11
pjp
odh = (struct dns_header *)&reply[0];
1948
2014-05-11
pjp
1949
2014-05-11
pjp
outlen = sizeof(struct dns_header);
1950
2014-05-11
pjp
1951
2014-05-11
pjp
if (len > replysize) {
1952
2014-10-08
pjp
return (retlen);
1953
2014-05-11
pjp
}
1954
2014-05-11
pjp
1955
2014-05-11
pjp
memcpy(reply, buf, sizeof(struct dns_header) + q->hdr->namelen + 4);
1956
2014-05-11
pjp
memset((char *)&odh->query, 0, sizeof(u_int16_t));
1957
2014-05-11
pjp
1958
2014-05-11
pjp
outlen += (q->hdr->namelen + 4);
1959
2014-05-11
pjp
1960
2014-05-11
pjp
SET_DNS_REPLY(odh);
1961
2014-05-11
pjp
1962
2014-05-11
pjp
if (sreply->sr == NULL) {
1963
2014-05-11
pjp
SET_DNS_AUTHORITATIVE(odh);
1964
2014-05-11
pjp
} else
1965
2014-05-11
pjp
SET_DNS_RECURSION_AVAIL(odh);
1966
2014-05-11
pjp
1967
2014-05-11
pjp
HTONS(odh->query);
1968
2014-05-11
pjp
1969
2014-05-11
pjp
odh->question = htons(1);
1970
2014-05-11
pjp
odh->answer = htons(sd->naptr_count);
1971
2014-05-11
pjp
odh->nsrr = 0;
1972
2014-05-11
pjp
odh->additional = 0;
1973
2014-05-11
pjp
1974
2014-05-11
pjp
/* skip dns header, question name, qtype and qclass */
1975
2014-05-11
pjp
answer = (struct answer *)(&reply[0] + sizeof(struct dns_header) +
1976
2014-05-11
pjp
q->hdr->namelen + 4);
1977
2014-05-11
pjp
1978
2014-05-11
pjp
naptr_count = 0;
1979
2014-05-11
pjp
do {
1980
2014-05-11
pjp
savelen = outlen;
1981
2014-05-11
pjp
answer->name[0] = 0xc0;
1982
2014-05-11
pjp
answer->name[1] = 0x0c;
1983
2014-05-11
pjp
answer->type = q->hdr->qtype;
1984
2014-05-11
pjp
answer->class = q->hdr->qclass;
1985
2014-05-11
pjp
if (sreply->sr != NULL)
1986
2014-05-11
pjp
answer->ttl = htonl(sd->ttl - (time(NULL) - sd->created));
1987
2014-05-11
pjp
else
1988
2014-05-11
pjp
answer->ttl = htonl(sd->ttl);
1989
2014-05-11
pjp
1990
2014-05-11
pjp
answer->naptr_order = htons(sd->naptr[naptr_count].order);
1991
2014-05-11
pjp
answer->naptr_preference = htons(sd->naptr[naptr_count].preference);
1992
2014-05-11
pjp
1993
2014-05-11
pjp
p = (char *)&answer->rest;
1994
2014-05-11
pjp
1995
2014-05-11
pjp
*p = sd->naptr[naptr_count].flagslen;
1996
2014-05-11
pjp
memcpy((p + 1), sd->naptr[naptr_count].flags, sd->naptr[naptr_count].flagslen);
1997
2014-05-11
pjp
p += (sd->naptr[naptr_count].flagslen + 1);
1998
2014-05-11
pjp
outlen += (1 + sd->naptr[naptr_count].flagslen);
1999
2014-05-11
pjp
2000
2014-05-11
pjp
/* services */
2001
2014-05-11
pjp
*p = sd->naptr[naptr_count].serviceslen;
2002
2014-05-11
pjp
memcpy((p + 1), sd->naptr[naptr_count].services, sd->naptr[naptr_count].serviceslen);
2003
2014-05-11
pjp
p += (sd->naptr[naptr_count].serviceslen + 1);
2004
2014-05-11
pjp
outlen += (1 + sd->naptr[naptr_count].serviceslen);
2005
2014-05-11
pjp
2006
2014-05-11
pjp
/* regexp */
2007
2014-05-11
pjp
*p = sd->naptr[naptr_count].regexplen;
2008
2014-05-11
pjp
memcpy((p + 1), sd->naptr[naptr_count].regexp, sd->naptr[naptr_count].regexplen);
2009
2014-05-11
pjp
p += (sd->naptr[naptr_count].regexplen + 1);
2010
2014-05-11
pjp
outlen += (1 + sd->naptr[naptr_count].regexplen);
2011
2014-05-11
pjp
2012
2014-05-11
pjp
/* replacement */
2013
2014-05-11
pjp
2014
2014-05-11
pjp
memcpy((char *)p, (char *)sd->naptr[naptr_count].replacement, sd->naptr[naptr_count].replacementlen);
2015
2014-05-11
pjp
2016
2014-05-11
pjp
name = sd->naptr[naptr_count].replacement;
2017
2014-05-11
pjp
namelen = sd->naptr[naptr_count].replacementlen;
2018
2014-05-11
pjp
2019
2014-05-11
pjp
outlen += (12 + 4 + sd->naptr[naptr_count].replacementlen);
2020
2014-05-11
pjp
2021
2014-05-11
pjp
/* compress the label if possible */
2022
2014-05-11
pjp
if ((tmplen = compress_label((u_char*)reply, outlen, namelen)) > 0) {
2023
2014-05-11
pjp
outlen = tmplen;
2024
2014-05-11
pjp
}
2025
2014-05-11
pjp
2026
2014-05-11
pjp
answer->rdlength = htons(outlen - (savelen + 12));
2027
2014-05-11
pjp
2028
2014-05-11
pjp
2029
2014-05-11
pjp
sd0 = Lookup_zone(db, name, namelen, htons(DNS_TYPE_A), wildcard);
2030
2014-05-11
pjp
if (sd0 != NULL) {
2031
2014-05-11
pjp
cn1 = malloc(sizeof(struct collects));
2032
2014-05-11
pjp
if (cn1 != NULL) {
2033
2014-05-11
pjp
cn1->name = malloc(namelen);
2034
2014-05-11
pjp
if (cn1->name != NULL) {
2035
2014-05-11
pjp
memcpy(cn1->name, name, namelen);
2036
2014-05-11
pjp
cn1->namelen = namelen;
2037
2014-05-11
pjp
cn1->sd = sd0;
2038
2014-05-11
pjp
cn1->type = DNS_TYPE_A;
2039
2014-05-11
pjp
2040
2014-05-11
pjp
SLIST_INSERT_HEAD(&collectshead, cn1, collect_entry);
2041
2014-05-11
pjp
}
2042
2014-05-11
pjp
}
2043
2014-05-11
pjp
}
2044
2014-05-11
pjp
sd0 = Lookup_zone(db, name, namelen, htons(DNS_TYPE_AAAA), wildcard);
2045
2014-05-11
pjp
if (sd0 != NULL) {
2046
2014-05-11
pjp
cn1 = malloc(sizeof(struct collects));
2047
2014-05-11
pjp
if (cn1 != NULL) {
2048
2014-05-11
pjp
cn1->name = malloc(namelen);
2049
2014-05-11
pjp
if (cn1->name != NULL) {
2050
2014-05-11
pjp
memcpy(cn1->name, name, namelen);
2051
2014-05-11
pjp
cn1->namelen = namelen;
2052
2014-05-11
pjp
cn1->sd = sd0;
2053
2014-05-11
pjp
cn1->type = DNS_TYPE_AAAA;
2054
2014-05-11
pjp
2055
2014-05-11
pjp
SLIST_INSERT_HEAD(&collectshead, cn1, collect_entry);
2056
2014-05-11
pjp
}
2057
2014-05-11
pjp
}
2058
2014-05-11
pjp
}
2059
2014-05-11
pjp
2060
2014-05-11
pjp
2061
2014-05-11
pjp
/* can we afford to write another header? if no truncate */
2062
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
2014-05-11
pjp
NTOHS(odh->query);
2064
2014-05-11
pjp
SET_DNS_TRUNCATION(odh);
2065
2014-05-11
pjp
HTONS(odh->query);
2066
2014-05-11
pjp
goto out;
2067
2014-05-11
pjp
}
2068
2014-05-11
pjp
2069
2014-05-11
pjp
/* set new offset for answer */
2070
2014-05-11
pjp
answer = (struct answer *)&reply[outlen];
2071
2014-05-11
pjp
} while (++naptr_count < RECORD_COUNT && --sd->naptr_count);
2072
2014-05-11
pjp
2073
2014-05-11
pjp
/* write additional */
2074
2014-05-11
pjp
2075
2014-05-11
pjp
SLIST_FOREACH(cnp, &collectshead, collect_entry) {
2076
2014-05-11
pjp
int addcount;
2077
2014-05-11
pjp
int tmplen;
2078
2014-05-11
pjp
2079
2014-05-11
pjp
switch (cnp->type) {
2080
2014-05-11
pjp
case DNS_TYPE_A:
2081
2014-05-11
pjp
tmplen = additional_a(cnp->name, cnp->namelen, cnp->sd, reply, replysize, outlen, &addcount);
2082
2014-05-11
pjp
additional += addcount;
2083
2014-05-11
pjp
break;
2084
2014-05-11
pjp
case DNS_TYPE_AAAA:
2085
2014-05-11
pjp
tmplen = additional_aaaa(cnp->name, cnp->namelen, cnp->sd, reply, replysize, outlen, &addcount);
2086
2014-05-11
pjp
additional += addcount;
2087
2014-05-11
pjp
break;
2088
2014-05-11
pjp
}
2089
2014-05-11
pjp
2090
2014-05-11
pjp
if (tmplen > 0) {
2091
2014-05-11
pjp
outlen = tmplen;
2092
2014-05-11
pjp
}
2093
2014-05-11
pjp
}
2094
2014-05-11
pjp
2095
2014-05-11
pjp
odh->additional = htons(additional);
2096
2014-05-11
pjp
2097
2014-05-11
pjp
while (!SLIST_EMPTY(&collectshead)) {
2098
2014-05-11
pjp
cn1 = SLIST_FIRST(&collectshead);
2099
2014-05-11
pjp
SLIST_REMOVE_HEAD(&collectshead, collect_entry);
2100
2014-05-11
pjp
free(cn1->name);
2101
2014-05-11
pjp
free(cn1->sd);
2102
2014-05-11
pjp
free(cn1);
2103
2014-05-11
pjp
}
2104
2014-05-11
pjp
2105
2014-05-11
pjp
if (q->edns0len) {
2106
2014-05-11
pjp
/* tag on edns0 opt record */
2107
2014-05-11
pjp
NTOHS(odh->additional);
2108
2014-05-11
pjp
odh->additional++;
2109
2014-05-11
pjp
HTONS(odh->additional);
2110
2014-05-11
pjp
2111
2014-05-11
pjp
outlen = additional_opt(q, reply, replysize, outlen);
2112
2014-05-11
pjp
}
2113
2014-05-11
pjp
2114
2014-05-11
pjp
out:
2115
2014-05-11
pjp
if (sreply->sr != NULL) {
2116
2014-10-08
pjp
retlen = reply_raw2(so, reply, outlen, sreply->sr);
2117
2014-05-11
pjp
} else {
2118
2014-05-11
pjp
if (istcp) {
2119
2014-05-11
pjp
char *tmpbuf;
2120
2014-05-11
pjp
2121
2014-05-11
pjp
tmpbuf = malloc(outlen + 2);
2122
2014-05-11
pjp
if (tmpbuf == NULL) {
2123
2014-05-11
pjp
dolog(LOG_INFO, "malloc: %s\n", strerror(errno));
2124
2014-05-11
pjp
}
2125
2014-05-11
pjp
plen = (u_int16_t *)tmpbuf;
2126
2014-05-11
pjp
*plen = htons(outlen);
2127
2014-05-11
pjp
2128
2014-05-11
pjp
memcpy(&tmpbuf[2], reply, outlen);
2129
2014-10-08
pjp
if ((retlen = send(so, tmpbuf, outlen + 2, 0)) < 0) {
2130
2014-05-11
pjp
dolog(LOG_INFO, "send: %s\n", strerror(errno));
2131
2014-05-11
pjp
}
2132
2014-05-11
pjp
free(tmpbuf);
2133
2014-05-11
pjp
} else {
2134
2014-10-08
pjp
if ((retlen = sendto(so, reply, outlen, 0, sa, salen)) < 0) {
2135
2014-05-11
pjp
dolog(LOG_INFO, "sendto: %s\n", strerror(errno));
2136
2014-05-11
pjp
}
2137
2014-05-11
pjp
}
2138
2014-05-11
pjp
}
2139
2014-05-11
pjp
2140
2014-10-08
pjp
return (retlen);
2141
2014-05-11
pjp
}
2142
2014-05-11
pjp
2143
2014-05-11
pjp
2144
2014-05-11
pjp
/*
2145
2012-04-30
pbug
* REPLY_SRV() - replies a DNS question (*q) on socket (so)
2146
2012-04-30
pbug
* (based on reply_mx)
2147
2012-04-30
pbug
*/
2148
2012-04-30
pbug
2149
2012-04-30
pbug
2150
2014-10-08
pjp
int
2151
2012-04-30
pbug
reply_srv(struct sreply *sreply, DB *db)
2152
2012-04-30
pbug
{
2153
2014-04-21
pjp
char *reply = sreply->replybuf;
2154
2012-04-30
pbug
struct dns_header *odh;
2155
2012-04-30
pbug
struct domain *sd0;
2156
2012-04-30
pbug
int srv_count;
2157
2012-04-30
pbug
u_int16_t *plen;
2158
2012-04-30
pbug
char *name;
2159
2012-04-30
pbug
u_int16_t outlen;
2160
2012-04-30
pbug
u_int16_t namelen;
2161
2012-04-30
pbug
int additional = 0;
2162
2012-04-30
pbug
2163
2012-04-30
pbug
struct answer {
2164
2012-04-30
pbug
char name[2];
2165
2012-04-30
pbug
u_int16_t type;
2166
2012-04-30
pbug
u_int16_t class;
2167
2012-04-30
pbug
u_int32_t ttl;
2168
2012-04-30
pbug
u_int16_t rdlength; /* 12 */
2169
2012-04-30
pbug
u_int16_t srv_priority;
2170
2012-04-30
pbug
u_int16_t srv_weight;
2171
2012-04-30
pbug
u_int16_t srv_port;
2172
2012-04-30
pbug
char target;
2173
2012-04-30
pbug
} __attribute__((packed));
2174
2012-04-30
pbug
2175
2012-04-30
pbug
struct answer *answer;
2176
2012-04-30
pbug
2177
2012-04-30
pbug
int so = sreply->so;
2178
2012-04-30
pbug
char *buf = sreply->buf;
2179
2012-04-30
pbug
int len = sreply->len;
2180
2012-04-30
pbug
struct question *q = sreply->q;
2181
2012-04-30
pbug
struct sockaddr *sa = sreply->sa;
2182
2012-04-30
pbug
int salen = sreply->salen;
2183
2012-04-30
pbug
struct domain *sd = sreply->sd1;
2184
2012-04-30
pbug
int istcp = sreply->istcp;
2185
2012-04-30
pbug
int wildcard = sreply->wildcard;
2186
2014-04-21
pjp
int replysize = 512;
2187
2014-10-08
pjp
int retlen = -1;
2188
2014-04-21
pjp
2189
2014-04-21
pjp
if (istcp) {
2190
2014-04-21
pjp
replysize = 65535;
2191
2014-04-21
pjp
}
2192
2012-04-30
pbug
2193
2014-05-10
pjp
if (q->edns0len > 512)
2194
2014-05-10
pjp
replysize = q->edns0len;
2195
2012-04-30
pbug
2196
2012-04-30
pbug
odh = (struct dns_header *)&reply[0];
2197
2012-04-30
pbug
2198
2012-04-30
pbug
outlen = sizeof(struct dns_header);
2199
2012-04-30
pbug
2200
2014-04-21
pjp
if (len > replysize) {
2201
2014-10-08
pjp
return (retlen);
2202
2012-04-30
pbug
}
2203
2012-04-30
pbug
2204
2014-04-21
pjp
memcpy(reply, buf, sizeof(struct dns_header) + q->hdr->namelen + 4);
2205
2012-04-30
pbug
memset((char *)&odh->query, 0, sizeof(u_int16_t));
2206
2012-04-30
pbug
2207
2012-04-30
pbug
outlen += (q->hdr->namelen + 4);
2208
2012-04-30
pbug
2209
2012-04-30
pbug
SET_DNS_REPLY(odh);
2210
2012-04-30
pbug
2211
2012-04-30
pbug
if (sreply->sr == NULL) {
2212
2012-04-30
pbug
SET_DNS_AUTHORITATIVE(odh);
2213
2012-04-30
pbug
} else
2214
2012-04-30
pbug
SET_DNS_RECURSION_AVAIL(odh);
2215
2012-04-30
pbug
2216
2012-04-30
pbug
HTONS(odh->query);
2217
2012-04-30
pbug
2218
2012-04-30
pbug
odh->question = htons(1);
2219
2012-04-30
pbug
odh->answer = htons(sd->srv_count);
2220
2012-04-30
pbug
odh->nsrr = 0;
2221
2012-04-30
pbug
odh->additional = 0;
2222
2012-04-30
pbug
2223
2012-04-30
pbug
/* skip dns header, question name, qtype and qclass */
2224
2012-04-30
pbug
answer = (struct answer *)(&reply[0] + sizeof(struct dns_header) +
2225
2012-04-30
pbug
q->hdr->namelen + 4);
2226
2012-04-30
pbug
2227
2012-04-30
pbug
srv_count = 0;
2228
2012-04-30
pbug
do {
2229
2012-04-30
pbug
answer->name[0] = 0xc0;
2230
2012-04-30
pbug
answer->name[1] = 0x0c;
2231
2012-04-30
pbug
answer->type = q->hdr->qtype;
2232
2012-04-30
pbug
answer->class = q->hdr->qclass;
2233
2012-04-30
pbug
if (sreply->sr != NULL)
2234
2012-04-30
pbug
answer->ttl = htonl(sd->ttl - (time(NULL) - sd->created));
2235
2012-04-30
pbug
else
2236
2012-04-30
pbug
answer->ttl = htonl(sd->ttl);
2237
2012-04-30
pbug
2238
2012-04-30
pbug
answer->rdlength = htons((3 * sizeof(u_int16_t)) + sd->srv[srv_count].targetlen);
2239
2012-04-30
pbug
2240
2012-04-30
pbug
answer->srv_priority = htons(sd->srv[srv_count].priority);
2241
2012-04-30
pbug
answer->srv_weight = htons(sd->srv[srv_count].weight);
2242
2012-04-30
pbug
answer->srv_port = htons(sd->srv[srv_count].port);
2243
2012-04-30
pbug
2244
2012-04-30
pbug
memcpy((char *)&answer->target, (char *)sd->srv[srv_count].target, sd->srv[srv_count].targetlen);
2245
2012-04-30
pbug
2246
2012-04-30
pbug
name = sd->srv[srv_count].target;
2247
2012-04-30
pbug
namelen = sd->srv[srv_count].targetlen;
2248
2012-04-30
pbug
2249
2012-04-30
pbug
sd0 = Lookup_zone(db, name, namelen, htons(DNS_TYPE_A), wildcard);
2250
2012-04-30
pbug
if (sd0 != NULL) {
2251
2012-04-30
pbug
cn1 = malloc(sizeof(struct collects));
2252
2012-04-30
pbug
if (cn1 != NULL) {
2253
2012-04-30
pbug
cn1->name = malloc(namelen);
2254
2012-04-30
pbug
if (cn1->name != NULL) {
2255
2012-04-30
pbug
memcpy(cn1->name, name, namelen);
2256
2012-04-30
pbug
cn1->namelen = namelen;
2257
2012-04-30
pbug
cn1->sd = sd0;
2258
2012-04-30
pbug
cn1->type = DNS_TYPE_A;
2259
2012-04-30
pbug
2260
2014-05-01
pjp
SLIST_INSERT_HEAD(&collectshead, cn1, collect_entry);
2261
2012-04-30
pbug
}
2262
2012-04-30
pbug
}
2263
2012-04-30
pbug
}
2264
2012-04-30
pbug
sd0 = Lookup_zone(db, name, namelen, htons(DNS_TYPE_AAAA), wildcard);
2265
2012-04-30
pbug
if (sd0 != NULL) {
2266
2012-04-30
pbug
cn1 = malloc(sizeof(struct collects));
2267
2012-04-30
pbug
if (cn1 != NULL) {
2268
2012-04-30
pbug
cn1->name = malloc(namelen);
2269
2012-04-30
pbug
if (cn1->name != NULL) {
2270
2012-04-30
pbug
memcpy(cn1->name, name, namelen);
2271
2012-04-30
pbug
cn1->namelen = namelen;
2272
2012-04-30
pbug
cn1->sd = sd0;
2273
2012-04-30
pbug
cn1->type = DNS_TYPE_AAAA;
2274
2012-04-30
pbug
2275
2014-05-01
pjp
SLIST_INSERT_HEAD(&collectshead, cn1, collect_entry);
2276
2012-04-30
pbug
}
2277
2012-04-30
pbug
}
2278
2012-04-30
pbug
}
2279
2012-04-30
pbug
2280
2012-04-30
pbug
outlen += (12 + 6 + sd->srv[srv_count].targetlen);
2281
2012-04-30
pbug
2282
2012-04-30
pbug
/* can we afford to write another header? if no truncate */
2283
2014-05-11
pjp
if (sd->srv_count > 1 && (outlen + 12 + 6 + sd->srv[srv_count].targetlen) > replysize) {
2284
2012-04-30
pbug
NTOHS(odh->query);
2285
2012-04-30
pbug
SET_DNS_TRUNCATION(odh);
2286
2012-04-30
pbug
HTONS(odh->query);
2287
2012-04-30
pbug
goto out;
2288
2012-04-30
pbug
}
2289
2012-04-30
pbug
2290
2012-04-30
pbug
/* set new offset for answer */
2291
2012-04-30
pbug
answer = (struct answer *)&reply[outlen];
2292
2012-04-30
pbug
} while (++srv_count < RECORD_COUNT && --sd->srv_count);
2293
2012-04-30
pbug
2294
2012-04-30
pbug
/* write additional */
2295
2012-04-30
pbug
2296
2014-05-01
pjp
SLIST_FOREACH(cnp, &collectshead, collect_entry) {
2297
2012-04-30
pbug
int addcount;
2298
2012-04-30
pbug
int tmplen;
2299
2012-04-30
pbug
2300
2012-04-30
pbug
switch (cnp->type) {
2301
2012-04-30
pbug
case DNS_TYPE_A:
2302
2014-04-21
pjp
tmplen = additional_a(cnp->name, cnp->namelen, cnp->sd, reply, replysize, outlen, &addcount);
2303
2012-04-30
pbug
additional += addcount;
2304
2012-04-30
pbug
break;
2305
2012-04-30
pbug
case DNS_TYPE_AAAA:
2306
2014-04-21
pjp
tmplen = additional_aaaa(cnp->name, cnp->namelen, cnp->sd, reply, replysize, outlen, &addcount);
2307
2012-04-30
pbug
additional += addcount;
2308
2012-04-30
pbug
break;
2309
2012-04-30
pbug
}
2310
2012-04-30
pbug
2311
2012-04-30
pbug
if (tmplen > 0) {
2312
2012-04-30
pbug
outlen = tmplen;
2313
2012-04-30
pbug
}
2314
2012-04-30
pbug
}
2315
2012-04-30
pbug
2316
2012-04-30
pbug
odh->additional = htons(additional);
2317
2012-04-30
pbug
2318
2012-04-30
pbug
while (!SLIST_EMPTY(&collectshead)) {
2319
2012-04-30
pbug
cn1 = SLIST_FIRST(&collectshead);
2320
2014-05-01
pjp
SLIST_REMOVE_HEAD(&collectshead, collect_entry);
2321
2012-04-30
pbug
free(cn1->name);
2322
2012-04-30
pbug
free(cn1->sd);
2323
2012-04-30
pbug
free(cn1);
2324
2012-04-30
pbug
}
2325
2012-04-30
pbug
2326
2014-05-10
pjp
if (q->edns0len) {
2327
2014-05-10
pjp
/* tag on edns0 opt record */
2328
2014-05-10
pjp
NTOHS(odh->additional);
2329
2014-05-10
pjp
odh->additional++;
2330
2014-05-10
pjp
HTONS(odh->additional);
2331
2014-05-10
pjp
2332
2014-05-10
pjp
outlen = additional_opt(q, reply, replysize, outlen);
2333
2014-05-10
pjp
}
2334
2014-05-10
pjp
2335
2012-04-30
pbug
out:
2336
2012-04-30
pbug
if (sreply->sr != NULL) {
2337
2014-10-08
pjp
retlen = reply_raw2(so, reply, outlen, sreply->sr);
2338
2012-04-30
pbug
} else {
2339
2012-04-30
pbug
if (istcp) {
2340
2012-04-30
pbug
char *tmpbuf;
2341
2012-04-30
pbug
2342
2012-04-30
pbug
tmpbuf = malloc(outlen + 2);
2343
2012-04-30
pbug
if (tmpbuf == NULL) {
2344
2013-02-16
pjp
dolog(LOG_INFO, "malloc: %s\n", strerror(errno));
2345
2012-04-30
pbug
}
2346
2012-04-30
pbug
plen = (u_int16_t *)tmpbuf;
2347
2012-04-30
pbug
*plen = htons(outlen);
2348
2012-04-30
pbug
2349
2012-04-30
pbug
memcpy(&tmpbuf[2], reply, outlen);
2350
2014-10-08
pjp
if ((retlen = send(so, tmpbuf, outlen + 2, 0)) < 0) {
2351
2013-02-16
pjp
dolog(LOG_INFO, "send: %s\n", strerror(errno));
2352
2012-04-30
pbug
}
2353
2012-04-30
pbug
free(tmpbuf);
2354
2012-04-30
pbug
} else {
2355
2014-10-08
pjp
if ((retlen = sendto(so, reply, outlen, 0, sa, salen)) < 0) {
2356
2013-02-16
pjp
dolog(LOG_INFO, "sendto: %s\n", strerror(errno));
2357
2012-04-30
pbug
}
2358
2012-04-30
pbug
}
2359
2012-04-30
pbug
}
2360
2012-04-30
pbug
2361
2014-10-08
pjp
return (retlen);
2362
2012-04-30
pbug
}
2363
2012-04-30
pbug
2364
2012-04-30
pbug
2365
2005-11-29
pbug
/*
2366
2005-11-29
pbug
* REPLY_NOTIMPL - reply "Not Implemented"
2367
2005-11-29
pbug
*
2368
2005-11-29
pbug
*/
2369
2005-11-29
pbug
2370
2012-04-30
pbug
2371
2014-10-08
pjp
int
2372
2005-11-29
pbug
reply_notimpl(struct sreply *sreply)
2373
2005-11-29
pbug
{
2374
2014-04-21
pjp
char *reply = sreply->replybuf;
2375
2005-11-29
pbug
struct dns_header *odh;
2376
2010-04-15
pbug
u_int16_t outlen;
2377
2005-11-29
pbug
2378
2005-11-29
pbug
int so = sreply->so;
2379
2005-11-29
pbug
char *buf = sreply->buf;
2380
2005-11-29
pbug
int len = sreply->len;
2381
2005-11-29
pbug
struct sockaddr *sa = sreply->sa;
2382
2005-11-29
pbug
int salen = sreply->salen;
2383
2010-03-12
pbug
int istcp = sreply->istcp;
2384
2014-04-21
pjp
int replysize = 512;
2385
2014-10-08
pjp
int retlen = -1;
2386
2005-11-29
pbug
2387
2014-04-21
pjp
if (istcp) {
2388
2014-04-21
pjp
replysize = 65535;
2389
2014-04-21
pjp
}
2390
2014-04-21
pjp
2391
2005-11-29
pbug
#if 0
2392
2005-11-29
pbug
struct domain *sd = sreply->sd1;
2393
2005-11-29
pbug
struct question *q = sreply->q;
2394
2005-11-29
pbug
#endif
2395
2005-11-29
pbug
2396
2010-04-05
pbug
odh = (struct dns_header *)&reply[0];
2397
2010-03-12
pbug
2398
2005-11-29
pbug
outlen = sizeof(struct dns_header);
2399
2005-11-29
pbug
2400
2014-04-21
pjp
if (len > replysize) {
2401
2014-10-08
pjp
return (retlen);
2402
2005-11-29
pbug
}
2403
2005-11-29
pbug
2404
2014-04-21
pjp
memcpy(reply, buf, len);
2405
2010-03-12
pbug
2406
2005-11-29
pbug
memset((char *)&odh->query, 0, sizeof(u_int16_t));
2407
2005-11-29
pbug
2408
2005-11-29
pbug
SET_DNS_REPLY(odh);
2409
2005-11-29
pbug
SET_DNS_RCODE_NOTIMPL(odh);
2410
2005-11-29
pbug
2411
2005-11-29
pbug
HTONS(odh->query);
2412
2005-11-29
pbug
2413
2010-04-05
pbug
2414
2010-03-12
pbug
if (istcp) {
2415
2010-04-05
pbug
char *tmpbuf;
2416
2010-04-05
pbug
u_int16_t *plen;
2417
2010-04-05
pbug
2418
2010-04-05
pbug
tmpbuf = malloc(outlen + 2);
2419
2010-04-05
pbug
if (tmpbuf == NULL) {
2420
2013-02-16
pjp
dolog(LOG_INFO, "malloc: %s\n", strerror(errno));
2421
2010-03-12
pbug
}
2422
2010-04-05
pbug
plen = (u_int16_t *)tmpbuf;
2423
2010-04-05
pbug
*plen = htons(outlen);
2424
2010-04-05
pbug
2425
2010-04-05
pbug
memcpy(&tmpbuf[2], reply, outlen);
2426
2010-04-05
pbug
2427
2014-10-08
pjp
if ((retlen = send(so, tmpbuf, outlen + 2, 0)) < 0) {
2428
2013-02-16
pjp
dolog(LOG_INFO, "send: %s\n", strerror(errno));
2429
2010-04-05
pbug
}
2430
2010-04-05
pbug
free(tmpbuf);
2431
2010-03-12
pbug
} else {
2432
2014-10-08
pjp
if ((retlen = sendto(so, reply, len, 0, sa, salen)) < 0) {
2433
2013-02-16
pjp
dolog(LOG_INFO, "sendto: %s\n", strerror(errno));
2434
2010-03-12
pbug
}
2435
2005-11-29
pbug
}
2436
2005-11-29
pbug
2437
2014-10-08
pjp
return (retlen);
2438
2005-11-29
pbug
}
2439
2005-11-29
pbug
2440
2005-11-29
pbug
/*
2441
2005-11-29
pbug
* REPLY_NXDOMAIN() - replies a DNS question (*q) on socket (so)
2442
2005-11-29
pbug
*
2443
2005-11-29
pbug
*/
2444
2005-11-29
pbug
2445
2014-10-08
pjp
int
2446
2005-11-29
pbug
reply_nxdomain(struct sreply *sreply)
2447
2005-11-29
pbug
{
2448
2014-04-21
pjp
char *reply = sreply->replybuf;
2449
2005-11-29
pbug
struct dns_header *odh;
2450
2010-04-15
pbug
u_int16_t outlen;
2451
2008-07-24
pbug
char *p;
2452
2008-07-24
pbug
u_int32_t *soa_val;
2453
2008-07-24
pbug
int i, tmplen;
2454
2008-07-24
pbug
int labellen;
2455
2008-07-24
pbug
char *label, *plabel;
2456
2005-11-29
pbug
2457
2008-07-24
pbug
struct answer {
2458
2008-07-24
pbug
char name[2];
2459
2008-07-24
pbug
u_int16_t type;
2460
2008-07-24
pbug
u_int16_t class;
2461
2008-07-24
pbug
u_int32_t ttl;
2462
2008-07-24
pbug
u_int16_t rdlength; /* 12 */
2463
2008-07-24
pbug
char rdata;
2464
2008-07-24
pbug
} __attribute__((packed));
2465
2008-07-24
pbug
2466
2008-07-24
pbug
struct soa {
2467
2008-07-24
pbug
char *nsserver;
2468
2008-07-24
pbug
char *responsible_person;
2469
2008-07-24
pbug
u_int32_t serial;
2470
2008-07-24
pbug
u_int32_t refresh;
2471
2008-07-24
pbug
u_int32_t retry;
2472
2008-07-24
pbug
u_int32_t expire;
2473
2008-07-24
pbug
u_int32_t minttl;
2474
2008-07-24
pbug
};
2475
2008-07-24
pbug
2476
2008-07-24
pbug
2477
2008-07-24
pbug
struct answer *answer;
2478
2008-07-24
pbug
2479
2005-11-29
pbug
int so = sreply->so;
2480
2005-11-29
pbug
char *buf = sreply->buf;
2481
2005-11-29
pbug
int len = sreply->len;
2482
2008-07-24
pbug
struct question *q = sreply->q;
2483
2005-11-29
pbug
struct sockaddr *sa = sreply->sa;
2484
2005-11-29
pbug
int salen = sreply->salen;
2485
2008-07-24
pbug
struct domain *sd = sreply->sd1;
2486
2010-03-12
pbug
int istcp = sreply->istcp;
2487
2014-04-21
pjp
int replysize = 512;
2488
2014-10-08
pjp
int retlen = -1;
2489
2014-04-21
pjp
2490
2014-04-21
pjp
if (istcp) {
2491
2014-04-21
pjp
replysize = 65535;
2492
2014-04-21
pjp
}
2493
2008-07-24
pbug
2494
2008-07-24
pbug
odh = (struct dns_header *)&reply[0];
2495
2008-07-24
pbug
outlen = sizeof(struct dns_header);
2496
2008-07-24
pbug
2497
2014-04-21
pjp
if (len > replysize) {
2498
2014-10-08
pjp
return (retlen);
2499
2008-07-24
pbug
2500
2008-07-24
pbug
}
2501
2008-07-24
pbug
2502
2008-07-24
pbug
/*
2503
2008-07-24
pbug
* no SOA, use the old code
2504
2008-07-24
pbug
*/
2505
2008-07-24
pbug
2506
2008-07-24
pbug
if ((sd->flags & DOMAIN_HAVE_SOA) != DOMAIN_HAVE_SOA) {
2507
2008-07-24
pbug
2508
2014-04-21
pjp
memcpy(reply, buf, len);
2509
2008-07-24
pbug
memset((char *)&odh->query, 0, sizeof(u_int16_t));
2510
2008-07-24
pbug
2511
2008-07-24
pbug
SET_DNS_REPLY(odh);
2512
2010-09-25
pbug
#if 1
2513
2010-09-25
pbug
if (sreply->sr != NULL) {
2514
2010-09-25
pbug
SET_DNS_RECURSION_AVAIL(odh);
2515
2010-09-25
pbug
}
2516
2010-09-25
pbug
#endif
2517
2008-07-24
pbug
SET_DNS_RCODE_NAMEERR(odh);
2518
2008-07-24
pbug
2519
2010-09-25
pbug
2520
2010-09-25
pbug
2521
2008-07-24
pbug
HTONS(odh->query);
2522
2010-09-25
pbug
if (sreply->sr != NULL) {
2523
2014-10-08
pjp
retlen = reply_raw2(so, reply, len, sreply->sr);
2524
2010-09-25
pbug
} else {
2525
2010-09-25
pbug
if (istcp) {
2526
2010-09-25
pbug
char *tmpbuf;
2527
2010-09-25
pbug
u_int16_t *plen;
2528
2008-07-24
pbug
2529
2010-09-25
pbug
tmpbuf = malloc(len + 2);
2530
2010-09-25
pbug
if (tmpbuf == NULL) {
2531
2013-02-16
pjp
dolog(LOG_INFO, "malloc: %s\n", strerror(errno));
2532
2010-09-25
pbug
}
2533
2010-09-25
pbug
plen = (u_int16_t *)tmpbuf;
2534
2010-09-25
pbug
*plen = htons(len);
2535
2010-09-25
pbug
2536
2010-09-25
pbug
memcpy(&tmpbuf[2], reply, len);
2537
2010-03-12
pbug
2538
2014-10-08
pjp
if ((retlen = send(so, tmpbuf, len + 2, 0)) < 0) {
2539
2013-02-16
pjp
dolog(LOG_INFO, "send: %s\n", strerror(errno));
2540
2010-09-25
pbug
}
2541
2010-09-25
pbug
free(tmpbuf);
2542
2010-09-25
pbug
} else {
2543
2014-10-08
pjp
if ((retlen = sendto(so, reply, len, 0, sa, salen)) < 0) {
2544
2013-02-16
pjp
dolog(LOG_INFO, "sendto: %s\n", strerror(errno));
2545
2010-09-25
pbug
}
2546
2010-03-12
pbug
}
2547
2008-07-24
pbug
}
2548
2008-07-24
pbug
2549
2014-10-08
pjp
return (retlen);
2550
2008-07-24
pbug
}
2551
2008-07-24
pbug
2552
2008-07-24
pbug
/* copy question to reply */
2553
2014-04-21
pjp
memcpy(reply, buf, sizeof(struct dns_header) + q->hdr->namelen + 4);
2554
2008-07-24
pbug
/* blank query */
2555
2008-07-24
pbug
memset((char *)&odh->query, 0, sizeof(u_int16_t));
2556
2008-07-24
pbug
2557
2008-07-24
pbug
outlen += (q->hdr->namelen + 4);
2558
2008-07-24
pbug
2559
2008-07-24
pbug
SET_DNS_REPLY(odh);
2560
2010-09-25
pbug
if (sreply->sr != NULL)
2561
2010-09-25
pbug
SET_DNS_RECURSION_AVAIL(odh);
2562
2010-09-25
pbug
else
2563
2010-09-25
pbug
SET_DNS_AUTHORITATIVE(odh);
2564
2010-09-25
pbug
2565
2008-07-24
pbug
SET_DNS_RCODE_NAMEERR(odh);
2566
2008-07-24
pbug
2567
2008-07-24
pbug
NTOHS(odh->query);
2568
2008-07-24
pbug
2569
2010-03-18
pbug
odh->question = htons(1);
2570
2008-07-24
pbug
odh->answer = 0;
2571
2010-03-18
pbug
odh->nsrr = htons(1);
2572
2008-07-24
pbug
odh->additional = 0;
2573
2008-07-24
pbug
2574
2008-07-24
pbug
answer = (struct answer *)(&reply[0] + sizeof(struct dns_header) +
2575
2008-07-24
pbug
q->hdr->namelen + 4);
2576
2008-07-24
pbug
2577
2008-07-24
pbug
answer->name[0] = 0xc0;
2578
2008-07-24
pbug
answer->name[1] = 0x0c;
2579
2008-07-24
pbug
answer->type = htons(DNS_TYPE_SOA);
2580
2008-07-24
pbug
answer->class = q->hdr->qclass;
2581
2010-09-25
pbug
if (sreply->sr != NULL)
2582
2010-09-25
pbug
answer->ttl = htonl(sd->ttl - (time(NULL) - sd->created));
2583
2010-09-25
pbug
else
2584
2010-09-25
pbug
answer->ttl = htonl(sd->ttl);
2585
2008-07-24
pbug
2586
2008-07-24
pbug
outlen += 12; /* up to rdata length */
2587
2008-07-24
pbug
2588
2008-07-24
pbug
p = (char *)&answer->rdata;
2589
2008-07-24
pbug
2590
2005-11-29
pbug
#if 0
2591
2011-09-19
pbug
label = dns_label((char *)mysoa.nsserver, &labellen);
2592
2008-07-24
pbug
if (label == NULL)
2593
2014-10-08
pjp
return (retlen);
2594
2005-12-01
pbug
#endif
2595
2008-07-24
pbug
2596
2011-09-19
pbug
label = &sd->soa.nsserver[0];
2597
2011-09-19
pbug
labellen = sd->soa.nsserver_len;
2598
2008-07-24
pbug
2599
2008-07-24
pbug
plabel = label;
2600
2008-07-24
pbug
2601
2008-07-24
pbug
/* copy label to reply */
2602
2014-04-21
pjp
for (i = outlen; i < replysize; i++) {
2603
2008-07-24
pbug
if (i - outlen == labellen)
2604
2008-07-24
pbug
break;
2605
2008-07-24
pbug
2606
2008-07-24
pbug
reply[i] = *plabel++;
2607
2008-07-24
pbug
}
2608
2008-07-24
pbug
2609
2014-04-21
pjp
if (i >= replysize) {
2610
2014-10-08
pjp
return (retlen);
2611
2008-07-24
pbug
}
2612
2008-07-24
pbug
2613
2008-07-24
pbug
outlen = i;
2614
2005-12-01
pbug
2615
2008-07-24
pbug
/* compress the label if possible */
2616
2010-07-27
pbug
if ((tmplen = compress_label((u_char*)reply, outlen, labellen)) > 0) {
2617
2008-07-24
pbug
outlen = tmplen;
2618
2008-07-24
pbug
}
2619
2008-07-24
pbug
2620
2011-09-19
pbug
label = sd->soa.responsible_person;
2621
2011-09-19
pbug
labellen = sd->soa.rp_len;
2622
2008-07-24
pbug
plabel = label;
2623
2008-07-24
pbug
2624
2014-04-21
pjp
for (i = outlen; i < replysize; i++) {
2625
2008-07-24
pbug
if (i - outlen == labellen)
2626
2008-07-24
pbug
break;
2627
2008-07-24
pbug
2628
2008-07-24
pbug
reply[i] = *plabel++;
2629
2008-07-24
pbug
}
2630
2008-07-24
pbug
2631
2014-04-21
pjp
if (i >= replysize) {
2632
2014-10-08
pjp
return (retlen);
2633
2008-07-24
pbug
}
2634
2008-07-24
pbug
2635
2008-07-24
pbug
outlen = i;
2636
2008-07-24
pbug
2637
2008-07-24
pbug
/* 2 compress the label if possible */
2638
2008-07-24
pbug
2639
2010-07-27
pbug
if ((tmplen = compress_label((u_char*)reply, outlen, labellen)) > 0) {
2640
2008-07-24
pbug
outlen = tmplen;
2641
2008-07-24
pbug
}
2642
2008-07-24
pbug
2643
2008-07-24
pbug
2644
2010-03-28
pbug
/* XXX */
2645
2014-04-21
pjp
if ((outlen + sizeof(sd->soa.serial)) > replysize) {
2646
2008-07-24
pbug
/* XXX server error reply? */
2647
2014-10-08
pjp
return (retlen);
2648
2008-07-24
pbug
}
2649
2008-07-24
pbug
soa_val = (u_int32_t *)&reply[outlen];
2650
2011-09-19
pbug
*soa_val = htonl(sd->soa.serial);
2651
2011-09-19
pbug
outlen += sizeof(sd->soa.serial);
2652
2008-07-24
pbug
2653
2014-04-21
pjp
if ((outlen + sizeof(sd->soa.refresh)) > replysize) {
2654
2014-10-08
pjp
return (retlen);
2655
2008-07-24
pbug
}
2656
2008-07-24
pbug
soa_val = (u_int32_t *)&reply[outlen];
2657
2011-09-19
pbug
*soa_val = htonl(sd->soa.refresh);
2658
2011-09-19
pbug
outlen += sizeof(sd->soa.refresh);
2659
2008-07-24
pbug
2660
2014-04-21
pjp
if ((outlen + sizeof(sd->soa.retry)) > replysize) {
2661
2014-10-08
pjp
return (retlen);
2662
2008-07-24
pbug
}
2663
2008-07-24
pbug
soa_val = (u_int32_t *)&reply[outlen];
2664
2011-09-19
pbug
*soa_val = htonl(sd->soa.retry);
2665
2011-09-19
pbug
outlen += sizeof(sd->soa.retry);
2666
2008-07-24
pbug
2667
2014-04-21
pjp
if ((outlen + sizeof(sd->soa.expire)) > replysize) {
2668
2014-10-08
pjp
return (retlen);
2669
2008-07-24
pbug
}
2670
2008-07-24
pbug
soa_val = (u_int32_t *)&reply[outlen];
2671
2011-09-19
pbug
*soa_val = htonl(sd->soa.expire);
2672
2011-09-19
pbug
outlen += sizeof(sd->soa.expire);
2673
2008-07-24
pbug
2674
2014-04-21
pjp
if ((outlen + sizeof(sd->soa.minttl)) > replysize) {
2675
2014-10-08
pjp
return (retlen);
2676
2008-07-24
pbug
}
2677
2008-07-24
pbug
soa_val = (u_int32_t *)&reply[outlen];
2678
2011-09-19
pbug
*soa_val = htonl(sd->soa.minttl);
2679
2011-09-19
pbug
outlen += sizeof(sd->soa.minttl);
2680
2008-07-24
pbug
2681
2008-07-24
pbug
answer->rdlength = htons(&reply[outlen] - &answer->rdata);
2682
2010-09-25
pbug
2683
2010-09-25
pbug
if (sreply->sr != NULL) {
2684
2014-10-08
pjp
retlen = reply_raw2(so, reply, outlen, sreply->sr);
2685
2010-09-25
pbug
} else {
2686
2008-07-24
pbug
2687
2010-09-25
pbug
if (istcp) {
2688
2010-09-25
pbug
char *tmpbuf;
2689
2010-09-25
pbug
u_int16_t *plen;
2690
2010-09-25
pbug
2691
2010-09-25
pbug
tmpbuf = malloc(outlen + 2);
2692
2010-09-25
pbug
if (tmpbuf == NULL) {
2693
2013-02-16
pjp
dolog(LOG_INFO, "malloc: %s\n", strerror(errno));
2694
2010-09-25
pbug
}
2695
2010-09-25
pbug
plen = (u_int16_t *)tmpbuf;
2696
2010-09-25
pbug
*plen = htons(outlen);
2697
2010-09-25
pbug
2698
2010-09-25
pbug
memcpy(&tmpbuf[2], reply, outlen);
2699
2010-09-25
pbug
2700
2014-10-08
pjp
if ((retlen = send(so, tmpbuf, outlen + 2, 0)) < 0) {
2701
2013-02-16
pjp
dolog(LOG_INFO, "send: %s\n", strerror(errno));
2702
2010-09-25
pbug
}
2703
2010-09-25
pbug
free(tmpbuf);
2704
2010-09-25
pbug
} else {
2705
2014-10-08
pjp
if ((retlen = sendto(so, reply, outlen, 0, sa, salen)) < 0) {
2706
2013-02-16
pjp
dolog(LOG_INFO, "sendto: %s\n", strerror(errno));
2707
2010-09-25
pbug
}
2708
2010-09-25
pbug
}
2709
2010-09-25
pbug
} /* sreply->sr.. */
2710
2010-09-25
pbug
2711
2014-10-08
pjp
return (retlen);
2712
2010-09-25
pbug
}
2713
2010-09-25
pbug
2714
2010-09-25
pbug
/*
2715
2014-05-01
pjp
* REPLY_REFUSED() - replies a DNS question (*q) on socket (so)
2716
2014-05-01
pjp
*
2717
2014-05-01
pjp
*/
2718
2014-05-01
pjp
2719
2014-10-08
pjp
int
2720
2014-05-01
pjp
reply_refused(struct sreply *sreply)
2721
2014-05-01
pjp
{
2722
2014-05-01
pjp
char *reply = sreply->replybuf;
2723
2014-05-01
pjp
struct dns_header *odh;
2724
2014-05-01
pjp
u_int16_t outlen;
2725
2014-05-01
pjp
2726
2014-05-01
pjp
int so = sreply->so;
2727
2014-05-01
pjp
int len = sreply->len;
2728
2014-05-01
pjp
char *buf = sreply->buf;
2729
2014-05-01
pjp
struct sockaddr *sa = sreply->sa;
2730
2014-05-01
pjp
int salen = sreply->salen;
2731
2014-05-01
pjp
int istcp = sreply->istcp;
2732
2014-05-01
pjp
int replysize = 512;
2733
2014-10-08
pjp
int retlen = -1;
2734
2014-05-01
pjp
2735
2014-05-01
pjp
if (istcp) {
2736
2014-05-01
pjp
replysize = 65535;
2737
2014-05-01
pjp
}
2738
2014-05-01
pjp
2739
2014-05-01
pjp
memset(reply, 0, replysize);
2740
2014-05-01
pjp
2741
2014-05-01
pjp
odh = (struct dns_header *)&reply[0];
2742
2014-05-01
pjp
2743
2014-05-01
pjp
outlen = sizeof(struct dns_header);
2744
2014-05-01
pjp
2745
2014-05-01
pjp
if (len > replysize) {
2746
2014-10-08
pjp
return (retlen);
2747
2014-05-01
pjp
}
2748
2014-05-01
pjp
2749
2014-05-01
pjp
memcpy((char *)&odh->id, buf, sizeof(u_int16_t));
2750
2014-05-01
pjp
memset((char *)&odh->query, 0, sizeof(u_int16_t));
2751
2014-05-01
pjp
2752
2014-05-01
pjp
SET_DNS_REPLY(odh);
2753
2014-05-01
pjp
SET_DNS_RCODE_REFUSED(odh);
2754
2014-05-01
pjp
2755
2014-05-01
pjp
HTONS(odh->query);
2756
2014-05-01
pjp
2757
2014-05-01
pjp
if (istcp) {
2758
2014-05-01
pjp
char *tmpbuf;
2759
2014-05-01
pjp
u_int16_t *plen;
2760
2014-05-01
pjp
2761
2014-05-01
pjp
tmpbuf = malloc(outlen + 2);
2762
2014-05-01
pjp
if (tmpbuf == NULL) {
2763
2014-05-01
pjp
dolog(LOG_INFO, "malloc: %s\n", strerror(errno));
2764
2014-05-01
pjp
}
2765
2014-05-01
pjp
plen = (u_int16_t *)tmpbuf;
2766
2014-05-01
pjp
*plen = htons(outlen);
2767
2014-05-01
pjp
2768
2014-05-01
pjp
memcpy(&tmpbuf[2], reply, outlen);
2769
2014-05-01
pjp
2770
2014-10-08
pjp
if ((retlen = send(so, tmpbuf, outlen + 2, 0)) < 0) {
2771
2014-05-01
pjp
dolog(LOG_INFO, "send: %s\n", strerror(errno));
2772
2014-05-01
pjp
}
2773
2014-05-01
pjp
free(tmpbuf);
2774
2014-05-01
pjp
} else {
2775
2014-10-08
pjp
if ((retlen = sendto(so, reply, sizeof(struct dns_header), 0, sa, salen)) < 0) {
2776
2014-05-01
pjp
dolog(LOG_INFO, "sendto: %s\n", strerror(errno));
2777
2014-05-01
pjp
}
2778
2014-05-01
pjp
}
2779
2014-05-01
pjp
2780
2014-10-08
pjp
return (retlen);
2781
2014-05-01
pjp
}
2782
2014-05-01
pjp
2783
2014-05-01
pjp
/*
2784
2005-12-01
pbug
* REPLY_FMTERROR() - replies a DNS question (*q) on socket (so)
2785
2005-12-01
pbug
*
2786
2005-12-01
pbug
*/
2787
2005-12-01
pbug
2788
2014-10-08
pjp
int
2789
2005-12-01
pbug
reply_fmterror(struct sreply *sreply)
2790
2005-12-01
pbug
{
2791
2014-04-21
pjp
char *reply = sreply->replybuf;
2792
2005-12-01
pbug
struct dns_header *odh;
2793
2010-04-15
pbug
u_int16_t outlen;
2794
2005-12-01
pbug
2795
2005-12-01
pbug
int so = sreply->so;
2796
2005-12-01
pbug
int len = sreply->len;
2797
2005-12-01
pbug
char *buf = sreply->buf;
2798
2005-12-01
pbug
struct sockaddr *sa = sreply->sa;
2799
2005-12-01
pbug
int salen = sreply->salen;
2800
2010-03-12
pbug
int istcp = sreply->istcp;
2801
2014-04-21
pjp
int replysize = 512;
2802
2014-10-08
pjp
int retlen = -1;
2803
2005-12-01
pbug
2804
2014-04-21
pjp
if (istcp) {
2805
2014-04-21
pjp
replysize = 65535;
2806
2014-04-21
pjp
}
2807
2010-03-12
pbug
2808
2014-04-21
pjp
memset(reply, 0, replysize);
2809
2014-04-21
pjp
2810
2010-04-05
pbug
odh = (struct dns_header *)&reply[0];
2811
2010-04-05
pbug
2812
2005-12-01
pbug
outlen = sizeof(struct dns_header);
2813
2005-12-01
pbug
2814
2014-04-21
pjp
if (len > replysize) {
2815
2014-10-08
pjp
return (retlen);
2816
2005-12-01
pbug
}
2817
2005-12-01
pbug
2818
2005-12-01
pbug
memcpy((char *)&odh->id, buf, sizeof(u_int16_t));
2819
2005-12-01
pbug
memset((char *)&odh->query, 0, sizeof(u_int16_t));
2820
2005-12-01
pbug
2821
2005-12-01
pbug
SET_DNS_REPLY(odh);
2822
2005-12-01
pbug
SET_DNS_RCODE_FORMATERR(odh);
2823
2005-12-01
pbug
2824
2005-12-01
pbug
HTONS(odh->query);
2825
2005-12-01
pbug
2826
2010-03-12
pbug
if (istcp) {
2827
2010-04-05
pbug
char *tmpbuf;
2828
2010-04-05
pbug
u_int16_t *plen;
2829
2010-04-05
pbug
2830
2010-04-05
pbug
tmpbuf = malloc(outlen + 2);
2831
2010-04-05
pbug
if (tmpbuf == NULL) {
2832
2013-02-16
pjp
dolog(LOG_INFO, "malloc: %s\n", strerror(errno));
2833
2010-03-12
pbug
}
2834
2010-04-05
pbug
plen = (u_int16_t *)tmpbuf;
2835
2010-04-05
pbug
*plen = htons(outlen);
2836
2010-04-05
pbug
2837
2010-04-05
pbug
memcpy(&tmpbuf[2], reply, outlen);
2838
2010-04-05
pbug
2839
2014-10-08
pjp
if ((retlen = send(so, tmpbuf, outlen + 2, 0)) < 0) {
2840
2013-02-16
pjp
dolog(LOG_INFO, "send: %s\n", strerror(errno));
2841
2010-04-05
pbug
}
2842
2010-04-05
pbug
free(tmpbuf);
2843
2010-03-12
pbug
} else {
2844
2014-10-08
pjp
if ((retlen = sendto(so, reply, sizeof(struct dns_header), 0, sa, salen)) < 0) {
2845
2013-02-16
pjp
dolog(LOG_INFO, "sendto: %s\n", strerror(errno));
2846
2010-03-12
pbug
}
2847
2005-12-01
pbug
}
2848
2005-12-01
pbug
2849
2014-10-08
pjp
return (retlen);
2850
2009-03-07
pbug
}
2851
2009-03-07
pbug
2852
2009-03-07
pbug
/*
2853
2009-03-07
pbug
* REPLY_NOERROR() - replies a DNS question (*q) on socket (so)
2854
2009-03-07
pbug
* based on reply_nxdomain
2855
2009-03-07
pbug
*
2856
2009-03-07
pbug
*/
2857
2009-03-07
pbug
2858
2014-10-08
pjp
int
2859
2009-03-07
pbug
reply_noerror(struct sreply *sreply)
2860
2009-03-07
pbug
{
2861
2014-04-21
pjp
char *reply = sreply->replybuf;
2862
2009-03-07
pbug
struct dns_header *odh;
2863
2010-04-15
pbug
u_int16_t outlen;
2864
2009-03-07
pbug
char *p;
2865
2009-03-07
pbug
u_int32_t *soa_val;
2866
2009-03-07
pbug
int i, tmplen;
2867
2009-03-07
pbug
int labellen;
2868
2009-03-07
pbug
char *label, *plabel;
2869
2009-03-07
pbug
2870
2009-03-07
pbug
struct answer {
2871
2009-03-07
pbug
char name[2];
2872
2009-03-07
pbug
u_int16_t type;
2873
2009-03-07
pbug
u_int16_t class;
2874
2009-03-07
pbug
u_int32_t ttl;
2875
2009-03-07
pbug
u_int16_t rdlength; /* 12 */
2876
2009-03-07
pbug
char rdata;
2877
2009-03-07
pbug
} __attribute__((packed));
2878
2009-03-07
pbug
2879
2009-03-07
pbug
struct soa {
2880
2009-03-07
pbug
char *nsserver;
2881
2009-03-07
pbug
char *responsible_person;
2882
2009-03-07
pbug
u_int32_t serial;
2883
2009-03-07
pbug
u_int32_t refresh;
2884
2009-03-07
pbug
u_int32_t retry;
2885
2009-03-07
pbug
u_int32_t expire;
2886
2009-03-07
pbug
u_int32_t minttl;
2887
2009-03-07
pbug
};
2888
2009-03-07
pbug
2889
2009-03-07
pbug
2890
2009-03-07
pbug
struct answer *answer;
2891
2009-03-07
pbug
2892
2009-03-07
pbug
int so = sreply->so;
2893
2009-03-07
pbug
char *buf = sreply->buf;
2894
2009-03-07
pbug
int len = sreply->len;
2895
2009-03-07
pbug
struct question *q = sreply->q;
2896
2009-03-07
pbug
struct sockaddr *sa = sreply->sa;
2897
2009-03-07
pbug
int salen = sreply->salen;
2898
2009-03-07
pbug
struct domain *sd = sreply->sd1;
2899
2010-03-12
pbug
int istcp = sreply->istcp;
2900
2014-04-21
pjp
int replysize = 512;
2901
2014-10-08
pjp
int retlen = -1;
2902
2014-04-21
pjp
2903
2014-04-21
pjp
if (istcp) {
2904
2014-04-21
pjp
replysize = 65535;
2905
2014-04-21
pjp
}
2906
2014-05-10
pjp
2907
2014-05-10
pjp
if (q->edns0len > 512)
2908
2014-05-10
pjp
replysize = q->edns0len;
2909
2009-03-07
pbug
2910
2009-03-07
pbug
odh = (struct dns_header *)&reply[0];
2911
2009-03-07
pbug
outlen = sizeof(struct dns_header);
2912
2009-03-07
pbug
2913
2014-04-21
pjp
if (len > replysize) {
2914
2014-10-08
pjp
return (retlen);
2915
2009-03-07
pbug
2916
2009-03-07
pbug
}
2917
2009-03-07
pbug
2918
2009-03-07
pbug
/*
2919
2009-03-07
pbug
* no SOA, use the old code
2920
2009-03-07
pbug
*/
2921
2009-03-07
pbug
2922
2009-03-07
pbug
if ((sd->flags & DOMAIN_HAVE_SOA) != DOMAIN_HAVE_SOA) {
2923
2009-03-07
pbug
2924
2014-04-21
pjp
memcpy(reply, buf, len);
2925
2009-03-07
pbug
memset((char *)&odh->query, 0, sizeof(u_int16_t));
2926
2009-03-07
pbug
2927
2009-03-07
pbug
SET_DNS_REPLY(odh);
2928
2009-03-07
pbug
#if 0
2929
2009-03-07
pbug
SET_DNS_RCODE_NAMEERR(odh);
2930
2009-03-07
pbug
#endif
2931
2009-03-07
pbug
2932
2009-03-07
pbug
HTONS(odh->query);
2933
2009-03-07
pbug
2934
2010-03-12
pbug
if (istcp) {
2935
2010-03-12
pbug
char *tmpbuf;
2936
2010-03-12
pbug
u_int16_t *plen;
2937
2010-03-12
pbug
2938
2010-03-12
pbug
tmpbuf = malloc(len + 2);
2939
2010-03-12
pbug
if (tmpbuf == NULL) {
2940
2013-02-16
pjp
dolog(LOG_INFO, "malloc: %s\n", strerror(errno));
2941
2010-03-12
pbug
}
2942
2010-03-12
pbug
plen = (u_int16_t *)tmpbuf;
2943
2010-03-12
pbug
*plen = htons(len);
2944
2010-03-12
pbug
2945
2010-03-12
pbug
memcpy(&tmpbuf[2], reply, len);
2946
2010-03-12
pbug
2947
2014-10-08
pjp
if ((retlen = send(so, tmpbuf, len + 2, 0)) < 0) {
2948
2013-02-16
pjp
dolog(LOG_INFO, "send: %s\n", strerror(errno));
2949
2010-03-12
pbug
}
2950
2010-03-12
pbug
free(tmpbuf);
2951
2010-03-12
pbug
} else {
2952
2014-10-08
pjp
if ((retlen = sendto(so, reply, len, 0, sa, salen)) < 0) {
2953
2013-02-16
pjp
dolog(LOG_INFO, "sendto: %s\n", strerror(errno));
2954
2010-03-12
pbug
}
2955
2009-03-07
pbug
}
2956
2009-03-07
pbug
2957
2014-10-08
pjp
return (retlen);
2958
2009-03-07
pbug
}
2959
2009-03-07
pbug
2960
2009-03-07
pbug
/* copy question to reply */
2961
2014-04-21
pjp
memcpy(reply, buf, sizeof(struct dns_header) + q->hdr->namelen + 4);
2962
2009-03-07
pbug
/* blank query */
2963
2009-03-07
pbug
memset((char *)&odh->query, 0, sizeof(u_int16_t));
2964
2009-03-07
pbug
2965
2009-03-07
pbug
outlen += (q->hdr->namelen + 4);
2966
2009-03-07
pbug
2967
2009-03-07
pbug
SET_DNS_REPLY(odh);
2968
2010-09-25
pbug
2969
2010-09-25
pbug
if (sreply->sr == NULL)
2970
2010-09-25
pbug
SET_DNS_AUTHORITATIVE(odh);
2971
2010-09-25
pbug
else
2972
2010-09-25
pbug
SET_DNS_RECURSION_AVAIL(odh);
2973
2009-03-07
pbug
2974
2009-03-07
pbug
NTOHS(odh->query);
2975
2009-03-07
pbug
2976
2010-03-18
pbug
odh->question = htons(1);
2977
2009-03-07
pbug
odh->answer = 0;
2978
2010-03-18
pbug
odh->nsrr = htons(1);
2979
2009-03-07
pbug
odh->additional = 0;
2980
2009-03-07
pbug
2981
2009-03-07
pbug
answer = (struct answer *)(&reply[0] + sizeof(struct dns_header) +
2982
2009-03-07
pbug
q->hdr->namelen + 4);
2983
2009-03-07
pbug
2984
2009-03-07
pbug
answer->name[0] = 0xc0;
2985
2009-03-07
pbug
answer->name[1] = 0x0c;
2986
2009-03-07
pbug
answer->type = htons(DNS_TYPE_SOA);
2987
2009-03-07
pbug
answer->class = q->hdr->qclass;
2988
2010-09-25
pbug
if (sreply->sr != NULL)
2989
2010-09-25
pbug
answer->ttl = htonl(sd->ttl - (time(NULL) - sd->created));
2990
2010-09-25
pbug
else
2991
2010-09-25
pbug
answer->ttl = htonl(sd->ttl);
2992
2009-03-07
pbug
2993
2009-03-07
pbug
outlen += 12; /* up to rdata length */
2994
2009-03-07
pbug
2995
2009-03-07
pbug
p = (char *)&answer->rdata;
2996
2009-03-07
pbug
2997
2011-09-19
pbug
label = sd->soa.nsserver;
2998
2011-09-19
pbug
labellen = sd->soa.nsserver_len;
2999
2009-03-07
pbug
3000
2009-03-07
pbug
plabel = label;
3001
2009-03-07
pbug
3002
2009-03-07
pbug
/* copy label to reply */
3003
2014-04-21
pjp
for (i = outlen; i < replysize; i++) {
3004
2009-03-07
pbug
if (i - outlen == labellen)
3005
2009-03-07
pbug
break;
3006
2009-03-07
pbug
3007
2009-03-07
pbug
reply[i] = *plabel++;
3008
2009-03-07
pbug
}
3009
2009-03-07
pbug
3010
2014-04-21
pjp
if (i >= replysize) {
3011
2014-10-08
pjp
return (retlen);
3012
2009-03-07
pbug
}
3013
2009-03-07
pbug
3014
2009-03-07
pbug
outlen = i;
3015
2009-03-07
pbug
3016
2009-03-07
pbug
/* compress the label if possible */
3017
2010-07-27
pbug
if ((tmplen = compress_label((u_char*)reply, outlen, labellen)) > 0) {
3018
2009-03-07
pbug
outlen = tmplen;
3019
2009-03-07
pbug
}
3020
2009-03-07
pbug
3021
2011-09-19
pbug
label = &sd->soa.responsible_person[0];
3022
2011-09-19
pbug
labellen = sd->soa.rp_len;
3023
2009-03-07
pbug
plabel = label;
3024
2009-03-07
pbug
3025
2014-04-21
pjp
for (i = outlen; i < replysize; i++) {
3026
2009-03-07
pbug
if (i - outlen == labellen)
3027
2009-03-07
pbug
break;
3028
2009-03-07
pbug
3029
2009-03-07
pbug
reply[i] = *plabel++;
3030
2009-03-07
pbug
}
3031
2009-03-07
pbug
3032
2014-04-21
pjp
if (i >= replysize) {
3033
2014-10-08
pjp
return (retlen);
3034
2009-03-07
pbug
}
3035
2009-03-07
pbug
3036
2009-03-07
pbug
outlen = i;
3037
2009-03-07
pbug
3038
2009-03-07
pbug
/* 2 compress the label if possible */
3039
2009-03-07
pbug
3040
2010-07-27
pbug
if ((tmplen = compress_label((u_char*)reply, outlen, labellen)) > 0) {
3041
2009-03-07
pbug
outlen = tmplen;
3042
2009-03-07
pbug
}
3043
2009-03-07
pbug
3044
2009-03-07
pbug
3045
2010-03-28
pbug
/* XXX */
3046
2014-04-21
pjp
if ((outlen + sizeof(sd->soa.serial)) > replysize) {
3047
2009-03-07
pbug
/* XXX server error reply? */
3048
2014-10-08
pjp
return (retlen);
3049
2009-03-07
pbug
}
3050
2009-03-07
pbug
soa_val = (u_int32_t *)&reply[outlen];
3051
2011-09-19
pbug
*soa_val = htonl(sd->soa.serial);
3052
2011-09-19
pbug
outlen += sizeof(sd->soa.serial);
3053
2009-03-07
pbug
3054
2014-04-21
pjp
if ((outlen + sizeof(sd->soa.refresh)) > replysize) {
3055
2014-10-08
pjp
return (retlen);
3056
2009-03-07
pbug
}
3057
2009-03-07
pbug
soa_val = (u_int32_t *)&reply[outlen];
3058
2011-09-19
pbug
*soa_val = htonl(sd->soa.refresh);
3059
2011-09-19
pbug
outlen += sizeof(sd->soa.refresh);
3060
2009-03-07
pbug
3061
2014-04-21
pjp
if ((outlen + sizeof(sd->soa.retry)) > replysize) {
3062
2014-10-08
pjp
return (retlen);
3063
2009-03-07
pbug
}
3064
2009-03-07
pbug
soa_val = (u_int32_t *)&reply[outlen];
3065
2011-09-19
pbug
*soa_val = htonl(sd->soa.retry);
3066
2011-09-19
pbug
outlen += sizeof(sd->soa.retry);
3067
2009-03-07
pbug
3068
2014-04-21
pjp
if ((outlen + sizeof(sd->soa.expire)) > replysize) {
3069
2014-10-08
pjp
return (retlen);
3070
2009-03-07
pbug
}
3071
2009-03-07
pbug
soa_val = (u_int32_t *)&reply[outlen];
3072
2011-09-19
pbug
*soa_val = htonl(sd->soa.expire);
3073
2011-09-19
pbug
outlen += sizeof(sd->soa.expire);
3074
2009-03-07
pbug
3075
2014-04-21
pjp
if ((outlen + sizeof(sd->soa.minttl)) > replysize) {
3076
2014-10-08
pjp
return (retlen);
3077
2009-03-07
pbug
}
3078
2009-03-07
pbug
soa_val = (u_int32_t *)&reply[outlen];
3079
2011-09-19
pbug
*soa_val = htonl(sd->soa.minttl);
3080
2011-09-19
pbug
outlen += sizeof(sd->soa.minttl);
3081
2009-03-07
pbug
3082
2009-03-07
pbug
answer->rdlength = htons(&reply[outlen] - &answer->rdata);
3083
2014-05-10
pjp
3084
2014-05-10
pjp
if (q->edns0len) {
3085
2014-05-10
pjp
/* tag on edns0 opt record */
3086
2014-05-10
pjp
NTOHS(odh->additional);
3087
2014-05-10
pjp
odh->additional++;
3088
2014-05-10
pjp
HTONS(odh->additional);
3089
2014-05-10
pjp
3090
2014-05-10
pjp
outlen = additional_opt(q, reply, replysize, outlen);
3091
2014-05-10
pjp
}
3092
2009-03-07
pbug
3093
2010-09-25
pbug
if (sreply->sr != NULL) {
3094
2014-10-08
pjp
retlen = reply_raw2(so, reply, outlen, sreply->sr);
3095
2010-09-25
pbug
} else {
3096
2010-09-25
pbug
if (istcp) {
3097
2010-09-25
pbug
char *tmpbuf;
3098
2010-09-25
pbug
u_int16_t *plen;
3099
2010-03-12
pbug
3100
2010-09-25
pbug
tmpbuf = malloc(outlen + 2);
3101
2010-09-25
pbug
if (tmpbuf == NULL) {
3102
2013-02-16
pjp
dolog(LOG_INFO, "malloc: %s\n", strerror(errno));
3103
2010-09-25
pbug
}
3104
2010-09-25
pbug
plen = (u_int16_t *)tmpbuf;
3105
2010-09-25
pbug
*plen = htons(outlen);
3106
2010-03-12
pbug
3107
2010-09-25
pbug
memcpy(&tmpbuf[2], reply, outlen);
3108
2010-03-12
pbug
3109
2014-10-08
pjp
if ((retlen = send(so, tmpbuf, outlen + 2, 0)) < 0) {
3110
2013-02-16
pjp
dolog(LOG_INFO, "send: %s\n", strerror(errno));
3111
2010-09-25
pbug
}
3112
2010-09-25
pbug
free(tmpbuf);
3113
2010-09-25
pbug
} else {
3114
2014-10-08
pjp
if ((retlen = sendto(so, reply, outlen, 0, sa, salen)) < 0) {
3115
2013-02-16
pjp
dolog(LOG_INFO, "sendto: %s\n", strerror(errno));
3116
2010-09-25
pbug
}
3117
2010-03-12
pbug
}
3118
2009-03-07
pbug
}
3119
2009-03-07
pbug
3120
2014-10-08
pjp
return (retlen);
3121
2009-11-03
pbug
}
3122
2009-11-03
pbug
3123
2009-11-03
pbug
void
3124
2009-11-03
pbug
update_db(DB *db, struct domain *sd)
3125
2009-11-03
pbug
{
3126
2009-11-03
pbug
int ret;
3127
2010-03-14
pbug
int i = 0;
3128
2009-11-03
pbug
DBT key, data;
3129
2009-11-03
pbug
3130
2009-11-03
pbug
3131
2010-03-13
pbug
do {
3132
2010-03-14
pbug
if (++i == 32) {
3133
2013-02-16
pjp
dolog(LOG_ERR, "could not update zone for 32 tries, giving up entire database, quit");
3134
2011-04-12
pbug
slave_shutdown();
3135
2010-03-14
pbug
exit(1);
3136
2010-03-14
pbug
}
3137
2010-03-14
pbug
3138
2010-03-13
pbug
memset(&key, 0, sizeof(key));
3139
2010-03-13
pbug
memset(&data, 0, sizeof(data));
3140
2009-11-03
pbug
3141
2010-03-13
pbug
key.data = sd->zone;
3142
2010-03-13
pbug
key.size = sd->zonelen;
3143
2010-03-13
pbug
3144
2010-03-13
pbug
data.data = (char *)sd;
3145
2010-03-13
pbug
data.size = sizeof(struct domain);
3146
2010-03-13
pbug
3147
2010-03-13
pbug
ret = db->put(db, NULL, &key, &data, 0);
3148
2010-03-13
pbug
} while (ret != 0);
3149
2010-03-13
pbug
3150
2010-03-13
pbug
return;
3151
2010-03-19
pbug
}
3152
2010-03-19
pbug
3153
2010-03-19
pbug
/*
3154
2010-03-19
pbug
* Lookup_zone: wrapper for lookup_zone() et al.
3155
2010-03-19
pbug
*/
3156
2010-03-19
pbug
3157
2010-03-19
pbug
struct domain *
3158
2010-04-15
pbug
Lookup_zone(DB *db, char *name, u_int16_t namelen, u_int16_t type, int wildcard)
3159
2010-03-19
pbug
{
3160
2010-03-19
pbug
struct domain *sd;
3161
2010-03-19
pbug
struct question *fakequestion;
3162
2010-03-19
pbug
char fakereplystring[DNS_MAXNAME + 1];
3163
2010-03-19
pbug
int mytype;
3164
2010-03-19
pbug
int lzerrno;
3165
2010-03-19
pbug
3166
2010-03-19
pbug
fakequestion = build_fake_question(name, namelen, type);
3167
2010-03-19
pbug
if (fakequestion == NULL) {
3168
2013-02-16
pjp
dolog(LOG_INFO, "fakequestion(2) failed\n");
3169
2010-03-19
pbug
return (NULL);
3170
2010-03-19
pbug
}
3171
2010-03-19
pbug
3172
2010-03-19
pbug
sd = calloc(sizeof(struct domain), 1);
3173
2010-03-19