Annotation of src/external/mpl/bind/dist/lib/dns/tests/rdata_test.c, Revision 1.3
1.2 christos 1: /* $NetBSD: rdata_test.c,v 1.1.1.7 2018/04/07 21:44:09 christos Exp $ */
1.1 christos 2:
3: /*
4: * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
5: *
6: * This Source Code Form is subject to the terms of the Mozilla Public
7: * License, v. 2.0. If a copy of the MPL was not distributed with this
8: * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9: *
10: * See the COPYRIGHT file distributed with this work for additional
11: * information regarding copyright ownership.
12: */
13:
14: #include <config.h>
15:
1.3 ! christos 16: #if HAVE_CMOCKA
1.1 christos 17:
1.3 ! christos 18: #include <stdarg.h>
! 19: #include <stddef.h>
! 20: #include <setjmp.h>
! 21:
! 22: #include <stdbool.h>
! 23: #include <stdlib.h>
! 24: #include <string.h>
1.1 christos 25: #include <unistd.h>
26:
1.3 ! christos 27: #define UNIT_TESTING
! 28: #include <cmocka.h>
! 29:
1.1 christos 30: #include <isc/hex.h>
31: #include <isc/lex.h>
1.3 ! christos 32: #include <isc/stdio.h>
1.1 christos 33: #include <isc/types.h>
1.3 ! christos 34: #include <isc/util.h>
1.1 christos 35:
36: #include <dns/rdata.h>
37:
38: #include "dnstest.h"
39:
1.3 ! christos 40: /*
! 41: * An array of these structures is passed to compare_ok().
! 42: */
! 43: struct compare_ok {
! 44: const char *text1; /* text passed to fromtext_*() */
! 45: const char *text2; /* text passed to fromtext_*() */
! 46: int answer; /* -1, 0, 1 */
! 47: int lineno; /* source line defining this RDATA */
! 48: };
! 49: typedef struct compare_ok compare_ok_t;
! 50:
! 51: static int
! 52: _setup(void **state) {
! 53: isc_result_t result;
! 54:
! 55: UNUSED(state);
! 56:
! 57: result = dns_test_begin(NULL, false);
! 58: assert_int_equal(result, ISC_R_SUCCESS);
! 59:
! 60: return (0);
! 61: }
! 62:
! 63: static int
! 64: _teardown(void **state) {
! 65: UNUSED(state);
! 66:
! 67: dns_test_end();
! 68:
! 69: return (0);
! 70: }
1.1 christos 71:
72: /*
73: * An array of these structures is passed to check_text_ok().
74: */
1.3 ! christos 75: typedef struct text_ok {
1.1 christos 76: const char *text_in; /* text passed to fromtext_*() */
77: const char *text_out; /* text expected from totext_*();
78: NULL indicates text_in is invalid */
1.3 ! christos 79: } text_ok_t;
1.1 christos 80:
81: /*
82: * An array of these structures is passed to check_wire_ok().
83: */
1.3 ! christos 84: typedef struct wire_ok {
1.1 christos 85: unsigned char data[512]; /* RDATA in wire format */
86: size_t len; /* octets of data to parse */
1.3 ! christos 87: bool ok; /* is this RDATA valid? */
! 88: } wire_ok_t;
1.1 christos 89:
1.3 ! christos 90: #define COMPARE(r1, r2, answer) \
! 91: { r1, r2, answer, __LINE__ }
! 92: #define COMPARE_SENTINEL() \
! 93: { NULL, NULL, 0, __LINE__ }
1.1 christos 94:
95: #define TEXT_VALID_CHANGED(data_in, data_out) \
1.3 ! christos 96: { data_in, data_out }
! 97: #define TEXT_VALID(data) { data, data }
! 98: #define TEXT_INVALID(data) { data, NULL }
1.1 christos 99: #define TEXT_SENTINEL() TEXT_INVALID(NULL)
100:
101: #define VARGC(...) (sizeof((unsigned char[]){ __VA_ARGS__ }))
102: #define WIRE_TEST(ok, ...) { \
103: { __VA_ARGS__ }, VARGC(__VA_ARGS__), \
1.3 ! christos 104: ok \
1.1 christos 105: }
1.3 ! christos 106: #define WIRE_VALID(...) WIRE_TEST(true, __VA_ARGS__)
! 107: #define WIRE_INVALID(...) WIRE_TEST(false, __VA_ARGS__)
! 108: #define WIRE_SENTINEL() WIRE_TEST(false)
1.1 christos 109:
110: /*
111: * Test whether converting rdata to a type-specific struct and then back to
112: * rdata results in the same uncompressed wire form. This checks whether
113: * tostruct_*() and fromstruct_*() routines for given RR class and type behave
114: * consistently.
115: *
116: * This function is called for every correctly processed input RDATA, from both
117: * check_text_ok_single() and check_wire_ok_single().
118: */
119: static void
1.3 ! christos 120: check_struct_conversions(dns_rdata_t *rdata, size_t structsize) {
1.1 christos 121: dns_rdataclass_t rdclass = rdata->rdclass;
122: dns_rdatatype_t type = rdata->type;
123: isc_result_t result;
124: isc_buffer_t target;
125: void *rdata_struct;
1.3 ! christos 126: char buf[1024];
1.1 christos 127:
128: rdata_struct = isc_mem_allocate(mctx, structsize);
1.3 ! christos 129: assert_non_null(rdata_struct);
1.1 christos 130:
131: /*
132: * Convert from uncompressed wire form into type-specific struct.
133: */
134: result = dns_rdata_tostruct(rdata, rdata_struct, NULL);
1.3 ! christos 135: assert_int_equal(result, ISC_R_SUCCESS);
! 136:
1.1 christos 137: /*
138: * Convert from type-specific struct into uncompressed wire form.
139: */
140: isc_buffer_init(&target, buf, sizeof(buf));
141: result = dns_rdata_fromstruct(NULL, rdclass, type, rdata_struct,
142: &target);
1.3 ! christos 143: assert_int_equal(result, ISC_R_SUCCESS);
! 144:
1.1 christos 145: /*
146: * Ensure results are consistent.
147: */
1.3 ! christos 148: assert_int_equal(isc_buffer_usedlength(&target), rdata->length);
! 149:
! 150: assert_memory_equal(buf, rdata->data, rdata->length);
1.1 christos 151:
152: isc_mem_free(mctx, rdata_struct);
153: }
154:
155: /*
156: * Check whether converting supplied text form RDATA into uncompressed wire
157: * form succeeds (tests fromtext_*()). If so, try converting it back into text
158: * form and see if it results in the original text (tests totext_*()).
159: */
160: static void
161: check_text_ok_single(const text_ok_t *text_ok, dns_rdataclass_t rdclass,
162: dns_rdatatype_t type, size_t structsize)
163: {
164: dns_rdata_t rdata = DNS_RDATA_INIT;
165: unsigned char buf_fromtext[1024];
166: char buf_totext[1024] = { 0 };
167: isc_buffer_t target;
168: isc_result_t result;
169:
170: /*
171: * Try converting text form RDATA into uncompressed wire form.
172: */
173: result = dns_test_rdatafromstring(&rdata, rdclass, type, buf_fromtext,
174: sizeof(buf_fromtext),
1.3 ! christos 175: text_ok->text_in, false);
1.1 christos 176: /*
177: * Check whether result is as expected.
178: */
179: if (text_ok->text_out != NULL) {
1.3 ! christos 180: assert_int_equal(result, ISC_R_SUCCESS);
1.1 christos 181: } else {
1.3 ! christos 182: assert_int_not_equal(result, ISC_R_SUCCESS);
1.1 christos 183: }
1.3 ! christos 184:
1.1 christos 185: /*
186: * If text form RDATA was not parsed correctly, performing any
187: * additional checks is pointless.
188: */
189: if (result != ISC_R_SUCCESS) {
190: return;
191: }
192: /*
193: * Try converting uncompressed wire form RDATA back into text form and
194: * check whether the resulting text is the same as the original one.
195: */
196: isc_buffer_init(&target, buf_totext, sizeof(buf_totext));
197: result = dns_rdata_totext(&rdata, NULL, &target);
1.3 ! christos 198: assert_int_equal(result, ISC_R_SUCCESS);
! 199: assert_string_equal(buf_totext, text_ok->text_out);
! 200:
1.1 christos 201: /*
202: * Perform two-way conversion checks between uncompressed wire form and
203: * type-specific struct.
204: */
1.3 ! christos 205: check_struct_conversions(&rdata, structsize);
1.1 christos 206: }
207:
208: /*
209: * Test whether supplied wire form RDATA is properly handled as being either
210: * valid or invalid for an RR of given rdclass and type.
211: */
212: static void
213: check_wire_ok_single(const wire_ok_t *wire_ok, dns_rdataclass_t rdclass,
214: dns_rdatatype_t type, size_t structsize)
215: {
216: isc_buffer_t source, target;
217: unsigned char buf[1024];
218: dns_decompress_t dctx;
219: isc_result_t result;
220: dns_rdata_t rdata;
221:
222: /*
223: * Set up len-octet buffer pointing at data.
224: */
225: isc_buffer_constinit(&source, wire_ok->data, wire_ok->len);
226: isc_buffer_add(&source, wire_ok->len);
227: isc_buffer_setactive(&source, wire_ok->len);
228: /*
229: * Initialize target structures.
230: */
231: isc_buffer_init(&target, buf, sizeof(buf));
232: dns_rdata_init(&rdata);
233: /*
234: * Try converting wire data into uncompressed wire form.
235: */
236: dns_decompress_init(&dctx, -1, DNS_DECOMPRESS_ANY);
237: result = dns_rdata_fromwire(&rdata, rdclass, type, &source, &dctx, 0,
238: &target);
239: dns_decompress_invalidate(&dctx);
240: /*
241: * Check whether result is as expected.
242: */
243: if (wire_ok->ok) {
1.3 ! christos 244: assert_int_equal(result, ISC_R_SUCCESS);
1.1 christos 245: } else {
1.3 ! christos 246: assert_int_not_equal(result, ISC_R_SUCCESS);
1.1 christos 247: }
248: /*
249: * If data was parsed correctly, perform two-way conversion checks
250: * between uncompressed wire form and type-specific struct.
251: */
252: if (result == ISC_R_SUCCESS) {
1.3 ! christos 253: check_struct_conversions(&rdata, structsize);
1.1 christos 254: }
255: }
256:
257: /*
258: * Test fromtext_*() and totext_*() routines for given RR class and type for
259: * each text form RDATA in the supplied array. See the comment for
260: * check_text_ok_single() for an explanation of how exactly these routines are
261: * tested.
262: */
263: static void
264: check_text_ok(const text_ok_t *text_ok, dns_rdataclass_t rdclass,
265: dns_rdatatype_t type, size_t structsize)
266: {
267: size_t i;
268:
269: /*
270: * Check all entries in the supplied array.
271: */
272: for (i = 0; text_ok[i].text_in != NULL; i++) {
273: check_text_ok_single(&text_ok[i], rdclass, type, structsize);
274: }
275: }
276:
277: /*
278: * For each wire form RDATA in the supplied array, check whether it is properly
279: * handled as being either valid or invalid for an RR of given rdclass and
280: * type, then check whether trying to process a zero-length wire data buffer
281: * yields the expected result. This checks whether the fromwire_*() routine
282: * for given RR class and type behaves as expected.
283: */
284: static void
1.3 ! christos 285: check_wire_ok(const wire_ok_t *wire_ok, bool empty_ok,
1.1 christos 286: dns_rdataclass_t rdclass, dns_rdatatype_t type,
287: size_t structsize)
288: {
289: wire_ok_t empty_wire = WIRE_TEST(empty_ok);
290: size_t i;
291:
292: /*
293: * Check all entries in the supplied array.
294: */
295: for (i = 0; wire_ok[i].len != 0; i++) {
296: check_wire_ok_single(&wire_ok[i], rdclass, type, structsize);
297: }
298:
299: /*
300: * Check empty wire data.
301: */
302: check_wire_ok_single(&empty_wire, rdclass, type, structsize);
303: }
304:
305: /*
1.3 ! christos 306: * Check that two records compare as expected with dns_rdata_compare().
! 307: */
! 308: static void
! 309: check_compare_ok_single(const compare_ok_t *compare_ok,
! 310: dns_rdataclass_t rdclass, dns_rdatatype_t type)
! 311: {
! 312: dns_rdata_t rdata1 = DNS_RDATA_INIT, rdata2 = DNS_RDATA_INIT;
! 313: unsigned char buf1[1024], buf2[1024];
! 314: isc_result_t result;
! 315: int answer;
! 316:
! 317: result = dns_test_rdatafromstring(&rdata1, rdclass, type,
! 318: buf1, sizeof(buf1),
! 319: compare_ok->text1, false);
! 320: if (result != ISC_R_SUCCESS) {
! 321: fail_msg("# line %d: '%s': expected success, got failure",
! 322: compare_ok->lineno, compare_ok->text1);
! 323: }
! 324:
! 325: result = dns_test_rdatafromstring(&rdata2, rdclass, type,
! 326: buf2, sizeof(buf2),
! 327: compare_ok->text2, false);
! 328:
! 329: if (result != ISC_R_SUCCESS) {
! 330: fail_msg("# line %d: '%s': expected success, got failure",
! 331: compare_ok->lineno, compare_ok->text2);
! 332: }
! 333:
! 334: answer = dns_rdata_compare(&rdata1, &rdata2);
! 335: if (compare_ok->answer == 0 && answer != 0) {
! 336: fail_msg("# line %d: dns_rdata_compare('%s', '%s'): "
! 337: "expected equal, got %s",
! 338: compare_ok->lineno,
! 339: compare_ok->text1, compare_ok->text2,
! 340: (answer > 0) ? "greater than" : "less than");
! 341: }
! 342: if (compare_ok->answer < 0 && answer >= 0) {
! 343: fail_msg("# line %d: dns_rdata_compare('%s', '%s'): "
! 344: "expected less than, got %s",
! 345: compare_ok->lineno,
! 346: compare_ok->text1, compare_ok->text2,
! 347: (answer == 0) ? "equal" : "greater than");
! 348: }
! 349: if (compare_ok->answer > 0 && answer <= 0) {
! 350: fail_msg("line %d: dns_rdata_compare('%s', '%s'): "
! 351: "expected greater than, got %s",
! 352: compare_ok->lineno,
! 353: compare_ok->text1, compare_ok->text2,
! 354: (answer == 0) ? "equal" : "less than");
! 355: }
! 356: }
! 357:
! 358: /*
! 359: * Check that all the records sets in compare_ok compare as expected
! 360: * with dns_rdata_compare().
! 361: */
! 362: static void
! 363: check_compare_ok(const compare_ok_t *compare_ok,
! 364: dns_rdataclass_t rdclass, dns_rdatatype_t type)
! 365: {
! 366: size_t i;
! 367: /*
! 368: * Check all entries in the supplied array.
! 369: */
! 370: for (i = 0; compare_ok[i].text1 != NULL; i++) {
! 371: check_compare_ok_single(&compare_ok[i], rdclass, type);
! 372: }
! 373: }
! 374:
! 375: /*
1.1 christos 376: * Test whether supplied sets of text form and/or wire form RDATA are handled
1.3 ! christos 377: * as expected.
1.1 christos 378: *
379: * The empty_ok argument denotes whether an attempt to parse a zero-length wire
380: * data buffer should succeed or not (it is valid for some RR types). There is
381: * no point in performing a similar check for empty text form RDATA, because
382: * dns_rdata_fromtext() returns ISC_R_UNEXPECTEDEND before calling fromtext_*()
383: * for the given RR class and type.
384: */
385: static void
386: check_rdata(const text_ok_t *text_ok, const wire_ok_t *wire_ok,
1.3 ! christos 387: const compare_ok_t *compare_ok,
! 388: bool empty_ok, dns_rdataclass_t rdclass,
1.1 christos 389: dns_rdatatype_t type, size_t structsize)
390: {
391: if (text_ok != NULL) {
392: check_text_ok(text_ok, rdclass, type, structsize);
393: }
394: if (wire_ok != NULL) {
395: check_wire_ok(wire_ok, empty_ok, rdclass, type, structsize);
396: }
1.3 ! christos 397: if (compare_ok != NULL) {
! 398: check_compare_ok(compare_ok, rdclass, type);
! 399: }
! 400: }
! 401:
! 402: /* APL RDATA manipulations */
! 403: static void
! 404: apl(void **state) {
! 405: text_ok_t text_ok[] = {
! 406: /* empty list */
! 407: TEXT_VALID(""),
! 408: /* min,max prefix IPv4 */
! 409: TEXT_VALID("1:0.0.0.0/0"),
! 410: TEXT_VALID("1:127.0.0.1/32"),
! 411: /* min,max prefix IPv6 */
! 412: TEXT_VALID("2:::/0"),
! 413: TEXT_VALID("2:::1/128"),
! 414: /* negated */
! 415: TEXT_VALID("!1:0.0.0.0/0"),
! 416: TEXT_VALID("!1:127.0.0.1/32"),
! 417: TEXT_VALID("!2:::/0"),
! 418: TEXT_VALID("!2:::1/128"),
! 419: /* bits set after prefix length - not disallowed */
! 420: TEXT_VALID("1:127.0.0.0/0"),
! 421: TEXT_VALID("2:8000::/0"),
! 422: /* multiple */
! 423: TEXT_VALID("1:0.0.0.0/0 1:127.0.0.1/32"),
! 424: TEXT_VALID("1:0.0.0.0/0 !1:127.0.0.1/32"),
! 425: /* family 0, prefix 0, positive */
! 426: TEXT_VALID("\\# 4 00000000"),
! 427: /* family 0, prefix 0, negative */
! 428: TEXT_VALID("\\# 4 00000080"),
! 429: /* prefix too long */
! 430: TEXT_INVALID("1:0.0.0.0/33"),
! 431: TEXT_INVALID("2:::/129"),
! 432: /*
! 433: * Sentinel.
! 434: */
! 435: TEXT_SENTINEL()
! 436: };
! 437: wire_ok_t wire_ok[] = {
! 438: /* zero length */
! 439: WIRE_VALID(),
! 440: /* prefix too big IPv4 */
! 441: WIRE_INVALID(0x00, 0x01, 33U, 0x00),
! 442: /* prefix too big IPv6 */
! 443: WIRE_INVALID(0x00, 0x02, 129U, 0x00),
! 444: /* trailing zero octet in afdpart */
! 445: WIRE_INVALID(0x00, 0x00, 0x00, 0x01, 0x00),
! 446: /*
! 447: * Sentinel.
! 448: */
! 449: WIRE_SENTINEL()
! 450: };
! 451:
! 452: UNUSED(state);
1.1 christos 453:
1.3 ! christos 454: check_rdata(text_ok, wire_ok, NULL, true, dns_rdataclass_in,
! 455: dns_rdatatype_apl, sizeof(dns_rdata_in_apl_t));
1.1 christos 456: }
457:
1.3 ! christos 458: /*
! 459: * http://broadband-forum.org/ftp/pub/approved-specs/af-saa-0069.000.pdf
! 460: *
! 461: * ATMA RR’s have the following RDATA format:
! 462: *
! 463: * 1 1 1 1 1 1
! 464: * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
! 465: * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
! 466: * | FORMAT | |
! 467: * +--+--+--+--+--+--+--+--+ |
! 468: * / ADDRESS /
! 469: * | |
! 470: * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
! 471: *
! 472: * The fields have the following meaning:
! 473: *
! 474: * * FORMAT: One octet that indicates the format of ADDRESS. The two
! 475: * possible values for FORMAT are value 0 indicating ATM End System Address
! 476: * (AESA) format and value 1 indicating E.164 format.
! 477: *
! 478: * * ADDRESS: Variable length string of octets containing the ATM address of
! 479: * the node to which this RR pertains.
! 480: *
! 481: * When the format value is 0, indicating that the address is in AESA format,
! 482: * the address is coded as described in ISO 8348/AD 2 using the preferred
! 483: * binary encoding of the ISO NSAP format. When the format value is 1,
! 484: * indicating that the address is in E.164 format, the Address/Number Digits
! 485: * appear in the order in which they would be entered on a numeric keypad.
! 486: * Digits are coded in IA5 characters with the leftmost bit of each digit set
! 487: * to 0. This ATM address appears in ATM End System Address Octets field (AESA
! 488: * format) or the Address/Number Digits field (E.164 format) of the Called
! 489: * party number information element [ATMUNI3.1]. Subaddress information is
! 490: * intentionally not included because E.164 subaddress information is used for
! 491: * routing.
! 492: *
! 493: * ATMA RRs cause no additional section processing.
! 494: */
! 495: static void
! 496: atma(void **state) {
! 497: text_ok_t text_ok[] = {
! 498: TEXT_VALID("00"),
! 499: TEXT_VALID_CHANGED("0.0", "00"),
! 500: /*
! 501: * multiple consecutive periods
! 502: */
! 503: TEXT_INVALID("0..0"),
! 504: /*
! 505: * trailing period
! 506: */
! 507: TEXT_INVALID("00."),
! 508: /*
! 509: * leading period
! 510: */
! 511: TEXT_INVALID(".00"),
! 512: /*
! 513: * Not full octets.
! 514: */
! 515: TEXT_INVALID("000"),
! 516: /*
! 517: * E.164
! 518: */
! 519: TEXT_VALID("+61200000000"),
! 520: /*
! 521: * E.164 with periods
! 522: */
! 523: TEXT_VALID_CHANGED("+61.2.0000.0000", "+61200000000"),
! 524: /*
! 525: * E.164 with period at end
! 526: */
! 527: TEXT_INVALID("+61200000000."),
! 528: /*
! 529: * E.164 with multiple consecutive periods
! 530: */
! 531: TEXT_INVALID("+612..00000000"),
! 532: /*
! 533: * E.164 with period before the leading digit.
! 534: */
! 535: TEXT_INVALID("+.61200000000"),
! 536: /*
! 537: * Sentinel.
! 538: */
! 539: TEXT_SENTINEL()
! 540: };
! 541: wire_ok_t wire_ok[] = {
! 542: /*
! 543: * Too short.
! 544: */
! 545: WIRE_INVALID(0x00),
! 546: WIRE_INVALID(0x01),
! 547: /*
! 548: * all digits
! 549: */
! 550: WIRE_VALID(0x01, '6', '1', '2', '0', '0', '0'),
! 551: /*
! 552: * non digit
! 553: */
! 554: WIRE_INVALID(0x01, '+', '6', '1', '2', '0', '0', '0'),
! 555: /*
! 556: * Sentinel.
! 557: */
! 558: WIRE_SENTINEL()
! 559: };
! 560:
! 561: UNUSED(state);
! 562:
! 563: check_rdata(text_ok, wire_ok, NULL, false, dns_rdataclass_in,
! 564: dns_rdatatype_atma, sizeof(dns_rdata_in_atma_t));
! 565: }
1.1 christos 566:
567: /*
568: * CSYNC tests.
569: *
570: * RFC 7477:
571: *
572: * 2.1. The CSYNC Resource Record Format
573: *
574: * 2.1.1. The CSYNC Resource Record Wire Format
575: *
576: * The CSYNC RDATA consists of the following fields:
577: *
578: * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
579: * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
580: * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
581: * | SOA Serial |
582: * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
583: * | Flags | Type Bit Map /
584: * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
585: * / Type Bit Map (continued) /
586: * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
587: *
588: * 2.1.1.1. The SOA Serial Field
589: *
590: * The SOA Serial field contains a copy of the 32-bit SOA serial number
591: * from the child zone. If the soaminimum flag is set, parental agents
592: * querying children's authoritative servers MUST NOT act on data from
593: * zones advertising an SOA serial number less than this value. See
594: * [RFC1982] for properly implementing "less than" logic. If the
595: * soaminimum flag is not set, parental agents MUST ignore the value in
596: * the SOA Serial field. Clients can set the field to any value if the
597: * soaminimum flag is unset, such as the number zero.
598: *
599: * (...)
600: *
601: * 2.1.1.2. The Flags Field
602: *
603: * The Flags field contains 16 bits of boolean flags that define
604: * operations that affect the processing of the CSYNC record. The flags
605: * defined in this document are as follows:
606: *
607: * 0x00 0x01: "immediate"
608: *
609: * 0x00 0x02: "soaminimum"
610: *
611: * The definitions for how the flags are to be used can be found in
612: * Section 3.
613: *
614: * The remaining flags are reserved for use by future specifications.
615: * Undefined flags MUST be set to 0 by CSYNC publishers. Parental
616: * agents MUST NOT process a CSYNC record if it contains a 1 value for a
617: * flag that is unknown to or unsupported by the parental agent.
618: *
619: * 2.1.1.2.1. The Type Bit Map Field
620: *
621: * The Type Bit Map field indicates the record types to be processed by
622: * the parental agent, according to the procedures in Section 3. The
623: * Type Bit Map field is encoded in the same way as the Type Bit Map
624: * field of the NSEC record, described in [RFC4034], Section 4.1.2. If
625: * a bit has been set that a parental agent implementation does not
626: * understand, the parental agent MUST NOT act upon the record.
627: * Specifically, a parental agent must not simply copy the data, and it
628: * must understand the semantics associated with a bit in the Type Bit
629: * Map field that has been set to 1.
630: */
1.3 ! christos 631: static void
! 632: csync(void **state) {
1.1 christos 633: text_ok_t text_ok[] = {
634: TEXT_INVALID(""),
635: TEXT_INVALID("0"),
636: TEXT_VALID("0 0"),
637: TEXT_VALID("0 0 A"),
638: TEXT_VALID("0 0 NS"),
639: TEXT_VALID("0 0 AAAA"),
640: TEXT_VALID("0 0 A AAAA"),
641: TEXT_VALID("0 0 A NS AAAA"),
642: TEXT_INVALID("0 0 A NS AAAA BOGUS"),
643: TEXT_SENTINEL()
644: };
645: wire_ok_t wire_ok[] = {
646: /*
647: * Short.
648: */
649: WIRE_INVALID(0x00),
650: /*
651: * Short.
652: */
653: WIRE_INVALID(0x00, 0x00),
654: /*
655: * Short.
656: */
657: WIRE_INVALID(0x00, 0x00, 0x00),
658: /*
659: * Short.
660: */
661: WIRE_INVALID(0x00, 0x00, 0x00, 0x00),
662: /*
663: * Short.
664: */
665: WIRE_INVALID(0x00, 0x00, 0x00, 0x00, 0x00),
666: /*
667: * Serial + flags only.
668: */
669: WIRE_VALID(0x00, 0x00, 0x00, 0x00, 0x00, 0x00),
670: /*
671: * Bad type map.
672: */
673: WIRE_INVALID(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00),
674: /*
675: * Bad type map.
676: */
677: WIRE_INVALID(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00),
678: /*
679: * Good type map.
680: */
681: WIRE_VALID(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
682: 0x02),
683: /*
684: * Sentinel.
685: */
686: WIRE_SENTINEL()
687: };
688:
1.3 ! christos 689: UNUSED(state);
1.1 christos 690:
1.3 ! christos 691: check_rdata(text_ok, wire_ok, NULL, false, dns_rdataclass_in,
1.1 christos 692: dns_rdatatype_csync, sizeof(dns_rdata_csync_t));
693: }
694:
695: /*
696: * DOA tests.
697: *
698: * draft-durand-doa-over-dns-03:
699: *
700: * 3.2. DOA RDATA Wire Format
701: *
702: * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
703: * 0: | |
704: * | DOA-ENTERPRISE |
705: * | |
706: * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
707: * 4: | |
708: * | DOA-TYPE |
709: * | |
710: * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
711: * 8: | DOA-LOCATION | DOA-MEDIA-TYPE /
712: * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
713: * 10: / /
714: * / DOA-MEDIA-TYPE (continued) /
715: * / /
716: * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
717: * / /
718: * / DOA-DATA /
719: * / /
720: * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
721: *
722: * DOA-ENTERPRISE: a 32-bit unsigned integer in network order.
723: *
724: * DOA-TYPE: a 32-bit unsigned integer in network order.
725: *
726: * DOA-LOCATION: an 8-bit unsigned integer.
727: *
728: * DOA-MEDIA-TYPE: A <character-string> (see [RFC1035]). The first
729: * octet of the <character-string> contains the number of characters to
730: * follow.
731: *
732: * DOA-DATA: A variable length blob of binary data. The length of the
733: * DOA-DATA is not contained within the wire format of the RR and has to
734: * be computed from the RDLENGTH of the entire RR once other fields have
735: * been taken into account.
736: *
737: * 3.3. DOA RDATA Presentation Format
738: *
739: * The DOA-ENTERPRISE field is presented as an unsigned 32-bit decimal
740: * integer with range 0 - 4,294,967,295.
741: *
742: * The DOA-TYPE field is presented as an unsigned 32-bit decimal integer
743: * with range 0 - 4,294,967,295.
744: *
745: * The DOA-LOCATION field is presented as an unsigned 8-bit decimal
746: * integer with range 0 - 255.
747: *
748: * The DOA-MEDIA-TYPE field is presented as a single <character-string>.
749: *
750: * The DOA-DATA is presented as Base64 encoded data [RFC4648] unless the
751: * DOA-DATA is empty in which case it is presented as a single dash
752: * character ("-", ASCII 45). White space is permitted within Base64
753: * data.
754: */
1.3 ! christos 755: static void
! 756: doa(void **state) {
1.1 christos 757: text_ok_t text_ok[] = {
758: /*
759: * Valid, non-empty DOA-DATA.
760: */
761: TEXT_VALID("0 0 1 \"text/plain\" Zm9v"),
762: /*
763: * Valid, non-empty DOA-DATA with whitespace in between.
764: */
765: TEXT_VALID_CHANGED("0 0 1 \"text/plain\" Zm 9v",
766: "0 0 1 \"text/plain\" Zm9v"),
767: /*
768: * Valid, unquoted DOA-MEDIA-TYPE, non-empty DOA-DATA.
769: */
770: TEXT_VALID_CHANGED("0 0 1 text/plain Zm9v",
771: "0 0 1 \"text/plain\" Zm9v"),
772: /*
773: * Invalid, quoted non-empty DOA-DATA.
774: */
775: TEXT_INVALID("0 0 1 \"text/plain\" \"Zm9v\""),
776: /*
777: * Valid, empty DOA-DATA.
778: */
779: TEXT_VALID("0 0 1 \"text/plain\" -"),
780: /*
781: * Invalid, quoted empty DOA-DATA.
782: */
783: TEXT_INVALID("0 0 1 \"text/plain\" \"-\""),
784: /*
785: * Invalid, missing "-" in empty DOA-DATA.
786: */
787: TEXT_INVALID("0 0 1 \"text/plain\""),
788: /*
789: * Valid, undefined DOA-LOCATION.
790: */
791: TEXT_VALID("0 0 100 \"text/plain\" Zm9v"),
792: /*
793: * Invalid, DOA-LOCATION too big.
794: */
795: TEXT_INVALID("0 0 256 \"text/plain\" ZM9v"),
796: /*
797: * Valid, empty DOA-MEDIA-TYPE, non-empty DOA-DATA.
798: */
799: TEXT_VALID("0 0 2 \"\" aHR0cHM6Ly93d3cuaXNjLm9yZy8="),
800: /*
801: * Valid, empty DOA-MEDIA-TYPE, empty DOA-DATA.
802: */
803: TEXT_VALID("0 0 1 \"\" -"),
804: /*
805: * Valid, DOA-MEDIA-TYPE with a space.
806: */
807: TEXT_VALID("0 0 1 \"plain text\" Zm9v"),
808: /*
809: * Invalid, missing DOA-MEDIA-TYPE.
810: */
811: TEXT_INVALID("1234567890 1234567890 1"),
812: /*
813: * Valid, DOA-DATA over 255 octets.
814: */
815: TEXT_VALID("1234567890 1234567890 1 \"image/gif\" "
816: "R0lGODlhKAAZAOMCAGZmZgBmmf///zOZzMz//5nM/zNmmWbM"
817: "/5nMzMzMzACZ/////////////////////yH5BAEKAA8ALAAA"
818: "AAAoABkAAATH8IFJK5U2a4337F5ogRkpnoCJrly7PrCKyh8c"
819: "3HgAhzT35MDbbtO7/IJIHbGiOiaTxVTpSVWWLqNq1UVyapNS"
820: "1wd3OAxug0LhnCubcVhsxysQnOt4ATpvvzHlFzl1AwODhWeF"
821: "AgRpen5/UhheAYMFdUB4SFcpGEGGdQeCAqBBLTuSk30EeXd9"
822: "pEsAbKGxjHqDSE0Sp6ixN4N1BJmbc7lIhmsBich1awPAjkY1"
823: "SZR8bJWrz382SGqIBQQFQd4IsUTaX+ceuudPEQA7"),
824: /*
825: * Invalid, bad Base64 in DOA-DATA.
826: */
827: TEXT_INVALID("1234567890 1234567890 1 \"image/gif\" R0lGODl"),
828: /*
829: * Sentinel.
830: */
831: TEXT_SENTINEL()
832: };
833: wire_ok_t wire_ok[] = {
834: /*
835: * Valid, empty DOA-MEDIA-TYPE, empty DOA-DATA.
836: */
837: WIRE_VALID(0x12, 0x34, 0x56, 0x78, 0x12, 0x34, 0x56, 0x78,
838: 0x01, 0x00),
839: /*
840: * Invalid, missing DOA-MEDIA-TYPE.
841: */
842: WIRE_INVALID(0x12, 0x34, 0x56, 0x78, 0x12, 0x34, 0x56, 0x78,
843: 0x01),
844: /*
845: * Invalid, malformed DOA-MEDIA-TYPE length.
846: */
847: WIRE_INVALID(0x12, 0x34, 0x56, 0x78, 0x12, 0x34, 0x56, 0x78,
848: 0x01, 0xff),
849: /*
850: * Valid, empty DOA-DATA.
851: */
852: WIRE_VALID(0x12, 0x34, 0x56, 0x78, 0x12, 0x34, 0x56, 0x78,
853: 0x01, 0x03, 0x66, 0x6f, 0x6f),
854: /*
855: * Valid, non-empty DOA-DATA.
856: */
857: WIRE_VALID(0x12, 0x34, 0x56, 0x78, 0x12, 0x34, 0x56, 0x78,
858: 0x01, 0x03, 0x66, 0x6f, 0x6f, 0x62, 0x61, 0x72),
859: /*
860: * Valid, DOA-DATA over 255 octets.
861: */
862: WIRE_VALID(0x12, 0x34, 0x56, 0x78, 0x12, 0x34, 0x56, 0x78,
863: 0x01, 0x06, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79,
864: 0x00, 0x66, 0x99, 0xff, 0xff, 0xff, 0x33, 0x99,
865: 0xcc, 0xcc, 0xff, 0xff, 0x99, 0xcc, 0xff, 0x33,
866: 0x66, 0x99, 0x66, 0xcc, 0xff, 0x99, 0xcc, 0xcc,
867: 0xcc, 0xcc, 0xcc, 0x00, 0x99, 0xff, 0xff, 0xff,
868: 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
869: 0xff, 0xff, 0xff, 0xff, 0xff, 0x21, 0xf9, 0x04,
870: 0x01, 0x0a, 0x00, 0x0f, 0x00, 0x2c, 0x00, 0x00,
871: 0x00, 0x00, 0x28, 0x00, 0x19, 0x00, 0x00, 0x04,
872: 0xc7, 0xf0, 0x81, 0x49, 0x2b, 0x95, 0x36, 0x6b,
873: 0x8d, 0xf7, 0xec, 0x5e, 0x68, 0x81, 0x19, 0x29,
874: 0x9e, 0x80, 0x89, 0xae, 0x5c, 0xbb, 0x3e, 0xb0,
875: 0x8a, 0xca, 0x1f, 0x1c, 0xdc, 0x78, 0x00, 0x87,
876: 0x34, 0xf7, 0xe4, 0xc0, 0xdb, 0x6e, 0xd3, 0xbb,
877: 0xfc, 0x82, 0x48, 0x1d, 0xb1, 0xa2, 0x3a, 0x26,
878: 0x93, 0xc5, 0x54, 0xe9, 0x49, 0x55, 0x96, 0x2e,
879: 0xa3, 0x6a, 0xd5, 0x45, 0x72, 0x6a, 0x93, 0x52,
880: 0xd7, 0x07, 0x77, 0x38, 0x0c, 0x6e, 0x83, 0x42,
881: 0xe1, 0x9c, 0x2b, 0x9b, 0x71, 0x58, 0x6c, 0xc7,
882: 0x2b, 0x10, 0x9c, 0xeb, 0x78, 0x01, 0x3a, 0x6f,
883: 0xbf, 0x31, 0xe5, 0x17, 0x39, 0x75, 0x03, 0x03,
884: 0x83, 0x85, 0x67, 0x85, 0x02, 0x04, 0x69, 0x7a,
885: 0x7e, 0x7f, 0x52, 0x18, 0x5e, 0x01, 0x83, 0x05,
886: 0x75, 0x40, 0x78, 0x48, 0x57, 0x29, 0x18, 0x41,
887: 0x86, 0x75, 0x07, 0x82, 0x02, 0xa0, 0x41, 0x2d,
888: 0x3b, 0x92, 0x93, 0x7d, 0x04, 0x79, 0x77, 0x7d,
889: 0xa4, 0x4b, 0x00, 0x6c, 0xa1, 0xb1, 0x8c, 0x7a,
890: 0x83, 0x48, 0x4d, 0x12, 0xa7, 0xa8, 0xb1, 0x37,
891: 0x83, 0x75, 0x04, 0x99, 0x9b, 0x73, 0xb9, 0x48,
892: 0x86, 0x6b, 0x01, 0x89, 0xc8, 0x75, 0x6b, 0x03,
893: 0xc0, 0x8e, 0x46, 0x35, 0x49, 0x94, 0x7c, 0x6c,
894: 0x95, 0xab, 0xcf, 0x7f, 0x36, 0x48, 0x6a, 0x88,
895: 0x05, 0x04, 0x05, 0x41, 0xde, 0x08, 0xb1, 0x44,
896: 0xda, 0x5f, 0xe7, 0x1e, 0xba, 0xe7, 0x4f, 0x11,
897: 0x00, 0x3b),
898: /*
899: * Sentinel.
900: */
901: WIRE_SENTINEL()
902: };
903:
1.3 ! christos 904: UNUSED(state);
1.1 christos 905:
1.3 ! christos 906: check_rdata(text_ok, wire_ok, NULL, false, dns_rdataclass_in,
1.1 christos 907: dns_rdatatype_doa, sizeof(dns_rdata_doa_t));
908: }
909:
910: /*
911: * EDNS Client Subnet tests.
912: *
913: * RFC 7871:
914: *
915: * 6. Option Format
916: *
917: * This protocol uses an EDNS0 [RFC6891] option to include client
918: * address information in DNS messages. The option is structured as
919: * follows:
920: *
921: * +0 (MSB) +1 (LSB)
922: * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
923: * 0: | OPTION-CODE |
924: * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
925: * 2: | OPTION-LENGTH |
926: * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
927: * 4: | FAMILY |
928: * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
929: * 6: | SOURCE PREFIX-LENGTH | SCOPE PREFIX-LENGTH |
930: * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
931: * 8: | ADDRESS... /
932: * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
933: *
934: * o (Defined in [RFC6891]) OPTION-CODE, 2 octets, for ECS is 8 (0x00
935: * 0x08).
936: *
937: * o (Defined in [RFC6891]) OPTION-LENGTH, 2 octets, contains the
938: * length of the payload (everything after OPTION-LENGTH) in octets.
939: *
940: * o FAMILY, 2 octets, indicates the family of the address contained in
941: * the option, using address family codes as assigned by IANA in
942: * Address Family Numbers [Address_Family_Numbers].
943: *
944: * The format of the address part depends on the value of FAMILY. This
945: * document only defines the format for FAMILY 1 (IPv4) and FAMILY 2
946: * (IPv6), which are as follows:
947: *
948: * o SOURCE PREFIX-LENGTH, an unsigned octet representing the leftmost
949: * number of significant bits of ADDRESS to be used for the lookup.
950: * In responses, it mirrors the same value as in the queries.
951: *
952: * o SCOPE PREFIX-LENGTH, an unsigned octet representing the leftmost
953: * number of significant bits of ADDRESS that the response covers.
954: * In queries, it MUST be set to 0.
955: *
956: * o ADDRESS, variable number of octets, contains either an IPv4 or
957: * IPv6 address, depending on FAMILY, which MUST be truncated to the
958: * number of bits indicated by the SOURCE PREFIX-LENGTH field,
959: * padding with 0 bits to pad to the end of the last octet needed.
960: *
961: * o A server receiving an ECS option that uses either too few or too
962: * many ADDRESS octets, or that has non-zero ADDRESS bits set beyond
963: * SOURCE PREFIX-LENGTH, SHOULD return FORMERR to reject the packet,
964: * as a signal to the software developer making the request to fix
965: * their implementation.
966: *
967: * All fields are in network byte order ("big-endian", per [RFC1700],
968: * Data Notation).
969: */
1.3 ! christos 970: static void
! 971: edns_client_subnet(void **state) {
1.1 christos 972: wire_ok_t wire_ok[] = {
973: /*
974: * Option code with no content.
975: */
976: WIRE_INVALID(0x00, 0x08, 0x00, 0x00),
977: /*
978: * Option code family 0, source 0, scope 0.
979: */
980: WIRE_VALID(0x00, 0x08, 0x00, 0x04,
981: 0x00, 0x00, 0x00, 0x00),
982: /*
983: * Option code family 1 (IPv4), source 0, scope 0.
984: */
985: WIRE_VALID(0x00, 0x08, 0x00, 0x04,
986: 0x00, 0x01, 0x00, 0x00),
987: /*
988: * Option code family 2 (IPv6) , source 0, scope 0.
989: */
990: WIRE_VALID(0x00, 0x08, 0x00, 0x04,
991: 0x00, 0x02, 0x00, 0x00),
992: /*
993: * Extra octet.
994: */
995: WIRE_INVALID(0x00, 0x08, 0x00, 0x05,
996: 0x00, 0x00, 0x00, 0x00,
997: 0x00),
998: /*
999: * Source too long for IPv4.
1000: */
1001: WIRE_INVALID(0x00, 0x08, 0x00, 8,
1002: 0x00, 0x01, 33, 0x00,
1003: 0x00, 0x00, 0x00, 0x00),
1004: /*
1005: * Source too long for IPv6.
1006: */
1007: WIRE_INVALID(0x00, 0x08, 0x00, 20,
1008: 0x00, 0x02, 129, 0x00,
1009: 0x00, 0x00, 0x00, 0x00,
1010: 0x00, 0x00, 0x00, 0x00,
1011: 0x00, 0x00, 0x00, 0x00,
1012: 0x00, 0x00, 0x00, 0x00),
1013: /*
1014: * Scope too long for IPv4.
1015: */
1016: WIRE_INVALID(0x00, 0x08, 0x00, 8,
1017: 0x00, 0x01, 0x00, 33,
1018: 0x00, 0x00, 0x00, 0x00),
1019: /*
1020: * Scope too long for IPv6.
1021: */
1022: WIRE_INVALID(0x00, 0x08, 0x00, 20,
1023: 0x00, 0x02, 0x00, 129,
1024: 0x00, 0x00, 0x00, 0x00,
1025: 0x00, 0x00, 0x00, 0x00,
1026: 0x00, 0x00, 0x00, 0x00,
1027: 0x00, 0x00, 0x00, 0x00),
1028: /*
1029: * When family=0, source and scope should be 0.
1030: */
1031: WIRE_VALID(0x00, 0x08, 0x00, 4,
1032: 0x00, 0x00, 0x00, 0x00),
1033: /*
1034: * When family=0, source and scope should be 0.
1035: */
1036: WIRE_INVALID(0x00, 0x08, 0x00, 5,
1037: 0x00, 0x00, 0x01, 0x00,
1038: 0x00),
1039: /*
1040: * When family=0, source and scope should be 0.
1041: */
1042: WIRE_INVALID(0x00, 0x08, 0x00, 5,
1043: 0x00, 0x00, 0x00, 0x01,
1044: 0x00),
1045: /*
1046: * Length too short for source IPv4.
1047: */
1048: WIRE_INVALID(0x00, 0x08, 0x00, 7,
1049: 0x00, 0x01, 32, 0x00,
1050: 0x00, 0x00, 0x00),
1051: /*
1052: * Length too short for source IPv6.
1053: */
1054: WIRE_INVALID(0x00, 0x08, 0x00, 19,
1055: 0x00, 0x02, 128, 0x00,
1056: 0x00, 0x00, 0x00, 0x00,
1057: 0x00, 0x00, 0x00, 0x00,
1058: 0x00, 0x00, 0x00, 0x00,
1059: 0x00, 0x00, 0x00),
1060: /*
1061: * Sentinel.
1062: */
1063: WIRE_SENTINEL()
1064: };
1065:
1.3 ! christos 1066: UNUSED(state);
1.1 christos 1067:
1.3 ! christos 1068: check_rdata(NULL, wire_ok, NULL, true, dns_rdataclass_in,
1.1 christos 1069: dns_rdatatype_opt, sizeof(dns_rdata_opt_t));
1070: }
1071:
1072: /*
1.3 ! christos 1073: * http://ana-3.lcs.mit.edu/~jnc/nimrod/dns.txt
! 1074: *
! 1075: * The RDATA portion of both the NIMLOC and EID records contains
! 1076: * uninterpreted binary data. The representation in the text master file
! 1077: * is an even number of hex characters (0 to 9, a to f), case is not
! 1078: * significant. For readability, whitespace may be included in the value
! 1079: * field and should be ignored when reading a master file.
1.1 christos 1080: */
1.3 ! christos 1081: static void
! 1082: eid(void **state) {
! 1083: text_ok_t text_ok[] = {
! 1084: TEXT_VALID("AABBCC"),
! 1085: TEXT_VALID_CHANGED("AA bb cc", "AABBCC"),
! 1086: TEXT_INVALID("aab"),
! 1087: /*
! 1088: * Sentinel.
! 1089: */
! 1090: TEXT_SENTINEL()
! 1091: };
! 1092: wire_ok_t wire_ok[] = {
! 1093: /*
! 1094: * Too short.
! 1095: */
! 1096: WIRE_INVALID(),
! 1097: WIRE_VALID(0x00),
! 1098: /*
! 1099: * Sentinel.
! 1100: */
! 1101: WIRE_SENTINEL()
! 1102: };
! 1103:
! 1104: UNUSED(state);
! 1105:
! 1106: check_rdata(text_ok, wire_ok, NULL, false, dns_rdataclass_in,
! 1107: dns_rdatatype_eid, sizeof(dns_rdata_in_eid_t));
1.1 christos 1108: }
1.3 ! christos 1109:
! 1110: /*
! 1111: * test that an oversized HIP record will be rejected
! 1112: */
! 1113: static void
! 1114: hip(void **state) {
1.1 christos 1115: unsigned char hipwire[DNS_RDATA_MAXLENGTH] = {
1116: 0x01, 0x00, 0x00, 0x01, 0x00, 0x00,
1117: 0x04, 0x41, 0x42, 0x43, 0x44, 0x00 };
1118: unsigned char buf[1024*1024];
1119: isc_buffer_t source, target;
1120: dns_rdata_t rdata;
1121: dns_decompress_t dctx;
1122: isc_result_t result;
1123: size_t i;
1124:
1.3 ! christos 1125: UNUSED(state);
1.1 christos 1126:
1127: /*
1128: * Fill the rest of input buffer with compression pointers.
1129: */
1130: for (i = 12; i < sizeof(hipwire) - 2; i += 2) {
1131: hipwire[i] = 0xc0;
1132: hipwire[i+1] = 0x06;
1133: }
1134:
1135: isc_buffer_init(&source, hipwire, sizeof(hipwire));
1136: isc_buffer_add(&source, sizeof(hipwire));
1137: isc_buffer_setactive(&source, i);
1138: isc_buffer_init(&target, buf, sizeof(buf));
1139: dns_rdata_init(&rdata);
1140: dns_decompress_init(&dctx, -1, DNS_DECOMPRESS_ANY);
1141: result = dns_rdata_fromwire(&rdata, dns_rdataclass_in,
1142: dns_rdatatype_hip, &source, &dctx,
1143: 0, &target);
1144: dns_decompress_invalidate(&dctx);
1.3 ! christos 1145: assert_int_equal(result, DNS_R_FORMERR);
1.1 christos 1146: }
1147:
1148: /*
1149: * ISDN tests.
1150: *
1151: * RFC 1183:
1152: *
1153: * 3.2. The ISDN RR
1154: *
1155: * The ISDN RR is defined with mnemonic ISDN and type code 20 (decimal).
1156: *
1157: * An ISDN (Integrated Service Digital Network) number is simply a
1158: * telephone number. The intent of the members of the CCITT is to
1159: * upgrade all telephone and data network service to a common service.
1160: *
1161: * The numbering plan (E.163/E.164) is the same as the familiar
1162: * international plan for POTS (an un-official acronym, meaning Plain
1163: * Old Telephone Service). In E.166, CCITT says "An E.163/E.164
1164: * telephony subscriber may become an ISDN subscriber without a number
1165: * change."
1166: *
1167: * ISDN has the following format:
1168: *
1169: * <owner> <ttl> <class> ISDN <ISDN-address> <sa>
1170: *
1171: * The <ISDN-address> field is required; <sa> is optional.
1172: *
1173: * <ISDN-address> identifies the ISDN number of <owner> and DDI (Direct
1174: * Dial In) if any, as defined by E.164 [8] and E.163 [7], the ISDN and
1175: * PSTN (Public Switched Telephone Network) numbering plan. E.163
1176: * defines the country codes, and E.164 the form of the addresses. Its
1177: * format in master files is a <character-string> syntactically
1178: * identical to that used in TXT and HINFO.
1179: *
1180: * <sa> specifies the subaddress (SA). The format of <sa> in master
1181: * files is a <character-string> syntactically identical to that used in
1182: * TXT and HINFO.
1183: *
1184: * The format of ISDN is class insensitive. ISDN RRs cause no
1185: * additional section processing.
1186: *
1187: * The <ISDN-address> is a string of characters, normally decimal
1188: * digits, beginning with the E.163 country code and ending with the DDI
1189: * if any. Note that ISDN, in Q.931, permits any IA5 character in the
1190: * general case.
1191: *
1192: * The <sa> is a string of hexadecimal digits. For digits 0-9, the
1193: * concrete encoding in the Q.931 call setup information element is
1194: * identical to BCD.
1195: *
1196: * For example:
1197: *
1198: * Relay.Prime.COM. IN ISDN 150862028003217
1199: * sh.Prime.COM. IN ISDN 150862028003217 004
1200: *
1201: * (Note: "1" is the country code for the North American Integrated
1202: * Numbering Area, i.e., the system of "area codes" familiar to people
1203: * in those countries.)
1204: *
1205: * The RR data is the ASCII representation of the digits. It is encoded
1206: * as one or two <character-string>s, i.e., count followed by
1207: * characters.
1208: */
1.3 ! christos 1209: static void
! 1210: isdn(void **state) {
1.1 christos 1211: wire_ok_t wire_ok[] = {
1212: /*
1213: * "".
1214: */
1215: WIRE_VALID(0x00),
1216: /*
1217: * "\001".
1218: */
1219: WIRE_VALID(0x01, 0x01),
1220: /*
1221: * "\001" "".
1222: */
1223: WIRE_VALID(0x01, 0x01, 0x00),
1224: /*
1225: * "\001" "\001".
1226: */
1227: WIRE_VALID(0x01, 0x01, 0x01, 0x01),
1228: /*
1229: * Sentinel.
1230: */
1231: WIRE_SENTINEL()
1232: };
1233:
1.3 ! christos 1234: UNUSED(state);
1.1 christos 1235:
1.3 ! christos 1236: check_rdata(NULL, wire_ok, NULL, false, dns_rdataclass_in,
1.1 christos 1237: dns_rdatatype_isdn, sizeof(dns_rdata_isdn_t));
1238: }
1239:
1240: /*
1.3 ! christos 1241: * http://ana-3.lcs.mit.edu/~jnc/nimrod/dns.txt
! 1242: *
! 1243: * The RDATA portion of both the NIMLOC and EID records contains
! 1244: * uninterpreted binary data. The representation in the text master file
! 1245: * is an even number of hex characters (0 to 9, a to f), case is not
! 1246: * significant. For readability, whitespace may be included in the value
! 1247: * field and should be ignored when reading a master file.
! 1248: */
! 1249: static void
! 1250: nimloc(void **state) {
! 1251: text_ok_t text_ok[] = {
! 1252: TEXT_VALID("AABBCC"),
! 1253: TEXT_VALID_CHANGED("AA bb cc", "AABBCC"),
! 1254: TEXT_INVALID("aab"),
! 1255: /*
! 1256: * Sentinel.
! 1257: */
! 1258: TEXT_SENTINEL()
! 1259: };
! 1260: wire_ok_t wire_ok[] = {
! 1261: /*
! 1262: * Too short.
! 1263: */
! 1264: WIRE_INVALID(),
! 1265: WIRE_VALID(0x00),
! 1266: /*
! 1267: * Sentinel.
! 1268: */
! 1269: WIRE_SENTINEL()
! 1270: };
! 1271:
! 1272: UNUSED(state);
! 1273:
! 1274: check_rdata(text_ok, wire_ok, NULL, false, dns_rdataclass_in,
! 1275: dns_rdatatype_nimloc, sizeof(dns_rdata_in_nimloc_t));
! 1276: }
! 1277:
! 1278: /*
1.1 christos 1279: * NSEC tests.
1280: *
1281: * RFC 4034:
1282: *
1283: * 4.1. NSEC RDATA Wire Format
1284: *
1285: * The RDATA of the NSEC RR is as shown below:
1286: *
1287: * 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
1288: * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1289: * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1290: * / Next Domain Name /
1291: * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1292: * / Type Bit Maps /
1293: * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1294: *
1295: * 4.1.1. The Next Domain Name Field
1296: *
1297: * The Next Domain field contains the next owner name (in the canonical
1298: * ordering of the zone) that has authoritative data or contains a
1299: * delegation point NS RRset; see Section 6.1 for an explanation of
1300: * canonical ordering. The value of the Next Domain Name field in the
1301: * last NSEC record in the zone is the name of the zone apex (the owner
1302: * name of the zone's SOA RR). This indicates that the owner name of
1303: * the NSEC RR is the last name in the canonical ordering of the zone.
1304: *
1305: * A sender MUST NOT use DNS name compression on the Next Domain Name
1306: * field when transmitting an NSEC RR.
1307: *
1308: * Owner names of RRsets for which the given zone is not authoritative
1309: * (such as glue records) MUST NOT be listed in the Next Domain Name
1310: * unless at least one authoritative RRset exists at the same owner
1311: * name.
1312: *
1313: * 4.1.2. The Type Bit Maps Field
1314: *
1315: * The Type Bit Maps field identifies the RRset types that exist at the
1316: * NSEC RR's owner name.
1317: *
1318: * The RR type space is split into 256 window blocks, each representing
1319: * the low-order 8 bits of the 16-bit RR type space. Each block that
1320: * has at least one active RR type is encoded using a single octet
1321: * window number (from 0 to 255), a single octet bitmap length (from 1
1322: * to 32) indicating the number of octets used for the window block's
1323: * bitmap, and up to 32 octets (256 bits) of bitmap.
1324: *
1325: * Blocks are present in the NSEC RR RDATA in increasing numerical
1326: * order.
1327: *
1328: * Type Bit Maps Field = ( Window Block # | Bitmap Length | Bitmap )+
1329: *
1330: * where "|" denotes concatenation.
1331: *
1332: * Each bitmap encodes the low-order 8 bits of RR types within the
1333: * window block, in network bit order. The first bit is bit 0. For
1334: * window block 0, bit 1 corresponds to RR type 1 (A), bit 2 corresponds
1335: * to RR type 2 (NS), and so forth. For window block 1, bit 1
1336: * corresponds to RR type 257, and bit 2 to RR type 258. If a bit is
1337: * set, it indicates that an RRset of that type is present for the NSEC
1338: * RR's owner name. If a bit is clear, it indicates that no RRset of
1339: * that type is present for the NSEC RR's owner name.
1340: *
1341: * Bits representing pseudo-types MUST be clear, as they do not appear
1342: * in zone data. If encountered, they MUST be ignored upon being read.
1343: */
1.3 ! christos 1344: static void
! 1345: nsec(void **state) {
1.1 christos 1346: text_ok_t text_ok[] = {
1347: TEXT_INVALID(""),
1348: TEXT_INVALID("."),
1349: TEXT_VALID(". RRSIG"),
1350: TEXT_SENTINEL()
1351: };
1352: wire_ok_t wire_ok[] = {
1353: WIRE_INVALID(0x00),
1354: WIRE_INVALID(0x00, 0x00),
1355: WIRE_INVALID(0x00, 0x00, 0x00),
1356: WIRE_VALID(0x00, 0x00, 0x01, 0x02),
1357: WIRE_INVALID()
1358: };
1359:
1.3 ! christos 1360: UNUSED(state);
1.1 christos 1361:
1.3 ! christos 1362: check_rdata(text_ok, wire_ok, NULL, false, dns_rdataclass_in,
1.1 christos 1363: dns_rdatatype_nsec, sizeof(dns_rdata_nsec_t));
1364: }
1365:
1366: /*
1367: * NSEC3 tests.
1368: *
1369: * RFC 5155.
1370: */
1.3 ! christos 1371: static void
! 1372: nsec3(void **state) {
1.1 christos 1373: text_ok_t text_ok[] = {
1374: TEXT_INVALID(""),
1375: TEXT_INVALID("."),
1376: TEXT_INVALID(". RRSIG"),
1377: TEXT_INVALID("1 0 10 76931F"),
1378: TEXT_INVALID("1 0 10 76931F IMQ912BREQP1POLAH3RMONG;UED541AS"),
1379: TEXT_INVALID("1 0 10 76931F IMQ912BREQP1POLAH3RMONG;UED541AS A RRSIG"),
1380: TEXT_VALID("1 0 10 76931F AJHVGTICN6K0VDA53GCHFMT219SRRQLM A RRSIG"),
1381: TEXT_VALID("1 0 10 76931F AJHVGTICN6K0VDA53GCHFMT219SRRQLM"),
1382: TEXT_VALID("1 0 10 - AJHVGTICN6K0VDA53GCHFMT219SRRQLM"),
1383: TEXT_SENTINEL()
1384: };
1385:
1.3 ! christos 1386: UNUSED(state);
1.1 christos 1387:
1.3 ! christos 1388: check_rdata(text_ok, NULL, NULL, false, dns_rdataclass_in,
1.1 christos 1389: dns_rdatatype_nsec3, sizeof(dns_rdata_nsec3_t));
1390: }
1391:
1.3 ! christos 1392: /* NXT RDATA manipulations */
! 1393: static void
! 1394: nxt(void **state) {
! 1395: compare_ok_t compare_ok[] = {
! 1396: COMPARE("a. A SIG", "a. A SIG", 0),
! 1397: /*
! 1398: * Records that differ only in the case of the next
! 1399: * name should be equal.
! 1400: */
! 1401: COMPARE("A. A SIG", "a. A SIG", 0),
! 1402: /*
! 1403: * Sorting on name field.
! 1404: */
! 1405: COMPARE("A. A SIG", "b. A SIG", -1),
! 1406: COMPARE("b. A SIG", "A. A SIG", 1),
! 1407: /* bit map differs */
! 1408: COMPARE("b. A SIG", "b. A AAAA SIG", -1),
! 1409: /* order of bit map does not matter */
! 1410: COMPARE("b. A SIG AAAA", "b. A AAAA SIG", 0),
! 1411: COMPARE_SENTINEL()
! 1412: };
! 1413:
! 1414: UNUSED(state);
! 1415:
! 1416: check_rdata(NULL, NULL, compare_ok, false, dns_rdataclass_in,
! 1417: dns_rdatatype_nxt, sizeof(dns_rdata_nxt_t));
! 1418: }
! 1419:
1.1 christos 1420: /*
1421: * WKS tests.
1422: *
1423: * RFC 1035:
1424: *
1425: * 3.4.2. WKS RDATA format
1426: *
1427: * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
1428: * | ADDRESS |
1429: * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
1430: * | PROTOCOL | |
1431: * +--+--+--+--+--+--+--+--+ |
1432: * | |
1433: * / <BIT MAP> /
1434: * / /
1435: * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
1436: *
1437: * where:
1438: *
1439: * ADDRESS An 32 bit Internet address
1440: *
1441: * PROTOCOL An 8 bit IP protocol number
1442: *
1443: * <BIT MAP> A variable length bit map. The bit map must be a
1444: * multiple of 8 bits long.
1445: *
1446: * The WKS record is used to describe the well known services supported by
1447: * a particular protocol on a particular internet address. The PROTOCOL
1448: * field specifies an IP protocol number, and the bit map has one bit per
1449: * port of the specified protocol. The first bit corresponds to port 0,
1450: * the second to port 1, etc. If the bit map does not include a bit for a
1451: * protocol of interest, that bit is assumed zero. The appropriate values
1452: * and mnemonics for ports and protocols are specified in [RFC-1010].
1453: *
1454: * For example, if PROTOCOL=TCP (6), the 26th bit corresponds to TCP port
1455: * 25 (SMTP). If this bit is set, a SMTP server should be listening on TCP
1456: * port 25; if zero, SMTP service is not supported on the specified
1457: * address.
1458: */
1.3 ! christos 1459: static void
! 1460: wks(void **state) {
! 1461: text_ok_t text_ok[] = {
! 1462: /*
! 1463: * Valid, IPv4 address in dotted-quad form.
! 1464: */
! 1465: TEXT_VALID("127.0.0.1 6"),
! 1466: /*
! 1467: * Invalid, IPv4 address not in dotted-quad form.
! 1468: */
! 1469: TEXT_INVALID("127.1 6"),
! 1470: /*
! 1471: * Sentinel.
! 1472: */
! 1473: TEXT_SENTINEL()
! 1474: };
1.1 christos 1475: wire_ok_t wire_ok[] = {
1476: /*
1477: * Too short.
1478: */
1479: WIRE_INVALID(0x00, 0x08, 0x00, 0x00),
1480: /*
1481: * Minimal TCP.
1482: */
1483: WIRE_VALID(0x00, 0x08, 0x00, 0x00, 6),
1484: /*
1485: * Minimal UDP.
1486: */
1487: WIRE_VALID(0x00, 0x08, 0x00, 0x00, 17),
1488: /*
1489: * Minimal other.
1490: */
1491: WIRE_VALID(0x00, 0x08, 0x00, 0x00, 1),
1492: /*
1493: * Sentinel.
1494: */
1495: WIRE_SENTINEL()
1496: };
1497:
1.3 ! christos 1498: UNUSED(state);
1.1 christos 1499:
1.3 ! christos 1500: check_rdata(text_ok, wire_ok, NULL, false, dns_rdataclass_in,
1.1 christos 1501: dns_rdatatype_wks, sizeof(dns_rdata_in_wks_t));
1502: }
1503:
1.3 ! christos 1504: int
! 1505: main(void) {
! 1506: const struct CMUnitTest tests[] = {
! 1507: cmocka_unit_test_setup_teardown(apl, _setup, _teardown),
! 1508: cmocka_unit_test_setup_teardown(atma, _setup, _teardown),
! 1509: cmocka_unit_test_setup_teardown(csync, _setup, _teardown),
! 1510: cmocka_unit_test_setup_teardown(doa, _setup, _teardown),
! 1511: cmocka_unit_test_setup_teardown(eid, _setup, _teardown),
! 1512: cmocka_unit_test_setup_teardown(edns_client_subnet,
! 1513: _setup, _teardown),
! 1514: cmocka_unit_test_setup_teardown(hip, _setup, _teardown),
! 1515: cmocka_unit_test_setup_teardown(isdn, _setup, _teardown),
! 1516: cmocka_unit_test_setup_teardown(nimloc, _setup, _teardown),
! 1517: cmocka_unit_test_setup_teardown(nsec, _setup, _teardown),
! 1518: cmocka_unit_test_setup_teardown(nsec3, _setup, _teardown),
! 1519: cmocka_unit_test_setup_teardown(nxt, _setup, _teardown),
! 1520: cmocka_unit_test_setup_teardown(wks, _setup, _teardown),
! 1521: };
! 1522:
! 1523: return (cmocka_run_group_tests(tests, NULL, NULL));
! 1524: }
1.1 christos 1525:
1.3 ! christos 1526: #else /* HAVE_CMOCKA */
! 1527:
! 1528: #include <stdio.h>
! 1529:
! 1530: int
! 1531: main(void) {
! 1532: printf("1..0 # Skipped: cmocka not available\n");
! 1533: return (0);
1.1 christos 1534: }
1.3 ! christos 1535:
! 1536: #endif
CVSweb <webmaster@jp.NetBSD.org>