aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog9
-rw-r--r--support/Makefile3
-rw-r--r--support/support_format_dns_packet.c21
-rw-r--r--support/tst-support_format_dns_packet.c97
4 files changed, 123 insertions, 7 deletions
diff --git a/ChangeLog b/ChangeLog
index 4206e36e98..db9db56b0f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2017-03-15 Florian Weimer <fweimer@redhat.com>
+
+ * support/support_format_dns_packet.c (support_format_dns_packet):
+ Handle CNAME records in the response. Extract RDATA names from
+ rdata, not the whole packet. Check AAAA record length.
+ * support/tst-support_format_dns_packet.c: New file.
+ * support/Makefile (tests): Add tst-support_format_dns_packet.
+ (tst-support_format_dns_packet): Link against libresolv.
+
2017-03-14 Adhemerval Zanella <adhemerval.zanella@linaro.org>
[BZ #21232]
diff --git a/support/Makefile b/support/Makefile
index 2ace559ae0..db7bb130b2 100644
--- a/support/Makefile
+++ b/support/Makefile
@@ -111,6 +111,7 @@ endif
tests = \
README-testing \
tst-support-namespace \
+ tst-support_format_dns_packet \
tst-support_record_failure \
ifeq ($(run-built-tests),yes)
@@ -125,4 +126,6 @@ $(objpfx)tst-support_record_failure-2.out: tst-support_record_failure-2.sh \
$(evaluate-test)
endif
+$(objpfx)tst-support_format_dns_packet: $(common-objpfx)resolv/libresolv.so
+
include ../Rules
diff --git a/support/support_format_dns_packet.c b/support/support_format_dns_packet.c
index 21fe7e5c8d..2992c57971 100644
--- a/support/support_format_dns_packet.c
+++ b/support/support_format_dns_packet.c
@@ -174,7 +174,7 @@ support_format_dns_packet (const unsigned char *buffer, size_t length)
goto out;
}
/* Skip non-matching record types. */
- if (rtype != qtype || rclass != qclass)
+ if ((rtype != qtype && rtype != T_CNAME) || rclass != qclass)
continue;
switch (rtype)
{
@@ -186,22 +186,29 @@ support_format_dns_packet (const unsigned char *buffer, size_t length)
rdata.data[2],
rdata.data[3]);
else
- fprintf (mem.out, "error: A record of size %d: %s\n", rdlen, rname.name);
+ fprintf (mem.out, "error: A record of size %d: %s\n",
+ rdlen, rname.name);
break;
case T_AAAA:
{
- char buf[100];
- if (inet_ntop (AF_INET6, rdata.data, buf, sizeof (buf)) == NULL)
- fprintf (mem.out, "error: AAAA record decoding failed: %m\n");
+ if (rdlen == 16)
+ {
+ char buf[100];
+ if (inet_ntop (AF_INET6, rdata.data, buf, sizeof (buf)) == NULL)
+ fprintf (mem.out, "error: AAAA record decoding failed: %m\n");
+ else
+ fprintf (mem.out, "address: %s\n", buf);
+ }
else
- fprintf (mem.out, "address: %s\n", buf);
+ fprintf (mem.out, "error: AAAA record of size %d: %s\n",
+ rdlen, rname.name);
}
break;
case T_CNAME:
case T_PTR:
{
struct dname name;
- if (extract_name (full, &in, &name))
+ if (extract_name (full, &rdata, &name))
fprintf (mem.out, "name: %s\n", name.name);
else
fprintf (mem.out, "error: malformed CNAME/PTR record\n");
diff --git a/support/tst-support_format_dns_packet.c b/support/tst-support_format_dns_packet.c
new file mode 100644
index 0000000000..ecd7abfe2b
--- /dev/null
+++ b/support/tst-support_format_dns_packet.c
@@ -0,0 +1,97 @@
+/* Tests for the support_format_dns_packet function.
+ Copyright (C) 2016-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <support/check.h>
+#include <support/format_nss.h>
+#include <support/run_diff.h>
+
+static void
+check_packet (const void *buffer, size_t length,
+ const char *name, const char *expected)
+{
+ char *actual = support_format_dns_packet (buffer, length);
+ if (strcmp (actual, expected) != 0)
+ {
+ support_record_failure ();
+ printf ("error: formatted packet does not match: %s\n", name);
+ support_run_diff ("expected", expected,
+ "actual", actual);
+ }
+ free (actual);
+}
+
+static void
+test_aaaa_length (void)
+{
+ static const char packet[] =
+ /* Header: Response with two records. */
+ "\x12\x34\x80\x00\x00\x01\x00\x02\x00\x00\x00\x00"
+ /* Question section. www.example/IN/AAAA. */
+ "\x03www\x07""example\x00\x00\x1c\x00\x01"
+ /* Answer section. www.example AAAA [corrupted]. */
+ "\xc0\x0c"
+ "\x00\x1c\x00\x01\x00\x00\x00\x00\x00\x10"
+ "\x20\x01\x0d\xb8\x05\x06\x07\x08"
+ "\x11\x12\x13\x14\x15\x16\x17\x18"
+ /* www.example AAAA [corrupted]. */
+ "\xc0\x0c"
+ "\x00\x1c\x00\x01\x00\x00\x00\x00\x00\x11"
+ "\x01\x02\x03\x04\x05\x06\x07\x08"
+ "\x11\x12\x13\x14\x15\x16\x17\x18" "\xff";
+ check_packet (packet, sizeof (packet) - 1, __func__,
+ "name: www.example\n"
+ "address: 2001:db8:506:708:1112:1314:1516:1718\n"
+ "error: AAAA record of size 17: www.example\n");
+}
+
+static void
+test_multiple_cnames (void)
+{
+ static const char packet[] =
+ /* Header: Response with three records. */
+ "\x12\x34\x80\x00\x00\x01\x00\x03\x00\x00\x00\x00"
+ /* Question section. www.example/IN/A. */
+ "\x03www\x07""example\x00\x00\x01\x00\x01"
+ /* Answer section. www.example CNAME www1.example. */
+ "\xc0\x0c"
+ "\x00\x05\x00\x01\x00\x00\x00\x00\x00\x07"
+ "\x04www1\xc0\x10"
+ /* www1 CNAME www2. */
+ "\x04www1\xc0\x10"
+ "\x00\x05\x00\x01\x00\x00\x00\x00\x00\x07"
+ "\x04www2\xc0\x10"
+ /* www2 A 192.0.2.1. */
+ "\x04www2\xc0\x10"
+ "\x00\x01\x00\x01\x00\x00\x00\x00\x00\x04"
+ "\xc0\x00\x02\x01";
+ check_packet (packet, sizeof (packet) - 1, __func__,
+ "name: www.example\n"
+ "name: www1.example\n"
+ "name: www2.example\n"
+ "address: 192.0.2.1\n");
+}
+
+static int
+do_test (void)
+{
+ test_aaaa_length ();
+ test_multiple_cnames ();
+ return 0;
+}
+
+#include <support/test-driver.c>