summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Barach <dave@barachs.net>2017-11-16 10:01:12 -0500
committerFlorin Coras <florin.coras@gmail.com>2017-11-16 16:56:17 +0000
commit52925385345e2222151b6e8c28e3d914ff0b407f (patch)
tree991e5f2fb3636289d45634a45c9952830b3a2cb6
parentf11cbc4fc0a8b0dcfb02732999f6d9427138b709 (diff)
Deal with double name-pointer chases
Change-Id: I153b07b4348133535b16b6bf55527d19a6b927c6 Signed-off-by: Dave Barach <dave@barachs.net>
-rw-r--r--src/vnet/dns/dns.c215
1 files changed, 167 insertions, 48 deletions
diff --git a/src/vnet/dns/dns.c b/src/vnet/dns/dns.c
index d361aa11b3b..cf76439ac8e 100644
--- a/src/vnet/dns/dns.c
+++ b/src/vnet/dns/dns.c
@@ -1075,10 +1075,11 @@ vnet_dns_response_to_reply (u8 * response,
dns_rr_t *rr;
int i, limit;
u8 len;
- u8 *curpos, *pos;
+ u8 *curpos, *pos, *pos2;
u16 flags;
u16 rcode;
u32 ttl;
+ int pointer_chase;
h = (dns_header_t *) response;
flags = clib_net_to_host_u16 (h->flags);
@@ -1134,29 +1135,42 @@ vnet_dns_response_to_reply (u8 * response,
for (i = 0; i < limit; i++)
{
- pos = curpos;
+ pos = pos2 = curpos;
+ pointer_chase = 0;
/* Expect pointer chases in the answer section... */
- if ((pos[0] & 0xC0) == 0xC0)
- curpos += 2;
- else
+ if ((pos2[0] & 0xC0) == 0xC0)
{
- len = *pos++;
- while (len)
+ pos = pos2 + 2;
+ pos2 = response + ((pos2[0] & 0x3f) << 8) + pos2[1];
+ pointer_chase = 1;
+ }
+
+ len = *pos2++;
+
+ while (len)
+ {
+ pos2 += len;
+ if ((pos2[0] & 0xc0) == 0xc0)
{
- if ((pos[0] & 0xC0) == 0xC0)
- {
- curpos = pos + 2;
- goto curpos_set;
- }
- pos += len;
- len = *pos++;
+ /*
+ * If we've already done one pointer chase,
+ * do not move the pos pointer.
+ */
+ if (pointer_chase == 0)
+ pos = pos2 + 2;
+ pos2 = response + ((pos2[0] & 0x3f) << 8) + pos2[1];
+ len = *pos2++;
+ pointer_chase = 1;
}
- curpos = pos;
+ else
+ len = *pos2++;
}
- curpos_set:
- rr = (dns_rr_t *) curpos;
+ if (pointer_chase == 0)
+ pos = pos2;
+
+ rr = (dns_rr_t *) pos;
switch (clib_net_to_host_u16 (rr->type))
{
@@ -1176,13 +1190,15 @@ vnet_dns_response_to_reply (u8 * response,
*min_ttlp = ttl;
rmp->ip6_set = 1;
break;
+
default:
break;
}
/* Might as well stop ASAP */
if (rmp->ip4_set && rmp->ip6_set)
break;
- curpos += sizeof (*rr) + clib_net_to_host_u16 (rr->rdlength);
+ pos += sizeof (*rr) + clib_net_to_host_u16 (rr->rdlength);
+ curpos = pos;
}
if ((rmp->ip4_set + rmp->ip6_set) == 0)
@@ -1200,13 +1216,14 @@ vnet_dns_response_to_name (u8 * response,
dns_rr_t *rr;
int i, limit;
u8 len;
- u8 *curpos, *pos;
+ u8 *curpos, *pos, *pos2;
u16 flags;
u16 rcode;
u8 *name;
u32 ttl;
u8 *junk __attribute__ ((unused));
int name_set = 0;
+ int pointer_chase;
h = (dns_header_t *) response;
flags = clib_net_to_host_u16 (h->flags);
@@ -1262,29 +1279,42 @@ vnet_dns_response_to_name (u8 * response,
for (i = 0; i < limit; i++)
{
- pos = curpos;
+ pos = pos2 = curpos;
+ pointer_chase = 0;
/* Expect pointer chases in the answer section... */
- if ((pos[0] & 0xC0) == 0xC0)
- curpos += 2;
- else
+ if ((pos2[0] & 0xC0) == 0xC0)
{
- len = *pos++;
- while (len)
+ pos = pos2 + 2;
+ pos2 = response + ((pos2[0] & 0x3f) << 8) + pos2[1];
+ pointer_chase = 1;
+ }
+
+ len = *pos2++;
+
+ while (len)
+ {
+ pos2 += len;
+ if ((pos2[0] & 0xc0) == 0xc0)
{
- if ((pos[0] & 0xC0) == 0xC0)
- {
- curpos = pos + 2;
- goto curpos_set;
- }
- pos += len;
- len = *pos++;
+ /*
+ * If we've already done one pointer chase,
+ * do not move the pos pointer.
+ */
+ if (pointer_chase == 0)
+ pos = pos2 + 2;
+ pos2 = response + ((pos2[0] & 0x3f) << 8) + pos2[1];
+ len = *pos2++;
+ pointer_chase = 1;
}
- curpos = pos;
+ else
+ len = *pos2++;
}
- curpos_set:
- rr = (dns_rr_t *) curpos;
+ if (pointer_chase == 0)
+ pos = pos2;
+
+ rr = (dns_rr_t *) pos;
switch (clib_net_to_host_u16 (rr->type))
{
@@ -1292,7 +1322,7 @@ vnet_dns_response_to_name (u8 * response,
name = vnet_dns_labels_to_name (rr->rdata, response, &junk);
memcpy (rmp->name, name, vec_len (name));
ttl = clib_net_to_host_u32 (rr->ttl);
- if (*min_ttlp)
+ if (min_ttlp)
*min_ttlp = ttl;
rmp->name[vec_len (name)] = 0;
name_set = 1;
@@ -1303,7 +1333,8 @@ vnet_dns_response_to_name (u8 * response,
/* Might as well stop ASAP */
if (name_set == 1)
break;
- curpos += sizeof (*rr) + clib_net_to_host_u16 (rr->rdlength);
+ pos += sizeof (*rr) + clib_net_to_host_u16 (rr->rdlength);
+ curpos = pos;
}
if (name_set == 0)
@@ -1700,7 +1731,7 @@ format_dns_reply_data (u8 * s, va_list * args)
u8 *pos, *pos2;
dns_rr_t *rr;
int i;
- int initial_pointer_chase = 0;
+ int pointer_chase = 0;
u16 *tp;
u16 rrtype_host_byte_order;
@@ -1710,11 +1741,11 @@ format_dns_reply_data (u8 * s, va_list * args)
s = format (s, " ");
/* chase pointer? almost always yes here... */
- if (pos2[0] == 0xc0)
+ if ((pos2[0] & 0xc0) == 0xc0)
{
- pos2 = reply + pos2[1];
- pos += 2;
- initial_pointer_chase = 1;
+ pos = pos2 + 2;
+ pos2 = reply + ((pos2[0] & 0x3f) << 8) + pos2[1];
+ pointer_chase = 1;
}
len = *pos2++;
@@ -1727,7 +1758,20 @@ format_dns_reply_data (u8 * s, va_list * args)
vec_add1 (s, *pos2);
pos2++;
}
- len = *pos2++;
+ if ((pos2[0] & 0xc0) == 0xc0)
+ {
+ /*
+ * If we've already done one pointer chase,
+ * do not move the pos pointer.
+ */
+ if (pointer_chase == 0)
+ pos = pos2 + 2;
+ pos2 = reply + ((pos2[0] & 0x3f) << 8) + pos2[1];
+ len = *pos2++;
+ pointer_chase = 1;
+ }
+ else
+ len = *pos2++;
if (len)
{
if (verbose > 1)
@@ -1740,7 +1784,7 @@ format_dns_reply_data (u8 * s, va_list * args)
}
}
- if (initial_pointer_chase == 0)
+ if (pointer_chase == 0)
pos = pos2;
rr = (dns_rr_t *) pos;
@@ -1826,8 +1870,11 @@ format_dns_reply_data (u8 * s, va_list * args)
pos2 = rr->rdata;
/* chase pointer? */
- if (pos2[0] == 0xc0)
- pos2 = reply + pos2[1];
+ if ((pos2[0] & 0xc0) == 0xc0)
+ {
+ pos = pos2 + 2;
+ pos2 = reply + ((pos2[0] & 0x3f) << 8) + pos2[1];
+ }
len = *pos2++;
@@ -2270,7 +2317,7 @@ VLIB_CLI_COMMAND (dns_cache_add_del_command) =
};
/* *INDENT-ON* */
-#define DNS_FORMAT_TEST 1
+#define DNS_FORMAT_TEST 0
#if DNS_FORMAT_TEST > 0
#if 0
@@ -2334,8 +2381,80 @@ static u8 dns_reply_data_initializer[] = {
0x03, 0x63, 0x6f, 0x6d, 0x06, 0x61, 0x6b, 0x61, 0x64,
0x6e, 0x73, 0x03, 0x6e, 0x65, 0x74, 0x00,
};
-#else
+
+/* bind8 (linux widget, w/ nasty double pointer chasees */
+static u8 dns_reply_data_initializer[] = {
+ /* 0 */
+ 0x00, 0x01, 0x81, 0x80, 0x00, 0x01, 0x00, 0x08,
+ /* 8 */
+ 0x00, 0x06, 0x00, 0x06, 0x0a, 0x6f, 0x72, 0x69,
+ /* 16 */
+ 0x67, 0x69, 0x6e, 0x2d, 0x77, 0x77, 0x77, 0x05,
+ /* 24 */
+ 0x63, 0x69, 0x73, 0x63, 0x6f, 0x03, 0x63, 0x6f,
+ /* 32 */
+ 0x6d, 0x00, 0x00, 0xff, 0x00, 0x01, 0x0a, 0x6f,
+ /* 40 */
+ 0x72, 0x69, 0x67, 0x69, 0x6e, 0x2d, 0x77, 0x77,
+ /* 48 */
+ 0x77, 0x05, 0x43, 0x49, 0x53, 0x43, 0x4f, 0xc0,
+
+ /* 56 */
+ 0x1d, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x05,
+
+ /* 64 */
+ 0x9a, 0x00, 0x18, 0x15, 0x72, 0x63, 0x64,
+ 0x6e, 0x39, 0x2d, 0x31, 0x34, 0x70, 0x2d, 0x64, 0x63,
+ 0x7a, 0x30, 0x35, 0x6e, 0x2d, 0x67, 0x73, 0x73, 0x31,
+ 0xc0, 0x17, 0xc0, 0x26, 0x00, 0x02, 0x00, 0x01, 0x00,
+ 0x00, 0x05, 0x9a, 0x00, 0x1a, 0x17, 0x61, 0x6c, 0x6c,
+ 0x6e, 0x30, 0x31, 0x2d, 0x61, 0x67, 0x30, 0x39, 0x2d,
+ 0x64, 0x63, 0x7a, 0x30, 0x33, 0x6e, 0x2d, 0x67, 0x73,
+ 0x73, 0x31, 0xc0, 0x17, 0xc0, 0x26, 0x00, 0x02, 0x00,
+ 0x01, 0x00, 0x00, 0x05, 0x9a, 0x00, 0x10, 0x0d, 0x72,
+ 0x74, 0x70, 0x35, 0x2d, 0x64, 0x6d, 0x7a, 0x2d, 0x67,
+ 0x73, 0x73, 0x31, 0xc0, 0x17, 0xc0, 0x26, 0x00, 0x02,
+ 0x00, 0x01, 0x00, 0x00, 0x05, 0x9a, 0x00, 0x18, 0x15,
+ 0x6d, 0x74, 0x76, 0x35, 0x2d, 0x61, 0x70, 0x31, 0x30,
+ 0x2d, 0x64, 0x63, 0x7a, 0x30, 0x36, 0x6e, 0x2d, 0x67,
+ 0x73, 0x73, 0x31, 0xc0, 0x17, 0xc0, 0x26, 0x00, 0x02,
+ 0x00, 0x01, 0x00, 0x00, 0x05, 0x9a, 0x00, 0x1b, 0x18,
+ 0x73, 0x6e, 0x67, 0x64, 0x63, 0x30, 0x31, 0x2d, 0x61,
+ 0x62, 0x30, 0x37, 0x2d, 0x64, 0x63, 0x7a, 0x30, 0x31,
+ 0x6e, 0x2d, 0x67, 0x73, 0x73, 0x31, 0xc0, 0x17, 0xc0,
+ 0x26, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x05, 0x9a,
+ 0x00, 0x1a, 0x17, 0x61, 0x65, 0x72, 0x30, 0x31, 0x2d,
+ 0x72, 0x34, 0x63, 0x32, 0x35, 0x2d, 0x64, 0x63, 0x7a,
+ 0x30, 0x31, 0x6e, 0x2d, 0x67, 0x73, 0x73, 0x31, 0xc0,
+ 0x17, 0xc0, 0x26, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00,
+ 0x00, 0x81, 0x00, 0x04, 0x48, 0xa3, 0x04, 0xa1, 0xc0,
+ 0x26, 0x00, 0x1c, 0x00, 0x01, 0x00, 0x00, 0x00, 0x82,
+ 0x00, 0x10, 0x20, 0x01, 0x04, 0x20, 0x12, 0x01, 0x00,
+ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a,
+ 0xc0, 0x0c, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x05,
+ 0x9a, 0x00, 0x02, 0xc0, 0xf4, 0xc0, 0x0c, 0x00, 0x02,
+ 0x00, 0x01, 0x00, 0x00, 0x05, 0x9a, 0x00, 0x02, 0xc0,
+ 0xcd, 0xc0, 0x0c, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00,
+ 0x05, 0x9a, 0x00, 0x02, 0xc0, 0x8d, 0xc0, 0x0c, 0x00,
+ 0x02, 0x00, 0x01, 0x00, 0x00, 0x05, 0x9a, 0x00, 0x02,
+ 0xc0, 0x43, 0xc0, 0x0c, 0x00, 0x02, 0x00, 0x01, 0x00,
+ 0x00, 0x05, 0x9a, 0x00, 0x02, 0xc0, 0xa9, 0xc0, 0x0c,
+ 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x05, 0x9a, 0x00,
+ 0x02, 0xc0, 0x67, 0xc0, 0x8d, 0x00, 0x01, 0x00, 0x01,
+ 0x00, 0x00, 0x07, 0x08, 0x00, 0x04, 0x40, 0x66, 0xf6,
+ 0x05, 0xc0, 0xa9, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00,
+ 0x07, 0x08, 0x00, 0x04, 0xad, 0x24, 0xe0, 0x64, 0xc0,
+ 0x43, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x07, 0x08,
+ 0x00, 0x04, 0x48, 0xa3, 0x04, 0x1c, 0xc0, 0xf4, 0x00,
+ 0x01, 0x00, 0x01, 0x00, 0x00, 0x07, 0x08, 0x00, 0x04,
+ 0xad, 0x26, 0xd4, 0x6c, 0xc0, 0x67, 0x00, 0x01, 0x00,
+ 0x01, 0x00, 0x00, 0x07, 0x08, 0x00, 0x04, 0xad, 0x25,
+ 0x90, 0x64, 0xc0, 0xcd, 0x00, 0x01, 0x00, 0x01, 0x00,
+ 0x00, 0x07, 0x08, 0x00, 0x04, 0xad, 0x27, 0x70, 0x44,
+};
+
/* google.com */
+#else
static u8 dns_reply_data_initializer[] =
{ 0x0, 0x0, 0x81, 0x80, 0x0, 0x1, 0x0, 0xe, 0x0, 0x0, 0x0, 0x0, 0x6,
0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x3, 0x63, 0x6f, 0x6d, 0x0, 0x0, 0xff,