bind9/tests/dns/dns64_test.c
Michał Kępień c2dcd055fe
Include <inttypes.h> whenever including <cmocka.h>
Development versions of cmocka require the intmax_t and uintmax_t types
to be defined by the time the test code includes the <cmocka.h> header.
These types are defined in the <stdint.h> header, which is included by
the <inttypes.h> header, which in turn is already explicitly included by
some of the programs in the tests/ directory.  Ensure all programs in
that directory that include the <cmocka.h> header also include the
<inttypes.h> header to future-proof the code while keeping the change
set minimal and the resulting code consistent.  Also prevent explicitly
including the <stdint.h> header in those programs as it is included by
the <inttypes.h> header.
2023-05-18 15:12:23 +02:00

234 lines
6.3 KiB
C

/*
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
*
* SPDX-License-Identifier: MPL-2.0
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
*
* See the COPYRIGHT file distributed with this work for additional
* information regarding copyright ownership.
*/
#include <inttypes.h>
#include <sched.h> /* IWYU pragma: keep */
#include <setjmp.h>
#include <stdarg.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define UNIT_TESTING
#include <cmocka.h>
#include <isc/netaddr.h>
#include <isc/result.h>
#include <isc/string.h>
#include <isc/util.h>
#include <dns/dns64.h>
#include <dns/rdata.h>
#include <dns/rdatalist.h>
#include <dns/rdataset.h>
#include <tests/dns.h>
static void
multiple_prefixes(void) {
size_t i, count;
/*
* Two prefix, non consectutive.
*/
unsigned char aaaa[4][16] = {
{ 0, 0, 0, 0, 192, 0, 0, 170, 0, 0, 0, 0, 192, 0, 0, 171 },
{ 0, 0, 0, 0, 192, 55, 0, 170, 0, 0, 0, 0, 192, 0, 0, 170 },
{ 0, 0, 0, 0, 192, 0, 0, 170, 0, 0, 0, 0, 192, 0, 0, 170 },
{ 0, 0, 0, 0, 192, 55, 0, 170, 0, 0, 0, 0, 192, 0, 0, 171 },
};
dns_rdataset_t rdataset;
dns_rdatalist_t rdatalist;
dns_rdata_t rdata[4] = { DNS_RDATA_INIT, DNS_RDATA_INIT, DNS_RDATA_INIT,
DNS_RDATA_INIT };
isc_netprefix_t prefix[2];
unsigned char p1[] = { 0, 0, 0, 0, 192, 0, 0, 170, 0, 0, 0, 0 };
unsigned char p2[] = { 0, 0, 0, 0, 192, 55, 0, 170, 0, 0, 0, 0 };
isc_result_t result;
bool have_p1, have_p2;
/*
* Construct AAAA rdataset containing 2 prefixes.
*/
dns_rdatalist_init(&rdatalist);
for (i = 0; i < 4; i++) {
isc_region_t region;
region.base = aaaa[i];
region.length = 16;
dns_rdata_fromregion(&rdata[i], dns_rdataclass_in,
dns_rdatatype_aaaa, &region);
ISC_LIST_APPEND(rdatalist.rdata, &rdata[i], link);
}
rdatalist.type = rdata[0].type;
rdatalist.rdclass = rdata[0].rdclass;
rdatalist.ttl = 0;
dns_rdataset_init(&rdataset);
dns_rdatalist_tordataset(&rdatalist, &rdataset);
count = ARRAY_SIZE(prefix);
memset(&prefix, 0, sizeof(prefix));
result = dns_dns64_findprefix(&rdataset, prefix, &count);
assert_int_equal(result, ISC_R_SUCCESS);
assert_int_equal(count, 2);
have_p1 = have_p2 = false;
for (i = 0; i < count; i++) {
assert_int_equal(prefix[i].prefixlen, 96);
assert_int_equal(prefix[i].addr.family, AF_INET6);
if (memcmp(prefix[i].addr.type.in6.s6_addr, p1, 12) == 0) {
have_p1 = true;
}
if (memcmp(prefix[i].addr.type.in6.s6_addr, p2, 12) == 0) {
have_p2 = true;
}
}
assert_true(have_p1);
assert_true(have_p2);
/*
* Check that insufficient prefix space returns ISC_R_NOSPACE
* and that the prefix is populated.
*/
count = 1;
memset(&prefix, 0, sizeof(prefix));
result = dns_dns64_findprefix(&rdataset, prefix, &count);
assert_int_equal(result, ISC_R_NOSPACE);
assert_int_equal(count, 2);
have_p1 = have_p2 = false;
assert_int_equal(prefix[0].prefixlen, 96);
assert_int_equal(prefix[0].addr.family, AF_INET6);
if (memcmp(prefix[0].addr.type.in6.s6_addr, p1, 12) == 0) {
have_p1 = true;
}
if (memcmp(prefix[0].addr.type.in6.s6_addr, p2, 12) == 0) {
have_p2 = true;
}
if (!have_p2) {
assert_true(have_p1);
}
if (!have_p1) {
assert_true(have_p2);
}
assert_true(have_p1 != have_p2);
}
ISC_RUN_TEST_IMPL(dns64_findprefix) {
unsigned int i, j, o;
isc_result_t result;
struct {
unsigned char prefix[12];
unsigned int prefixlen;
isc_result_t result;
} tests[] = {
/* The WKP with various lengths. */
{ { 0, 0x64, 0xff, 0x9b, 0, 0, 0, 0, 0, 0, 0, 0 },
32,
ISC_R_SUCCESS },
{ { 0, 0x64, 0xff, 0x9b, 0, 0, 0, 0, 0, 0, 0, 0 },
40,
ISC_R_SUCCESS },
{ { 0, 0x64, 0xff, 0x9b, 0, 0, 0, 0, 0, 0, 0, 0 },
48,
ISC_R_SUCCESS },
{ { 0, 0x64, 0xff, 0x9b, 0, 0, 0, 0, 0, 0, 0, 0 },
56,
ISC_R_SUCCESS },
{ { 0, 0x64, 0xff, 0x9b, 0, 0, 0, 0, 0, 0, 0, 0 },
64,
ISC_R_SUCCESS },
{ { 0, 0x64, 0xff, 0x9b, 0, 0, 0, 0, 0, 0, 0, 0 },
96,
ISC_R_SUCCESS },
/*
* Prefix with the mapped addresses also appearing in the
* prefix.
*/
{ { 0, 0, 0, 0, 192, 0, 0, 170, 0, 0, 0, 0 },
96,
ISC_R_SUCCESS },
{ { 0, 0, 0, 0, 192, 0, 0, 171, 0, 0, 0, 0 },
96,
ISC_R_SUCCESS },
/* Bad prefix, MBZ != 0. */
{ { 0, 0x64, 0xff, 0x9b, 0, 0, 0, 0, 1, 0, 0, 0 },
96,
ISC_R_NOTFOUND },
};
for (i = 0; i < ARRAY_SIZE(tests); i++) {
size_t count = 2;
dns_rdataset_t rdataset;
dns_rdatalist_t rdatalist;
dns_rdata_t rdata[2] = { DNS_RDATA_INIT, DNS_RDATA_INIT };
struct in6_addr ina6[2];
isc_netprefix_t prefix[2];
unsigned char aa[] = { 192, 0, 0, 170 };
unsigned char ab[] = { 192, 0, 0, 171 };
isc_region_t region;
/*
* Construct rdata.
*/
memset(ina6[0].s6_addr, 0, sizeof(ina6[0].s6_addr));
memset(ina6[1].s6_addr, 0, sizeof(ina6[1].s6_addr));
memmove(ina6[0].s6_addr, tests[i].prefix, 12);
memmove(ina6[1].s6_addr, tests[i].prefix, 12);
o = tests[i].prefixlen / 8;
for (j = 0; j < 4; j++) {
if ((o + j) == 8U) {
o++; /* skip mbz */
}
ina6[0].s6_addr[j + o] = aa[j];
ina6[1].s6_addr[j + o] = ab[j];
}
region.base = ina6[0].s6_addr;
region.length = sizeof(ina6[0].s6_addr);
dns_rdata_fromregion(&rdata[0], dns_rdataclass_in,
dns_rdatatype_aaaa, &region);
region.base = ina6[1].s6_addr;
region.length = sizeof(ina6[1].s6_addr);
dns_rdata_fromregion(&rdata[1], dns_rdataclass_in,
dns_rdatatype_aaaa, &region);
dns_rdatalist_init(&rdatalist);
rdatalist.type = rdata[0].type;
rdatalist.rdclass = rdata[0].rdclass;
rdatalist.ttl = 0;
ISC_LIST_APPEND(rdatalist.rdata, &rdata[0], link);
ISC_LIST_APPEND(rdatalist.rdata, &rdata[1], link);
dns_rdataset_init(&rdataset);
dns_rdatalist_tordataset(&rdatalist, &rdataset);
result = dns_dns64_findprefix(&rdataset, prefix, &count);
assert_int_equal(result, tests[i].result);
if (tests[i].result == ISC_R_SUCCESS) {
assert_int_equal(count, 1);
assert_int_equal(prefix[0].prefixlen,
tests[i].prefixlen);
assert_int_equal(prefix[0].addr.family, AF_INET6);
assert_memory_equal(prefix[0].addr.type.in6.s6_addr,
tests[i].prefix,
tests[i].prefixlen / 8);
}
}
/*
* Test multiple prefixes.
*/
multiple_prefixes();
}
ISC_TEST_LIST_START
ISC_TEST_ENTRY(dns64_findprefix)
ISC_TEST_LIST_END
ISC_TEST_MAIN