@@ -28,6 +28,7 @@ LOG_MODULE_REGISTER(net_test, CONFIG_DNS_RESOLVER_LOG_LEVEL);
2828
2929#define NET_LOG_ENABLED 1
3030#include "net_private.h"
31+ #include "dns_pack.h"
3132
3233#if defined(CONFIG_DNS_RESOLVER_LOG_LEVEL_DBG )
3334#define DBG (fmt , ...) printk(fmt, ##__VA_ARGS__)
@@ -909,4 +910,143 @@ ZTEST(dns_resolve, test_dns_localhost_resolve_ipv6)
909910 0 , "not loopback address" );
910911}
911912
913+ NET_BUF_POOL_DEFINE (test_dns_qname_pool , 2 , CONFIG_DNS_RESOLVER_MAX_QUERY_LEN ,
914+ 0 , NULL );
915+
916+ ZTEST (dns_resolve , test_dns_unpack_name )
917+ {
918+ /* NULL string terminator serves a role of a final zero-length label */
919+ static const uint8_t * test_records [] = {
920+ /* example.com */
921+ "\007example\003com" ,
922+ /* www.zephyrproject.org */
923+ "\003www\015zephyrproject\003org" ,
924+ /* These records should barely fit (fills up the buffer size limit). */
925+ "\077very_long_record_that_has_a_length_of_63_bytes_xxxxxxxxxxxxxxxx"
926+ "\077very_long_record_that_has_a_length_of_63_bytes_xxxxxxxxxxxxxxxx"
927+ "\077very_long_record_that_has_a_length_of_63_bytes_xxxxxxxxxxxxxxxx"
928+ "\076very_long_record_that_has_a_length_of_62_bytes_xxxxxxxxxxxxxxx" ,
929+ };
930+ static const uint8_t * expected_names [] = {
931+ "example.com" ,
932+ "www.zephyrproject.org" ,
933+ "very_long_record_that_has_a_length_of_63_bytes_xxxxxxxxxxxxxxxx."
934+ "very_long_record_that_has_a_length_of_63_bytes_xxxxxxxxxxxxxxxx."
935+ "very_long_record_that_has_a_length_of_63_bytes_xxxxxxxxxxxxxxxx."
936+ "very_long_record_that_has_a_length_of_62_bytes_xxxxxxxxxxxxxxx" ,
937+
938+ };
939+ struct net_buf * result ;
940+ int ret ;
941+
942+ zassert_equal (CONFIG_DNS_RESOLVER_MAX_QUERY_LEN , 255 , "Invalid test configuration" );
943+
944+ for (int i = 0 ; i < ARRAY_SIZE (test_records ); i ++ ) {
945+ const uint8_t * end_of_label = NULL ;
946+
947+ result = net_buf_alloc (& test_dns_qname_pool , K_NO_WAIT );
948+ zassert_not_null (result , "Failed to allocate buffer" );
949+
950+ /* +1 to include NULL as terminating label */
951+ ret = dns_unpack_name (test_records [i ], strlen (test_records [i ]) + 1 ,
952+ test_records [i ], result , & end_of_label );
953+ zassert_equal (ret , strlen (expected_names [i ]),
954+ "Error parsing records (%d)" , ret );
955+ zassert_str_equal (expected_names [i ], result -> data ,
956+ "Parsed wrong name (%s)" , result -> data );
957+ zassert_equal_ptr (test_records [i ] + strlen (test_records [i ]) + 1 ,
958+ end_of_label , "Wrong end of label" );
959+
960+ net_buf_unref (result );
961+ }
962+ }
963+
964+ ZTEST (dns_resolve , test_dns_unpack_name_with_pointer )
965+ {
966+ static const uint8_t test_records [] = {
967+ /* www.example.com followed by ftp.example.com with pointer */
968+ "\003www\007example\003com\000\003ftp\300\004" /* Last two bytes are pointer */
969+ };
970+ static const uint8_t * expected_names [] = {
971+ "www.example.com" ,
972+ "ftp.example.com" ,
973+ };
974+ const size_t offset_2nd_rec = 17 ;
975+ const uint8_t * end_of_label = NULL ;
976+ struct net_buf * result ;
977+ int ret ;
978+
979+ /* First name */
980+ result = net_buf_alloc (& test_dns_qname_pool , K_NO_WAIT );
981+ zassert_not_null (result , "Failed to allocate buffer" );
982+
983+ ret = dns_unpack_name (test_records , sizeof (test_records ),
984+ test_records , result , & end_of_label );
985+ zassert_equal (ret , strlen (expected_names [0 ]),
986+ "Error parsing records (%d)" , ret );
987+ zassert_str_equal (expected_names [0 ], result -> data ,
988+ "Parsed wrong name (%s)" , result -> data );
989+ zassert_equal_ptr (test_records + offset_2nd_rec , end_of_label ,
990+ "Wrong end of label" );
991+
992+ net_buf_unref (result );
993+
994+ /* Second name with a pointer within */
995+ end_of_label = NULL ;
996+
997+ result = net_buf_alloc (& test_dns_qname_pool , K_NO_WAIT );
998+ zassert_not_null (result , "Failed to allocate buffer" );
999+
1000+ ret = dns_unpack_name (test_records , sizeof (test_records ),
1001+ test_records + offset_2nd_rec , result , & end_of_label );
1002+ zassert_equal (ret , strlen (expected_names [1 ]),
1003+ "Error parsing records (%d)" , ret );
1004+ zassert_str_equal (expected_names [1 ], result -> data ,
1005+ "Parsed wrong name (%s)" , result -> data );
1006+ /* -1 as end_of_label should point to the last byte in the buffer (pointer offset) */
1007+ zassert_equal_ptr (test_records + sizeof (test_records ) - 1 , end_of_label ,
1008+ "Wrong end of label" );
1009+
1010+ net_buf_unref (result );
1011+ }
1012+
1013+ ZTEST (dns_resolve , test_dns_unpack_name_overflow )
1014+ {
1015+ static const uint8_t * test_records [] = {
1016+ /* 4 records 63 bytes (252 bytes) + 3 bytes for dot separators,
1017+ * no space left for NULL terminator.
1018+ */
1019+ "\077very_long_record_that_has_a_length_of_63_bytes_xxxxxxxxxxxxxxxx"
1020+ "\077very_long_record_that_has_a_length_of_63_bytes_xxxxxxxxxxxxxxxx"
1021+ "\077very_long_record_that_has_a_length_of_63_bytes_xxxxxxxxxxxxxxxx"
1022+ "\077very_long_record_that_has_a_length_of_63_bytes_xxxxxxxxxxxxxxxx" ,
1023+ /* 4 records fit (251 bytes), 4 bytes for dot separators, 5th one-byte
1024+ * record won't fit.
1025+ */
1026+ "\077very_long_record_that_has_a_length_of_63_bytes_xxxxxxxxxxxxxxxx"
1027+ "\077very_long_record_that_has_a_length_of_63_bytes_xxxxxxxxxxxxxxxx"
1028+ "\077very_long_record_that_has_a_length_of_63_bytes_xxxxxxxxxxxxxxxx"
1029+ "\076very_long_record_that_has_a_length_of_62_bytes_xxxxxxxxxxxxxxx"
1030+ "\001x" ,
1031+ /* Single 64 byte record, that's forbidden (max record len is 63). */
1032+ "\100very_long_record_that_has_a_length_of_64_bytes_that_is_incorrect" ,
1033+ };
1034+ struct net_buf * result ;
1035+ int ret ;
1036+
1037+ zassert_equal (CONFIG_DNS_RESOLVER_MAX_QUERY_LEN , 255 , "Invalid test configuration" );
1038+
1039+ for (int i = 0 ; i < ARRAY_SIZE (test_records ); i ++ ) {
1040+ result = net_buf_alloc (& test_dns_qname_pool , K_NO_WAIT );
1041+ zassert_not_null (result , "Failed to allocate buffer" );
1042+
1043+ /* +1 to include NULL as terminating label */
1044+ ret = dns_unpack_name (test_records [i ], strlen (test_records [i ]) + 1 ,
1045+ test_records [i ], result , NULL );
1046+ zassert_equal (ret , - EMSGSIZE , "Name parsing should've failed" );
1047+
1048+ net_buf_unref (result );
1049+ }
1050+ }
1051+
9121052ZTEST_SUITE (dns_resolve , NULL , test_init , NULL , NULL , NULL );
0 commit comments