26#include <freeradius-devel/util/value.h>
27#include <freeradius-devel/util/dns.h>
42 lb->
end = packet + packet_len;
77 slen =
encode_label(buf,
sizeof(buf), buf,
"",
false, NULL);
88 slen =
encode_label(buf,
sizeof(buf), buf,
".",
false, NULL);
99 slen =
encode_label(buf,
sizeof(buf), buf,
"com",
false, NULL);
101 TEST_MSG(
"Expected 5, got %zd", slen);
113 slen =
encode_label(buf,
sizeof(buf), buf,
"www.example.com",
false, NULL);
115 TEST_MSG(
"Expected 17, got %zd", slen);
119 TEST_CHECK(memcmp(buf + 5,
"example", 7) == 0);
131 slen =
encode_label(buf,
sizeof(buf), buf,
"example.com.",
false, NULL);
133 TEST_MSG(
"Expected 13, got %zd", slen);
146 slen =
encode_label(buf,
sizeof(buf), buf,
"_srv.example.com",
false, NULL);
148 TEST_MSG(
"Expected >0, got %zd", slen);
191 slen =
encode_label(buf,
sizeof(buf), buf,
"hello world",
false, NULL);
195 slen =
encode_label(buf,
sizeof(buf), buf,
"user@host",
false, NULL);
199 slen =
encode_label(buf,
sizeof(buf), buf,
"a\tb",
false, NULL);
208 slen =
encode_label(buf,
sizeof(buf), buf,
"www..example.com",
false, NULL);
217 slen =
encode_label(buf,
sizeof(buf), buf,
".example.com",
false, NULL);
228 memset(label,
'a', 64);
230 slen =
encode_label(buf,
sizeof(buf), buf, label,
false, NULL);
244 TEST_MSG(
"need=%zu, buf_len=%zu", need,
sizeof(buf));
270 pkt[13] =
'c'; pkt[14] =
'o'; pkt[15] =
'm';
276 TEST_MSG(
"Expected 3, got %zd", slen);
287 pkt[12] = 3; memcpy(pkt + 13,
"www", 3);
288 pkt[16] = 7; memcpy(pkt + 17,
"example", 7);
289 pkt[24] = 3; memcpy(pkt + 25,
"com", 3);
295 TEST_MSG(
"Expected 15, got %zd", slen);
311 TEST_MSG(
"Expected 1, got %zd", slen);
322 pkt[12] = 3; pkt[13] =
'c'; pkt[14] =
'o'; pkt[15] =
'm'; pkt[16] = 0x00;
323 pkt[17] = 3; pkt[18] =
'f'; pkt[19] =
'o'; pkt[20] =
'o';
324 pkt[21] = 0xc0; pkt[22] = 0x0c;
332 TEST_MSG(
"Expected 7, got %zd", slen);
343 pkt[12] = 0xc0; pkt[13] = 17;
344 pkt[14] = 3; pkt[15] =
'c'; pkt[16] =
'o'; pkt[17] =
'm'; pkt[18] = 0x00;
349 TEST_MSG(
"Forward pointer should be rejected, got %zd", slen);
359 pkt[12] = 0xc0; pkt[13] = 12;
364 TEST_MSG(
"Self-pointer should be rejected, got %zd", slen);
374 pkt[12] = 3; pkt[13] =
'c'; pkt[14] =
'o'; pkt[15] =
'm'; pkt[16] = 0x00;
375 pkt[17] = 0xc0; pkt[18] = 0x0c;
376 pkt[19] = 0xc0; pkt[20] = 0x11;
381 TEST_MSG(
"Pointer-to-pointer should be rejected, got %zd", slen);
391 pkt[12] = 0x80; pkt[13] = 0x00;
396 TEST_MSG(
"0x80 high bits should be rejected, got %zd", slen);
407 pkt[13] =
'a'; pkt[14] =
'b'; pkt[15] =
'c';
412 TEST_MSG(
"Overflow should be rejected, got %zd", slen);
434 memset(pkt, 0,
sizeof(pkt));
447 pkt[12] = 3; pkt[13] =
'a'; pkt[14] =
' '; pkt[15] =
'b';
452 TEST_MSG(
"Invalid char in label should be rejected, got %zd", slen);
465 for (i = 0; i < 5; i++) {
475 TEST_MSG(
"Total length > 255 should be rejected, got %zd", slen);
488 pkt[12] = 3; pkt[13] =
'c'; pkt[14] =
'o'; pkt[15] =
'm'; pkt[16] = 0x00;
492 TEST_MSG(
"Expected >0, got %zd", slen);
514 TALLOC_CTX *ctx = talloc_init(
"test");
518 enc_len =
encode_label(buf,
sizeof(buf), buf,
"example.com",
false, NULL);
520 TEST_MSG(
"encode returned %zd", enc_len);
521 if (enc_len <= 0)
return;
525 TEST_MSG(
"decode returned %zd", dec_len);
528 TEST_CHECK(strcmp(vb_out.vb_strvalue,
"example.com") == 0);
529 TEST_MSG(
"Expected 'example.com', got '%s'", vb_out.vb_strvalue);
538 TALLOC_CTX *ctx = talloc_init(
"test");
542 enc_len =
encode_label(buf,
sizeof(buf), buf,
"example.com.",
false, NULL);
544 if (enc_len <= 0)
return;
549 TEST_CHECK(strcmp(vb_out.vb_strvalue,
"example.com") == 0);
550 TEST_MSG(
"Expected 'example.com', got '%s'", vb_out.vb_strvalue);
559 TALLOC_CTX *ctx = talloc_init(
"test");
563 enc_len =
encode_label(buf,
sizeof(buf), buf,
".",
false, NULL);
565 if (enc_len <= 0)
return;
570 TEST_CHECK(strcmp(vb_out.vb_strvalue,
".") == 0);
571 TEST_MSG(
"Expected '.', got '%s'", vb_out.vb_strvalue);
580 TALLOC_CTX *ctx = talloc_init(
"test");
584 enc_len =
encode_label(buf,
sizeof(buf), buf,
"_tcp.example.com",
false, NULL);
586 if (enc_len <= 0)
return;
590 TEST_CHECK(strcmp(vb_out.vb_strvalue,
"_tcp.example.com") == 0);
591 TEST_MSG(
"Expected '_tcp.example.com', got '%s'", vb_out.vb_strvalue);
600 TALLOC_CTX *ctx = talloc_init(
"test");
604 enc_len =
encode_label(buf,
sizeof(buf), buf,
"WWW.Example.COM",
false, NULL);
606 if (enc_len <= 0)
return;
610 TEST_CHECK(strcmp(vb_out.vb_strvalue,
"WWW.Example.COM") == 0);
611 TEST_MSG(
"Expected 'WWW.Example.COM', got '%s'", vb_out.vb_strvalue);
631 TEST_MSG(
"First encode: %zd", slen1);
635 TEST_MSG(
"Second encode: %zd", slen2);
642 TEST_MSG(
"Compressed size %zd should be < 17", slen2);
684 TEST_MSG(
"encode returned %zd", slen);
697 pkt[12] = 3; pkt[13] =
'c'; pkt[14] =
'o'; pkt[15] =
'm'; pkt[16] = 0x00;
698 pkt[17] = 3; pkt[18] =
'f'; pkt[19] =
'o'; pkt[20] =
'o';
699 pkt[21] = 0xc0; pkt[22] = 0x0c;
704 TEST_MSG(
"Expected 7, got %zd", slen);
715 pkt[12] = 3; pkt[13] =
'c'; pkt[14] =
'o'; pkt[15] =
'm'; pkt[16] = 0x00;
716 pkt[17] = 3; pkt[18] =
'f'; pkt[19] =
'o'; pkt[20] =
'o';
717 pkt[21] = 0xc0; pkt[22] = 0x0c;
725 TEST_MSG(
"Unmarked pointer target should be rejected, got %zd", slen);
735 pkt[12] = 3; pkt[13] =
'c'; pkt[14] =
'o'; pkt[15] =
'm'; pkt[16] = 0x00;
736 pkt[17] = 0xc0; pkt[18] = 0x10;
741 TEST_MSG(
"Pointer to 0x00 should be rejected, got %zd", slen);
754 memset(label,
'a', 63);
756 slen =
encode_label(buf,
sizeof(buf), buf, label,
false, NULL);
758 TEST_MSG(
"Expected 65, got %zd", slen);
766 slen =
encode_label(buf,
sizeof(buf), buf,
"my-host-01.example.com",
false, NULL);
768 TEST_MSG(
"Expected >0, got %zd", slen);
782 TALLOC_CTX *ctx = talloc_init(
"test");
795 slen1 + slen2, &next_label, &lb);
797 TEST_MSG(
"Expected 15, got %zd", uncomp_len);
803 TEST_CHECK(strcmp(vb_out.vb_strvalue,
"foo.example.com") == 0);
804 TEST_MSG(
"Expected 'foo.example.com', got '%s'", vb_out.vb_strvalue);
830 TALLOC_CTX *ctx = talloc_init(
"test");
831 char const *name1 =
"bar.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
832 char const *name2 =
"foo.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
843 TEST_MSG(
"First encode: %zd", slen1);
853 TEST_MSG(
"62-byte label compression: %zd (expected < 68)", slen2);
862 TEST_CHECK(strcmp(vb_out.vb_strvalue, name2) == 0);
863 TEST_MSG(
"Expected '%s', got '%s'", name2, vb_out.vb_strvalue);
874 TALLOC_CTX *ctx = talloc_init(
"test");
883 memset(long63,
'a', 63);
890 TEST_MSG(
"First encode: %zd", slen1);
896 TEST_MSG(
"63-byte duplicate compression: %zd (expected 2)", slen2);
905 TEST_CHECK(strcmp(vb_out.vb_strvalue, long63) == 0);
906 TEST_MSG(
"Expected '%s', got '%s'", long63, vb_out.vb_strvalue);
923 char const *name1 =
"bar.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.com";
924 char const *name2 =
"foo.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.com";
934 TEST_MSG(
"First encode: %zd", slen1);
944 TEST_MSG(
"Compressed size %zd should be < %zd", slen2, slen1);
952 TALLOC_CTX *ctx = talloc_init(
"test");
953 char const *
name =
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.com";
971 TEST_MSG(
"First encode: %zd", slen1);
977 TEST_MSG(
"Compressed size %zd (expected 2)", slen2);
987 TEST_MSG(
"Expected '%s', got '%s'",
name, vb_out.vb_strvalue);
ssize_t fr_dns_label_uncompressed_length(uint8_t const *packet, uint8_t const *buf, size_t buf_len, uint8_t const **next, fr_dns_labels_t *lb)
Get the uncompressed length of a DNS label in a network buffer.
ssize_t fr_dns_label_from_value_box(size_t *need, uint8_t *buf, size_t buf_len, uint8_t *where, bool compression, fr_value_box_t const *value, fr_dns_labels_t *lb)
Encode a single value box of type string, serializing its contents to a dns label.
ssize_t fr_dns_labels_network_verify(uint8_t const *packet, uint8_t const *buf, size_t buf_len, uint8_t const *start, fr_dns_labels_t *lb)
Verify that a network buffer contains valid DNS labels.
ssize_t fr_dns_label_to_value_box(TALLOC_CTX *ctx, fr_value_box_t *dst, uint8_t const *src, size_t len, uint8_t const *label, bool tainted, fr_dns_labels_t *lb)
Decode a fr_value_box_t from one DNS label.
static void test_encode_multi_label(void)
static void test_roundtrip_simple(void)
static void test_encode_underscore_prefix(void)
static void test_decode_self_pointer_rejected(void)
static void test_encode_buffer_too_small(void)
static void test_roundtrip_compressed(void)
static void test_encode_root_dot(void)
static void test_encode_where_outside_buf(void)
static void test_encode_double_dot(void)
static void test_decode_pointer_to_pointer_rejected(void)
static void test_encode_label_too_long(void)
static void labels_init(fr_dns_labels_t *lb, uint8_t const *packet, size_t packet_len, bool use_mark)
static void test_encode_max_label_length(void)
static void test_compress_middle_63_byte_label(void)
static void test_verify_empty(void)
static void test_decode_to_value_box_zero_len(void)
static fr_dns_block_t test_blocks[256]
static void test_encode_null_inputs(void)
static void test_compress_two_names(void)
static void test_compress_63_byte_label(void)
static void test_decode_compressed_pointer(void)
static void test_encode_non_string_type(void)
static void test_decode_label_invalid_chars(void)
static void test_encode_trailing_dot(void)
static void test_decode_label_overflow(void)
static void test_pointer_invalid_with_mark_tracking(void)
static void test_roundtrip_root(void)
static void test_labels_block_tracking(void)
static void test_encode_leading_dot(void)
static void test_verify_simple(void)
static void test_encode_invalid_chars(void)
static void test_decode_root_label(void)
static void test_compress_62_byte_label(void)
static void test_decode_forward_pointer_rejected(void)
static ssize_t encode_label(uint8_t *buf, size_t buf_len, uint8_t *where, char const *str, bool compression, fr_dns_labels_t *lb)
static void test_decode_to_value_box_label_outside_buf(void)
static void test_compress_middle_62_byte_label(void)
static void test_pointer_valid_no_tracking(void)
static void test_roundtrip_trailing_dot(void)
static uint8_t test_marker[65536]
static void test_pointer_to_zero_label_rejected(void)
static void test_encode_empty_string(void)
static void test_encode_hyphen_and_digits(void)
static void test_decode_total_length_exceeds_255(void)
static void test_decode_null_inputs(void)
static void test_decode_invalid_high_bits(void)
static void test_roundtrip_case_preservation(void)
static void test_roundtrip_underscore(void)
static void test_decode_simple_label(void)
static void test_decode_multi_label(void)
static void test_encode_simple_label(void)
uint8_t const * start
start of packet
uint8_t const * end
end of the packet
fr_dns_block_t * blocks
maximum number of labels
uint8_t * mark
markup buffer used for decoding.
int num
number of used labels
@ FR_TYPE_STRING
String of printable characters.
void fr_value_box_clear(fr_value_box_t *data)
Clear/free any existing value and metadata.
#define fr_value_box_init_null(_vb)
Initialise an empty/null box that will be filled later.
#define fr_box_strvalue(_val)