Fix data length in encoding dns queries

This commit is contained in:
Erik Ekman 2009-09-20 15:41:24 +00:00
parent 3b4560505a
commit a5c6f93fa2
2 changed files with 38 additions and 41 deletions

View File

@ -90,47 +90,41 @@ dns_encode(char *buf, size_t buflen, struct query *q, qr_t qr, char *data, size_
putshort(&p, C_IN); putshort(&p, C_IN);
putlong(&p, 0); /* TTL */ putlong(&p, 0); /* TTL */
if (q->type == T_CNAME || q->type == T_A || q->type == T_MX) if (q->type == T_CNAME || q->type == T_A || q->type == T_MX) {
{ /* data is expected to be like "Hblabla.host.name.com\0" */
/* data is expected to be like "Hblabla.host.name.com\0" */
char *startp = p; char *startp = p;
int namelen; int namelen;
p += 2; /* skip 2 bytes length */ p += 2; /* skip 2 bytes length */
CHECKLEN(2); CHECKLEN(2);
if (q->type == T_MX) if (q->type == T_MX)
putshort(&p, 10); /* preference */ putshort(&p, 10); /* preference */
putname(&p, buflen - (p - buf), data); putname(&p, buflen - (p - buf), data);
CHECKLEN(0); CHECKLEN(0);
namelen = p - startp; namelen = p - startp;
namelen -= 2; namelen -= 2;
putshort(&startp, namelen); putshort(&startp, namelen);
} } else if (q->type == T_TXT) {
else if (q->type == T_TXT) /* TXT has binary or base-X data */
{ char *startp = p;
/* TXT has binary or base-X data */ int txtlen;
char *startp = p;
int txtlen;
p += 2; /* skip 2 bytes length */
puttxtbin(&p, buflen - (p - buf), data, datalen);
CHECKLEN(0);
txtlen = p - startp;
txtlen -= 2;
putshort(&startp, txtlen);
}
else
{
/* NULL has raw binary data */
datalen = MIN(datalen, buflen - (p - buf));
CHECKLEN(2);
putshort(&p, datalen);
CHECKLEN(datalen);
putdata(&p, data, datalen);
CHECKLEN(0);
}
p += 2; /* skip 2 bytes length */
puttxtbin(&p, buflen - (p - buf), data, datalen);
CHECKLEN(0);
txtlen = p - startp;
txtlen -= 2;
putshort(&startp, txtlen);
} else {
/* NULL has raw binary data */
datalen = MIN(datalen, buflen - (p - buf));
CHECKLEN(2);
putshort(&p, datalen);
CHECKLEN(datalen);
putdata(&p, data, datalen);
CHECKLEN(0);
}
break; break;
case QR_QUERY: case QR_QUERY:
/* Note that iodined also uses this for forward queries */ /* Note that iodined also uses this for forward queries */
@ -138,7 +132,8 @@ dns_encode(char *buf, size_t buflen, struct query *q, qr_t qr, char *data, size_
header->qdcount = htons(1); header->qdcount = htons(1);
header->arcount = htons(1); header->arcount = htons(1);
putname(&p, buflen - (p - buf), data); datalen = MIN(datalen, buflen - (p - buf));
putname(&p, datalen, data);
CHECKLEN(4); CHECKLEN(4);
putshort(&p, q->type); putshort(&p, q->type);

View File

@ -69,8 +69,9 @@ START_TEST(test_encode_query)
char *d; char *d;
size_t len; size_t len;
int ret; int ret;
int enclen;
len = sizeof(buf); enclen = sizeof(resolv);
memset(&buf, 0, sizeof(buf)); memset(&buf, 0, sizeof(buf));
memset(&resolv, 0, sizeof(resolv)); memset(&resolv, 0, sizeof(resolv));
memset(&q, 0, sizeof(struct query)); memset(&q, 0, sizeof(struct query));
@ -80,12 +81,13 @@ START_TEST(test_encode_query)
enc = get_base32_encoder(); enc = get_base32_encoder();
*d++ = 'A'; *d++ = 'A';
enc->encode(d, &len, innerData, strlen(innerData)); enc->encode(d, &enclen, innerData, strlen(innerData));
d = resolv + strlen(resolv); d = resolv + strlen(resolv);
if (*d != '.') { if (*d != '.') {
*d++ = '.'; *d++ = '.';
} }
strcpy(d, topdomain); strcpy(d, topdomain);
len = sizeof(buf);
ret = dns_encode(buf, len, &q, QR_QUERY, resolv, strlen(resolv)); ret = dns_encode(buf, len, &q, QR_QUERY, resolv, strlen(resolv));
len = sizeof(query_packet) - 1; /* Skip extra null character */ len = sizeof(query_packet) - 1; /* Skip extra null character */