1 /*
2  * Copyright (c) 2017 Intel Corporation
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/kernel.h>
8 #include <zephyr/ztest.h>
9 #include <zephyr/sys/crc.h>
10 #include <dns_pack.h>
11 #include <dns_internal.h>
12 
13 #define MAX_BUF_SIZE	512
14 /* RFC 1035, 4.1.1. Header section format */
15 #define DNS_HEADER_SIZE	12
16 
17 static uint8_t dns_buf[MAX_BUF_SIZE];
18 static uint16_t dns_buf_len;
19 
20 static uint8_t qname[MAX_BUF_SIZE];
21 static uint16_t qname_len;
22 
23 static struct dns_resolve_context dns_ctx;
24 
25 /* Domain: www.zephyrproject.org
26  * Type: standard query (IPv4)
27  * Transaction ID: 0xda0f
28  * Recursion desired
29  */
30 static uint8_t query_ipv4[] = { 0xda, 0x0f, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00,
31 				0x00, 0x00, 0x00, 0x00, 0x03, 0x77, 0x77, 0x77,
32 				0x0d, 0x7a, 0x65, 0x70, 0x68, 0x79, 0x72, 0x70,
33 				0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x03, 0x6f,
34 				0x72, 0x67, 0x00, 0x00, 0x01, 0x00, 0x01 };
35 
36 #define DNAME1 "www.zephyrproject.org"
37 
38 /* Domain: zephyr.local
39  * Type: standard query (IPv6)
40  * Recursion not desired
41  */
42 static uint8_t query_mdns[] = {
43 	0xda, 0x0f, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00,
44 	0x00, 0x00, 0x00, 0x00, 0x06, 0x7a, 0x65, 0x70,
45 	0x68, 0x79, 0x72, 0x05, 0x6c, 0x6f, 0x63, 0x61,
46 	0x6c, 0x00, 0x00, 0x01, 0x00, 0x01,
47 };
48 
49 #define ZEPHYR_LOCAL "zephyr.local"
50 
51 static uint16_t tid1 = 0xda0f;
52 
eval_query(const char * dname,uint16_t tid,enum dns_rr_type type,uint8_t * expected,uint16_t expected_len)53 static int eval_query(const char *dname, uint16_t tid, enum dns_rr_type type,
54 		      uint8_t *expected, uint16_t expected_len)
55 {
56 	uint8_t *question;
57 	int rc;
58 
59 	rc = dns_msg_pack_qname(&qname_len, qname, MAX_BUF_SIZE, dname);
60 	if (rc != 0) {
61 		goto lb_exit;
62 	}
63 
64 	rc = dns_msg_pack_query(dns_buf, &dns_buf_len, MAX_BUF_SIZE, qname, qname_len,
65 				tid, type);
66 	if (rc != 0) {
67 		goto lb_exit;
68 	}
69 
70 	if (dns_unpack_header_id(dns_buf) != tid) {
71 		rc = -EINVAL;
72 		goto lb_exit;
73 	}
74 
75 	/* This is a query */
76 	if (dns_header_qr(dns_buf) != DNS_QUERY) {
77 		rc = -EINVAL;
78 		goto lb_exit;
79 	}
80 
81 	/* This is a query (standard query) */
82 	if (dns_header_opcode(dns_buf) != DNS_QUERY) {
83 		rc = -EINVAL;
84 		goto lb_exit;
85 	}
86 
87 	/* Authoritative Answer must be 0 for a Query */
88 	if (dns_header_aa(dns_buf) != 0) {
89 		rc = -EINVAL;
90 		goto lb_exit;
91 	}
92 
93 	/* TrunCation is always 0 */
94 	if (dns_header_tc(dns_buf) != 0) {
95 		rc = -EINVAL;
96 		goto lb_exit;
97 	}
98 
99 	/* Recursion Desired is always 1 */
100 	if (dns_header_rd(dns_buf) != 1) {
101 		rc = -EINVAL;
102 		goto lb_exit;
103 	}
104 
105 	/* Recursion Available is always 0 */
106 	if (dns_header_ra(dns_buf) != 0) {
107 		rc = -EINVAL;
108 		goto lb_exit;
109 	}
110 
111 	/* Z is always 0 */
112 	if (dns_header_z(dns_buf) != 0) {
113 		rc = -EINVAL;
114 		goto lb_exit;
115 	}
116 
117 	/* Response code must be 0 (no error) */
118 	if (dns_header_rcode(dns_buf) != DNS_HEADER_NOERROR) {
119 		rc = -EINVAL;
120 		goto lb_exit;
121 	}
122 
123 	/* Question counter must be 1 */
124 	if (dns_header_qdcount(dns_buf) != 1) {
125 		rc = -EINVAL;
126 		goto lb_exit;
127 	}
128 
129 	/* Answer counter must be 0 */
130 	if (dns_header_ancount(dns_buf) != 0) {
131 		rc = -EINVAL;
132 		goto lb_exit;
133 	}
134 
135 	/* Name server resource records counter must be 0 */
136 	if (dns_header_nscount(dns_buf) != 0) {
137 		rc = -EINVAL;
138 		goto lb_exit;
139 	}
140 
141 	/* Additional records counter must be 0 */
142 	if (dns_header_arcount(dns_buf) != 0) {
143 		rc = -EINVAL;
144 		goto lb_exit;
145 	}
146 
147 	question = dns_buf + DNS_HEADER_SIZE;
148 
149 	/* QClass */
150 	if (dns_unpack_query_qclass(question + qname_len) != DNS_CLASS_IN) {
151 		rc = -EINVAL;
152 		goto lb_exit;
153 	}
154 
155 	/* QType */
156 	if (dns_unpack_query_qtype(question + qname_len) != type) {
157 		rc = -EINVAL;
158 		goto lb_exit;
159 	}
160 
161 	/* compare with the expected result */
162 	if (dns_buf_len != expected_len) {
163 		rc = -EINVAL;
164 		goto lb_exit;
165 	}
166 
167 	if (memcmp(expected, dns_buf, dns_buf_len) != 0) {
168 		rc = -EINVAL;
169 		goto lb_exit;
170 	}
171 
172 lb_exit:
173 	return rc;
174 }
175 
176 /* The DNS response min size is computed as follows:
177  * (hdr size) + (question min size) +  (RR min size)
178  */
179 #define RESPONSE_MIN_SIZE	(DNS_HEADER_SIZE + 6 + 14)
180 
181 /* DNS QNAME size here is 2 because we use DNS pointers */
182 #define NAME_PTR_SIZE	2
183 /* DNS integer size */
184 #define INT_SIZE	2
185 /* DNS answer TTL size */
186 #define ANS_TTL_SIZE	4
187 
188 struct dns_response_test {
189 	/* domain name: example.com */
190 	const char *dname;
191 
192 	/* expected result */
193 	uint8_t *res;
194 	/* expected result length */
195 	uint16_t res_len;
196 
197 	/* transaction id */
198 	uint16_t tid;
199 	/* A, AAAA */
200 	uint8_t answer_type;
201 	/* answer counter */
202 	uint8_t ancount;
203 	/* answer TTL */
204 	uint32_t ttl;
205 	/* recursion available */
206 	uint8_t ra;
207 	/* recursion desired */
208 	uint8_t rd;
209 	/* data len */
210 	uint8_t rdlen;
211 	/* data */
212 	const uint8_t *rdata;
213 };
214 
215 /* This routine evaluates DNS responses with one RR, and assumes that the
216  * RR's name points to the DNS question's qname.
217  */
eval_response1(struct dns_response_test * resp,bool unpack_answer)218 static int eval_response1(struct dns_response_test *resp, bool unpack_answer)
219 {
220 	uint8_t *ptr = resp->res;
221 	uint16_t offset;
222 	int  rc;
223 
224 	if (resp->res_len < RESPONSE_MIN_SIZE) {
225 		rc = __LINE__;
226 		goto lb_exit;
227 	}
228 
229 	if (dns_unpack_header_id(resp->res) != resp->tid) {
230 		rc = __LINE__;
231 		goto lb_exit;
232 	}
233 
234 	/* This is a response */
235 	if (dns_header_qr(resp->res) != DNS_RESPONSE) {
236 		rc = __LINE__;
237 		goto lb_exit;
238 	}
239 
240 	/* For the DNS response, this value is standard query */
241 	if (dns_header_opcode(resp->res) != DNS_QUERY) {
242 		rc = __LINE__;
243 		goto lb_exit;
244 	}
245 
246 	/* Authoritative Answer */
247 	if (dns_header_aa(resp->res) != 0) {
248 		rc = __LINE__;
249 		goto lb_exit;
250 	}
251 
252 	/* TrunCation is always 0 */
253 	if (dns_header_tc(resp->res) != 0) {
254 		rc = __LINE__;
255 		goto lb_exit;
256 	}
257 
258 	/* Recursion Desired */
259 	if (dns_header_rd(resp->res) != resp->rd) {
260 		rc = __LINE__;
261 		goto lb_exit;
262 	}
263 
264 	/* Recursion Available */
265 	if (dns_header_ra(resp->res) != resp->ra) {
266 		rc = __LINE__;
267 		goto lb_exit;
268 	}
269 
270 	/* Z is always 0 */
271 	if (dns_header_z(resp->res) != 0) {
272 		rc = __LINE__;
273 		goto lb_exit;
274 	}
275 
276 	/* Response code must be 0 (no error) */
277 	if (dns_header_rcode(resp->res) != DNS_HEADER_NOERROR) {
278 		rc = __LINE__;
279 		goto lb_exit;
280 	}
281 
282 	/* Question counter must be 1 */
283 	if (dns_header_qdcount(resp->res) != 1) {
284 		rc = __LINE__;
285 		goto lb_exit;
286 	}
287 
288 	/* Answer counter */
289 	if (dns_header_ancount(resp->res) != resp->ancount) {
290 		rc = __LINE__;
291 		goto lb_exit;
292 	}
293 
294 	/* Name server resource records counter must be 0 */
295 	if (dns_header_nscount(resp->res) != 0) {
296 		rc = __LINE__;
297 		goto lb_exit;
298 	}
299 
300 	/* Additional records counter must be 0 */
301 	if (dns_header_arcount(resp->res) != 0) {
302 		rc = __LINE__;
303 		goto lb_exit;
304 	}
305 
306 	rc = dns_msg_pack_qname(&qname_len, qname, MAX_BUF_SIZE, resp->dname);
307 	if (rc != 0) {
308 		goto lb_exit;
309 	}
310 
311 	offset = DNS_HEADER_SIZE;
312 
313 	/* DNS header + qname + qtype (int size) + qclass (int size) */
314 	if (offset + qname_len + 2 * INT_SIZE >= resp->res_len) {
315 		rc = __LINE__;
316 		goto lb_exit;
317 	}
318 
319 	if (memcmp(qname, resp->res + offset, qname_len) != 0) {
320 		rc = __LINE__;
321 		goto lb_exit;
322 	}
323 
324 	offset += qname_len;
325 
326 	if (dns_unpack_query_qtype(resp->res + offset) != resp->answer_type) {
327 		rc = __LINE__;
328 		goto lb_exit;
329 	}
330 
331 	if (dns_unpack_query_qclass(resp->res + offset) != DNS_CLASS_IN) {
332 		rc = __LINE__;
333 		goto lb_exit;
334 	}
335 
336 	/* qtype and qclass */
337 	offset += INT_SIZE + INT_SIZE;
338 
339 	if (unpack_answer) {
340 		uint32_t ttl;
341 		struct dns_msg_t msg;
342 		enum dns_rr_type answer_type;
343 
344 		msg.msg = resp->res;
345 		msg.msg_size = resp->res_len;
346 		msg.answer_offset = offset;
347 
348 		if (dns_unpack_answer(&msg, DNS_ANSWER_MIN_SIZE, &ttl, &answer_type) < 0) {
349 			rc = __LINE__;
350 			goto lb_exit;
351 		}
352 
353 		offset = msg.response_position;
354 	} else {
355 		/* 0xc0 and 0x0c are derived from RFC 1035 4.1.4 Message
356 		 * compression. 0x0c is the DNS Header Size (fixed size) and
357 		 * 0xc0 is the DNS pointer marker.
358 		 */
359 		if (resp->res[offset + 0] != 0xc0 ||
360 		    resp->res[offset + 1] != 0x0c) {
361 			rc = __LINE__;
362 			goto lb_exit;
363 		}
364 
365 		/* simplify the following lines by applying the offset here */
366 		resp->res += offset;
367 		offset = NAME_PTR_SIZE;
368 
369 		if (dns_answer_type(NAME_PTR_SIZE,
370 				    resp->res) != resp->answer_type) {
371 			rc = __LINE__;
372 			goto lb_exit;
373 		}
374 
375 		offset += INT_SIZE;
376 
377 		if (dns_answer_class(NAME_PTR_SIZE,
378 				     resp->res) != DNS_CLASS_IN) {
379 			rc = __LINE__;
380 			goto lb_exit;
381 		}
382 
383 		offset += INT_SIZE;
384 
385 		if (dns_answer_ttl(NAME_PTR_SIZE, resp->res) != resp->ttl) {
386 			rc = __LINE__;
387 			goto lb_exit;
388 		}
389 
390 		offset += ANS_TTL_SIZE;
391 
392 		if (dns_answer_rdlength(NAME_PTR_SIZE,
393 					resp->res) != resp->rdlen) {
394 			rc = __LINE__;
395 			goto lb_exit;
396 		}
397 
398 		offset += INT_SIZE;
399 	}
400 
401 	if (resp->rdlen + offset > resp->res_len) {
402 		rc = __LINE__;
403 		goto lb_exit;
404 	}
405 
406 	if (memcmp(resp->res + offset, resp->rdata, resp->rdlen) != 0) {
407 		rc = __LINE__;
408 	}
409 
410 lb_exit:
411 	resp->res = ptr;
412 
413 	return -rc;
414 }
415 
416 
ZTEST(dns_packet,test_dns_query)417 ZTEST(dns_packet, test_dns_query)
418 {
419 	int rc;
420 
421 	rc = eval_query(DNAME1, tid1, DNS_RR_TYPE_A,
422 			query_ipv4, sizeof(query_ipv4));
423 	zassert_equal(rc, 0, "Query test failed for domain: "DNAME1);
424 
425 	rc = eval_query(NULL, tid1, DNS_RR_TYPE_A,
426 			query_ipv4, sizeof(query_ipv4));
427 	zassert_not_equal(rc, 0, "Query test with invalid domain name failed");
428 
429 	rc = eval_query(DNAME1, tid1, DNS_RR_TYPE_AAAA,
430 			query_ipv4, sizeof(query_ipv4));
431 	zassert_not_equal(rc, 0, "Query test for IPv4 with RR type AAAA failed");
432 
433 	rc = eval_query(DNAME1, tid1 + 1, DNS_RR_TYPE_A,
434 			query_ipv4, sizeof(query_ipv4));
435 	zassert_not_equal(rc, 0, "Query test with invalid ID failed");
436 }
437 
438 /* DNS response for www.zephyrproject.org with the following parameters:
439  * Transaction ID: 0xb041
440  * Answer type: RR A
441  * Answer counter: 1
442  * TTL: 3028
443  * Recursion Available: 1
444  * RD len: 4 (IPv4 Address)
445  * RData: 140.211.169.8
446  */
447 static uint8_t resp_ipv4[] = { 0xb0, 0x41, 0x81, 0x80, 0x00, 0x01, 0x00, 0x01,
448 			       0x00, 0x00, 0x00, 0x00, 0x03, 0x77, 0x77, 0x77,
449 			       0x0d, 0x7a, 0x65, 0x70, 0x68, 0x79, 0x72, 0x70,
450 			       0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x03, 0x6f,
451 			       0x72, 0x67, 0x00, 0x00, 0x01, 0x00, 0x01, 0xc0,
452 			       0x0c, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x0b,
453 			       0xd4, 0x00, 0x04, 0x8c, 0xd3, 0xa9, 0x08 };
454 
455 static const uint8_t resp_ipv4_addr[] = {140, 211, 169, 8};
456 
ZTEST(dns_packet,test_dns_response)457 ZTEST(dns_packet, test_dns_response)
458 {
459 	struct dns_response_test test = {
460 		.dname = DNAME1,
461 		.res = resp_ipv4,
462 		.res_len = sizeof(resp_ipv4),
463 		.tid = 0xb041,
464 		.answer_type = DNS_RR_TYPE_A,
465 		.ancount = 1,
466 		.ttl = 3028,
467 		.ra = 1,
468 		.rd = 1,
469 		.rdlen = 4, /* IPv4 test */
470 		.rdata = resp_ipv4_addr
471 	};
472 	struct dns_response_test test1, test2;
473 	int rc;
474 
475 	memcpy(&test1, &test, sizeof(test1));
476 	rc = eval_response1(&test1, false);
477 	zassert_equal(rc, 0,
478 		      "Response test failed for domain: " DNAME1
479 		      " at line %d", -rc);
480 
481 	/* Test also using dns_unpack_answer() API */
482 	memcpy(&test2, &test, sizeof(test2));
483 	rc = eval_response1(&test2, true);
484 	zassert_equal(rc, 0,
485 		      "Response test 2 failed for domain: " DNAME1
486 		      " at line %d", -rc);
487 }
488 
489 /* Domain: www.wireshark.org
490  * Type: standard query (IPv4)
491  * Transaction ID: 0x2121
492  * Answer is for a.www.wireshark.org for testing purposes.
493  */
494 char answer_ipv4[] = {
495 	0x21, 0x21, 0x81, 0x80, 0x00, 0x01, 0x00, 0x01,
496 	0x00, 0x00, 0x00, 0x00, 0x03, 0x77, 0x77, 0x77,
497 	0x09, 0x77, 0x69, 0x72, 0x65, 0x73, 0x68, 0x61,
498 	0x72, 0x6b, 0x03, 0x6f, 0x72, 0x67, 0x00, 0x00,
499 	0x01, 0x00, 0x01, 0x01, 0x61, 0xc0, 0x0c, 0x00, 0x01, 0x00,
500 	0x01, 0x00, 0x00, 0x02, 0x58, 0x00, 0x04, 0xae,
501 	0x89, 0x2a, 0x41
502 };
503 
504 #define DNAME2 "www.wireshark.org"
505 
506 static const uint8_t answer_ipv4_addr[] = { 174, 137, 42, 65 };
507 
ZTEST(dns_packet,test_dns_response2)508 ZTEST(dns_packet, test_dns_response2)
509 {
510 	struct dns_response_test test1 = {
511 		.dname = DNAME2,
512 		.res = answer_ipv4,
513 		.res_len = sizeof(answer_ipv4),
514 		.tid = 0x2121,
515 		.answer_type = DNS_RR_TYPE_A,
516 		.ancount = 1,
517 		.ttl = 600,
518 		.ra = 1,
519 		.rd = 1,
520 		.rdlen = 4, /* IPv4 test */
521 		.rdata = answer_ipv4_addr
522 	};
523 	int rc;
524 
525 	/* Test also using dns_unpack_answer() API */
526 	rc = eval_response1(&test1, true);
527 	zassert_equal(rc, 0,
528 		      "Response test 2 failed for domain: " DNAME2
529 		      " at line %d", -rc);
530 }
531 
ZTEST(dns_packet,test_mdns_query)532 ZTEST(dns_packet, test_mdns_query)
533 {
534 	int rc;
535 
536 	rc = eval_query(ZEPHYR_LOCAL, tid1, DNS_RR_TYPE_A,
537 			query_mdns, sizeof(query_mdns));
538 	zassert_equal(rc, 0, "Query test failed for domain: " ZEPHYR_LOCAL);
539 }
540 
541 /* DNS response for zephyr.local with the following parameters:
542  * Transaction ID: 0xf2b6
543  * Answer type: RR AAAA
544  * Answer counter: 1
545  * TTL: 30
546  * Recursion Available: 0
547  * RD len: 16 (IPv6 Address)
548  * RData: fe80:0000:0000:0000:0200:5eff:fe00:5337
549  */
550 static uint8_t resp_ipv6[] = {
551 	0xf2, 0xb6, 0x80, 0x00, 0x00, 0x01, 0x00, 0x01,
552 	0x00, 0x00, 0x00, 0x00, 0x06, 0x7a, 0x65, 0x70,
553 	0x68, 0x79, 0x72, 0x05, 0x6c, 0x6f, 0x63, 0x61,
554 	0x6c, 0x00, 0x00, 0x1c, 0x00, 0x01, 0x06, 0x7a,
555 	0x65, 0x70, 0x68, 0x79, 0x72, 0x05, 0x6c, 0x6f,
556 	0x63, 0x61, 0x6c, 0x00, 0x00, 0x1c, 0x00, 0x01,
557 	0x00, 0x00, 0x00, 0x1e, 0x00, 0x10, 0xfe, 0x80,
558 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
559 	0x5e, 0xff, 0xfe, 0x00, 0x53, 0x37,
560 };
561 
562 static const uint8_t resp_ipv6_addr[] = {
563 	0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
564 	0x02, 0x00, 0x5e, 0xff, 0xfe, 0x00, 0x53, 0x37
565 };
566 
ZTEST(dns_packet,test_mdns_response)567 ZTEST(dns_packet, test_mdns_response)
568 {
569 	struct dns_response_test test1 = {
570 		.dname = ZEPHYR_LOCAL,
571 		.res = resp_ipv6,
572 		.res_len = sizeof(resp_ipv6),
573 		.tid = 0xf2b6,
574 		.answer_type = DNS_RR_TYPE_AAAA,
575 		.ancount = 1,
576 		.ttl = 30,
577 		.ra = 0,
578 		.rd = 0,
579 		.rdlen = 16, /* IPv6 test */
580 		.rdata = resp_ipv6_addr,
581 	};
582 	int rc;
583 
584 	rc = eval_response1(&test1, true);
585 	zassert_equal(rc, 0,
586 		      "Response test failed for domain: " ZEPHYR_LOCAL
587 		      " at line %d", -rc);
588 }
589 
590 static uint8_t resp_truncated_response_ipv4_1[] = {
591 	/* DNS msg header (12 bytes) */
592 	0xb0, 0x41, 0x81, 0x80, 0x00, 0x01, 0x00, 0x01,
593 	0x00, 0x00, 0x00, 0x00,
594 
595 	/* Query string (www.zephyrproject.org) */
596 	0x03, 0x77, 0x77, 0x77, 0x0d, 0x7a, 0x65, 0x70,
597 	0x68, 0x79, 0x72, 0x70, 0x72, 0x6f, 0x6a, 0x65,
598 	0x63, 0x74, 0x03, 0x6f, 0x72, 0x67, 0x00,
599 
600 	/* Query type */
601 	0x00, 0x01,
602 
603 	/* Query class */
604 	0x00, 0x01,
605 
606 	/* Answer data is missing */
607 };
608 
609 static uint8_t resp_truncated_response_ipv4_2[] = {
610 	/* DNS msg header (12 bytes) */
611 	0xb0, 0x41, 0x81, 0x80, 0x00, 0x01, 0x00, 0x01,
612 	0x00, 0x00, 0x00, 0x00,
613 
614 	/* Query string (www.zephyrproject.org) */
615 	0x03, 0x77, 0x77, 0x77, 0x0d, 0x7a, 0x65, 0x70,
616 	0x68, 0x79, 0x72, 0x70, 0x72, 0x6f, 0x6a, 0x65,
617 	0x63, 0x74, 0x03, 0x6f, 0x72, 0x67, 0x00,
618 
619 	/* Rest of the data is missing */
620 };
621 
622 static uint8_t resp_truncated_response_ipv4_3[] = {
623 	/* DNS msg header (12 bytes) */
624 	0xb0, 0x41, 0x81, 0x80, 0x00, 0x01, 0x00, 0x01,
625 	0x00, 0x00, 0x00, 0x00,
626 
627 	/* Query string (www.zephyrproject.org) */
628 	0x03, 0x77, 0x77, 0x77, 0x0d, 0x7a, 0x65, 0x70,
629 	0x68, 0x79, 0x72, 0x70, 0x72, 0x6f, 0x6a, 0x65,
630 	0x63, 0x74, 0x03, 0x6f, 0x72, 0x67, 0x00,
631 
632 	/* Query type */
633 	0x00, 0x01,
634 
635 	/* Query class */
636 	0x00, 0x01,
637 
638 	/* Answer name */
639 	0xc0, 0x1c,
640 
641 	/* Answer type */
642 	0x00, 0x01,
643 
644 	/* Answer class */
645 	0x00, 0x01,
646 
647 	/* TTL */
648 	0x00, 0x00, 0x0b, 0xd4,
649 };
650 
651 static uint8_t resp_truncated_response_ipv4_4[] = {
652 	/* DNS msg header (12 bytes) */
653 	0xb0, 0x41, 0x81, 0x80, 0x00, 0x01, 0x00, 0x01,
654 	0x00, 0x00, 0x00, 0x00,
655 
656 	/* Query string (www.zephyrproject.org) */
657 	0x03, 0x77, 0x77, 0x77, 0x0d, 0x7a, 0x65, 0x70,
658 	0x68, 0x79, 0x72, 0x70, 0x72, 0x6f, 0x6a, 0x65,
659 	0x63, 0x74, 0x03, 0x6f, 0x72, 0x67, 0x00,
660 
661 	/* Query type */
662 	0x00, 0x01,
663 
664 	/* Query class */
665 	0x00, 0x01,
666 
667 	/* Answer name */
668 	0xc0, 0x1c,
669 
670 	/* Answer type */
671 	0x00, 0x01,
672 
673 	/* Answer class */
674 	0x00, 0x01,
675 
676 	/* TTL */
677 	0x00, 0x00, 0x0b, 0xd4,
678 };
679 
680 static uint8_t resp_truncated_response_ipv4_5[] = {
681 	/* DNS msg header (12 bytes) */
682 	0xb0, 0x41, 0x81, 0x80, 0x00, 0x01, 0x00, 0x01,
683 	0x00, 0x00, 0x00, 0x00,
684 
685 	/* Query string (www.zephyrproject.org) */
686 	0x03, 0x77, 0x77, 0x77, 0x0d, 0x7a, 0x65, 0x70,
687 	0x68, 0x79, 0x72, 0x70, 0x72, 0x6f, 0x6a, 0x65,
688 	0x63, 0x74, 0x03, 0x6f, 0x72, 0x67, 0x00,
689 
690 	/* Query type */
691 	0x00, 0x01,
692 
693 	/* Query class */
694 	0x00, 0x01,
695 
696 	/* Answer name */
697 	0xc0, 0x1c,
698 
699 	/* Answer type */
700 	0x00, 0x01,
701 
702 	/* Answer class */
703 	0x00, 0x01,
704 
705 	/* TTL */
706 	0x00, 0x00, 0x0b, 0xd4,
707 
708 	/* Resource data length */
709 	0x00, 0x04,
710 };
711 
712 static uint8_t resp_truncated_response_ipv4_6[] = {
713 	/* DNS msg header (12 bytes) */
714 	/* Id (0) */
715 	0x00, 0x00,
716 	/* Flags (response, rcode = 1) */
717 	0x80, 0x01,
718 	/* Number of questions */
719 	0x00, 0x01,
720 	/* Number of answers */
721 	0x00, 0x00,
722 	/* Number of authority RRs */
723 	0x00, 0x00,
724 	/* Number of additional RRs */
725 	0x00, 0x00,
726 
727 	/* Rest of the data is missing */
728 };
729 
730 static uint8_t resp_valid_response_ipv4_6[] = {
731 	/* DNS msg header (12 bytes) */
732 	0xb0, 0x41, 0x81, 0x80, 0x00, 0x01, 0x00, 0x01,
733 	0x00, 0x00, 0x00, 0x00,
734 
735 	/* Query string (www.zephyrproject.org) */
736 	0x03, 0x77, 0x77, 0x77, 0x0d, 0x7a, 0x65, 0x70,
737 	0x68, 0x79, 0x72, 0x70, 0x72, 0x6f, 0x6a, 0x65,
738 	0x63, 0x74, 0x03, 0x6f, 0x72, 0x67, 0x00,
739 
740 	/* Query type */
741 	0x00, 0x01,
742 
743 	/* Query class */
744 	0x00, 0x01,
745 
746 	/* Answer name */
747 	0xc0, 0x1c,
748 
749 	/* Answer type */
750 	0x00, 0x01,
751 
752 	/* Answer class */
753 	0x00, 0x01,
754 
755 	/* TTL */
756 	0x00, 0x00, 0x0b, 0xd4,
757 
758 	/* Resource data length */
759 	0x00, 0x04,
760 
761 	/* Resource data (IP address) */
762 	0x8c, 0xd3, 0xa9, 0x08
763 };
764 
765 static uint8_t resp_valid_response_ipv4_7[] = {
766 	/* DNS msg header (12 bytes) */
767 	0xb0, 0x41, 0x81, 0x80, 0x00, 0x01, 0x00, 0x01,
768 	0x00, 0x00, 0x00, 0x00,
769 
770 	/* Query string (www.zephyrproject.org) */
771 	0x03, 0x77, 0x77, 0x77, 0x0d, 0x7a, 0x65, 0x70,
772 	0x68, 0x79, 0x72, 0x70, 0x72, 0x6f, 0x6a, 0x65,
773 	0x63, 0x74, 0x03, 0x6f, 0x72, 0x67, 0x00,
774 
775 	/* Query type */
776 	0x00, 0x01,
777 
778 	/* Query class */
779 	0x00, 0x01,
780 
781 	/* Answer name (do not use pointer here) */
782 	0x03, 0x77, 0x77, 0x77, 0x0d, 0x7a, 0x65, 0x70,
783 	0x68, 0x79, 0x72, 0x70, 0x72, 0x6f, 0x6a, 0x65,
784 	0x63, 0x74, 0x03, 0x6f, 0x72, 0x67, 0x00,
785 
786 	/* Answer type */
787 	0x00, 0x01,
788 
789 	/* Answer class */
790 	0x00, 0x01,
791 
792 	/* TTL */
793 	0x00, 0x00, 0x0b, 0xd4,
794 
795 	/* Resource data length */
796 	0x00, 0x04,
797 
798 	/* Resource data (IP address) */
799 	0x8c, 0xd3, 0xa9, 0x08
800 };
801 
802 static uint8_t resp_valid_response_ipv4_8[] = {
803 	/* DNS msg header (12 bytes) */
804 	0xb0, 0x41, 0x81, 0x80, 0x00, 0x01, 0x00, 0x02,
805 	0x00, 0x00, 0x00, 0x00,
806 
807 	/* Query string (www.zephyrproject.org) */
808 	0x03, 0x77, 0x77, 0x77, 0x0d, 0x7a, 0x65, 0x70,
809 	0x68, 0x79, 0x72, 0x70, 0x72, 0x6f, 0x6a, 0x65,
810 	0x63, 0x74, 0x03, 0x6f, 0x72, 0x67, 0x00,
811 
812 	/* Query type */
813 	0x00, 0x01,
814 
815 	/* Query class */
816 	0x00, 0x01,
817 
818 	/* 1st answer name (do not use pointer here) */
819 	0x03, 0x77, 0x77, 0x77, 0x0d, 0x7a, 0x65, 0x70,
820 	0x68, 0x79, 0x72, 0x70, 0x72, 0x6f, 0x6a, 0x65,
821 	0x63, 0x74, 0x03, 0x6f, 0x72, 0x67, 0x00,
822 
823 	/* Answer type */
824 	0x00, 0x01,
825 
826 	/* Answer class */
827 	0x00, 0x01,
828 
829 	/* TTL */
830 	0x00, 0x00, 0x0b, 0xd4,
831 
832 	/* Resource data length */
833 	0x00, 0x04,
834 
835 	/* Resource data (IP address) */
836 	0x8c, 0xd3, 0xa9, 0x08,
837 
838 	/* 2nd answer name (do not use pointer here) */
839 	0x03, 0x77, 0x77, 0x77, 0x0d, 0x7a, 0x65, 0x70,
840 	0x68, 0x79, 0x72, 0x70, 0x72, 0x6f, 0x6a, 0x65,
841 	0x63, 0x74, 0x03, 0x6f, 0x72, 0x67, 0x00,
842 
843 	/* Answer type */
844 	0x00, 0x01,
845 
846 	/* Answer class */
847 	0x00, 0x01,
848 
849 	/* TTL */
850 	0x00, 0x00, 0x0b, 0xd4,
851 
852 	/* Resource data length */
853 	0x00, 0x04,
854 
855 	/* Resource data (IP address) */
856 	0x8c, 0xd3, 0xa9, 0x09
857 };
858 
859 static uint8_t resp_valid_response_ipv4_9[] = {
860 	/* DNS msg header (12 bytes) */
861 	0xb0, 0x41, 0x81, 0x80, 0x00, 0x01, 0x00, 0x02,
862 	0x00, 0x00, 0x00, 0x00,
863 
864 	/* Query string (www.zephyrproject.org) */
865 	0x03, 0x77, 0x77, 0x77, 0x0d, 0x7a, 0x65, 0x70,
866 	0x68, 0x79, 0x72, 0x70, 0x72, 0x6f, 0x6a, 0x65,
867 	0x63, 0x74, 0x03, 0x6f, 0x72, 0x67, 0x00,
868 
869 	/* Query type */
870 	0x00, 0x01,
871 
872 	/* Query class */
873 	0x00, 0x01,
874 
875 	/* 1st answer name (use pointer for 1st answer) */
876 	0xc0, 0x1c,
877 
878 	/* Answer type */
879 	0x00, 0x01,
880 
881 	/* Answer class */
882 	0x00, 0x01,
883 
884 	/* TTL */
885 	0x00, 0x00, 0x0b, 0xd4,
886 
887 	/* Resource data length */
888 	0x00, 0x04,
889 
890 	/* Resource data (IP address) */
891 	0x8c, 0xd3, 0xa9, 0x08,
892 
893 	/* 2nd answer name (do not use pointer here) */
894 	0x03, 0x77, 0x77, 0x77, 0x0d, 0x7a, 0x65, 0x70,
895 	0x68, 0x79, 0x72, 0x70, 0x72, 0x6f, 0x6a, 0x65,
896 	0x63, 0x74, 0x03, 0x6f, 0x72, 0x67, 0x00,
897 
898 	/* Answer type */
899 	0x00, 0x01,
900 
901 	/* Answer class */
902 	0x00, 0x01,
903 
904 	/* TTL */
905 	0x00, 0x00, 0x0b, 0xd4,
906 
907 	/* Resource data length */
908 	0x00, 0x04,
909 
910 	/* Resource data (IP address) */
911 	0x8c, 0xd3, 0xa9, 0x09
912 };
913 
914 static uint8_t resp_valid_response_ipv4_10[] = {
915 	/* DNS msg header (12 bytes) */
916 	0x74, 0xe1, 0x81, 0x80, 0x00, 0x01, 0x00, 0x02,
917 	0x00, 0x00, 0x00, 0x00,
918 
919 	/* Query string */
920 	0x0e, 0x77, 0x65, 0x73,	0x74, 0x75, 0x73, 0x32,
921 	0x2d, 0x70, 0x72, 0x6f, 0x64, 0x2d, 0x32, 0x0d,
922 	0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61,
923 	0x74, 0x69, 0x6f, 0x6e, 0x73, 0x05, 0x74, 0x65,
924 	0x61, 0x6d, 0x73, 0x09, 0x6d, 0x69, 0x63, 0x72,
925 	0x6f, 0x73, 0x6f, 0x66, 0x74, 0x03, 0x63, 0x6f,
926 	0x6d, 0x00,
927 
928 	/* Type */
929 	0x00, 0x01,
930 
931 	/* Class */
932 	0x00, 0x01,
933 
934 	/* Answer 1 */
935 	0xc0, 0x0c,
936 
937 	/* Answer type (cname) */
938 	0x00, 0x05,
939 
940 	/* Class */
941 	0x00, 0x01,
942 
943 	/* TTL */
944 	0x00, 0x00, 0x00, 0x04,
945 
946 	/* RR data length */
947 	0x00, 0x26,
948 
949 	/* Data */
950 	0x11, 0x77, 0x65, 0x73, 0x74, 0x75, 0x73, 0x32,
951 	0x63, 0x6e, 0x73, 0x2d, 0x70, 0x72, 0x6f, 0x64,
952 	0x2d, 0x32, 0x0e, 0x74, 0x72, 0x61, 0x66, 0x66,
953 	0x69, 0x63, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65,
954 	0x72, 0x03, 0x6e, 0x65, 0x74, 0x00,
955 
956 	/* Answer 2 */
957 	0xc0, 0x4e,
958 
959 	/* cname */
960 	0x00, 0x05,
961 
962 	/* Class */
963 	0x00, 0x01,
964 
965 	/* TTL */
966 	0x00, 0x00, 0x00, 0x04,
967 
968 	/* RR data length */
969 	0x00, 0x2e,
970 
971 	/* Data */
972 	0x14, 0x77, 0x65, 0x73, 0x74, 0x75, 0x73, 0x32,
973 	0x63, 0x6e, 0x73, 0x2d, 0x70, 0x72, 0x6f, 0x64,
974 	0x2d, 0x32, 0x2d, 0x31, 0x36, 0x07, 0x77, 0x65,
975 	0x73, 0x74, 0x75, 0x73, 0x32, 0x08, 0x63, 0x6c,
976 	0x6f, 0x75, 0x64, 0x61, 0x70, 0x70, 0x05, 0x61,
977 	0x7a, 0x75, 0x72, 0x65, 0xc0, 0x39,
978 };
979 
980 static uint8_t resp_valid_response_ipv4_11[] = {
981 	/* DNS msg header (12 bytes) */
982 	0x74, 0xe1, 0x81, 0x80, 0x00, 0x01, 0x00, 0x03,
983 	0x00, 0x00, 0x00, 0x00,
984 
985 	/* Query string */
986 	0x0e, 0x77, 0x65, 0x73,	0x74, 0x75, 0x73, 0x32,
987 	0x2d, 0x70, 0x72, 0x6f, 0x64, 0x2d, 0x32, 0x0d,
988 	0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61,
989 	0x74, 0x69, 0x6f, 0x6e, 0x73, 0x05, 0x74, 0x65,
990 	0x61, 0x6d, 0x73, 0x09, 0x6d, 0x69, 0x63, 0x72,
991 	0x6f, 0x73, 0x6f, 0x66, 0x74, 0x03, 0x63, 0x6f,
992 	0x6d, 0x00,
993 
994 	/* Type */
995 	0x00, 0x01,
996 
997 	/* Class */
998 	0x00, 0x01,
999 
1000 	/* Answer 1 */
1001 	0xc0, 0x0c,
1002 
1003 	/* Answer type (cname) */
1004 	0x00, 0x05,
1005 
1006 	/* Class */
1007 	0x00, 0x01,
1008 
1009 	/* TTL */
1010 	0x00, 0x00, 0x00, 0x04,
1011 
1012 	/* RR data length */
1013 	0x00, 0x26,
1014 
1015 	/* Data */
1016 	0x11, 0x77, 0x65, 0x73, 0x74, 0x75, 0x73, 0x32,
1017 	0x63, 0x6e, 0x73, 0x2d, 0x70, 0x72, 0x6f, 0x64,
1018 	0x2d, 0x32, 0x0e, 0x74, 0x72, 0x61, 0x66, 0x66,
1019 	0x69, 0x63, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65,
1020 	0x72, 0x03, 0x6e, 0x65, 0x74, 0x00,
1021 
1022 	/* Answer 2 */
1023 	0xc0, 0x4e,
1024 
1025 	/* cname */
1026 	0x00, 0x05,
1027 
1028 	/* Class */
1029 	0x00, 0x01,
1030 
1031 	/* TTL */
1032 	0x00, 0x00, 0x00, 0x04,
1033 
1034 	/* RR data length */
1035 	0x00, 0x2e,
1036 
1037 	/* Data */
1038 	0x14, 0x77, 0x65, 0x73, 0x74, 0x75, 0x73, 0x32,
1039 	0x63, 0x6e, 0x73, 0x2d, 0x70, 0x72, 0x6f, 0x64,
1040 	0x2d, 0x32, 0x2d, 0x31, 0x36, 0x07, 0x77, 0x65,
1041 	0x73, 0x74, 0x75, 0x73, 0x32, 0x08, 0x63, 0x6c,
1042 	0x6f, 0x75, 0x64, 0x61, 0x70, 0x70, 0x05, 0x61,
1043 	0x7a, 0x75, 0x72, 0x65, 0xc0, 0x39,
1044 
1045 	/* Answer 3 */
1046 	0xc0, 0x80,
1047 
1048 	/* A record */
1049 	0x00, 0x01,
1050 
1051 	/* Class */
1052 	0x00, 0x01,
1053 
1054 	/* TTL */
1055 	0x00, 0x00, 0x00, 0x04,
1056 
1057 	/* RR length */
1058 	0x00, 0x04,
1059 
1060 	/* IP address */
1061 	0x34, 0x72, 0x94, 0x90
1062 };
1063 
resolve_cb(enum dns_resolve_status status,struct dns_addrinfo * info,void * user_data)1064 static void resolve_cb(enum dns_resolve_status status,
1065 		       struct dns_addrinfo *info,
1066 		       void *user_data)
1067 {
1068 	ARG_UNUSED(status);
1069 	ARG_UNUSED(info);
1070 	ARG_UNUSED(user_data);
1071 }
1072 
setup_dns_context(struct dns_resolve_context * ctx,int idx,uint16_t dns_id,const uint8_t * query,size_t query_len,enum dns_query_type query_type)1073 static void setup_dns_context(struct dns_resolve_context *ctx,
1074 			      int idx,
1075 			      uint16_t dns_id,
1076 			      const uint8_t *query,
1077 			      size_t query_len,
1078 			      enum dns_query_type query_type)
1079 {
1080 	ctx->queries[idx].cb = resolve_cb;
1081 	ctx->queries[idx].id = dns_id;
1082 	ctx->queries[idx].query = query;
1083 	ctx->queries[idx].query_type = query_type;
1084 	ctx->queries[idx].query_hash = crc16_ansi(query, query_len);
1085 	ctx->state = DNS_RESOLVE_CONTEXT_ACTIVE;
1086 
1087 }
1088 
run_dns_malformed_response(const char * test_case,uint8_t * buf,size_t len)1089 static void run_dns_malformed_response(const char *test_case,
1090 				       uint8_t *buf, size_t len)
1091 {
1092 	/* Query is used to calculate the hash, it contains the
1093 	 * labels + query type
1094 	 */
1095 	static const uint8_t query[] = {
1096 		/* Labels */
1097 		0x03, 0x77, 0x77, 0x77, 0x0d, 0x7a, 0x65, 0x70,
1098 		0x68, 0x79, 0x72, 0x70, 0x72, 0x6f, 0x6a, 0x65,
1099 		0x63, 0x74, 0x03, 0x6f, 0x72, 0x67, 0x00,
1100 		/* Query type */
1101 		0x00, 0x01
1102 	};
1103 	struct dns_msg_t dns_msg = { 0 };
1104 	uint16_t dns_id = 0;
1105 	int query_idx = -1;
1106 	uint16_t query_hash = 0;
1107 	int ret;
1108 
1109 	dns_msg.msg = buf;
1110 	dns_msg.msg_size = len;
1111 
1112 	dns_id = dns_unpack_header_id(dns_msg.msg);
1113 
1114 	/* If the message is longer than 12 bytes, it could be a valid DNS message
1115 	 * in which case setup the context for the reply.
1116 	 */
1117 	if (len > 12) {
1118 		setup_dns_context(&dns_ctx, 0, dns_id, query, sizeof(query),
1119 				  DNS_QUERY_TYPE_A);
1120 	}
1121 
1122 	ret = dns_validate_msg(&dns_ctx, &dns_msg, &dns_id, &query_idx,
1123 			       NULL, &query_hash);
1124 	zassert_not_equal(ret, DNS_EAI_ALLDONE,
1125 			  "[%s] DNS message was valid (%d)",
1126 			  test_case, ret);
1127 }
1128 
run_dns_valid_response(const char * test_case,uint8_t * buf,size_t len)1129 static void run_dns_valid_response(const char *test_case,
1130 				   uint8_t *buf, size_t len)
1131 {
1132 	struct dns_msg_t dns_msg = { 0 };
1133 	uint16_t dns_id = 0;
1134 	int query_idx = -1;
1135 	uint16_t query_hash = 0;
1136 	int ret;
1137 
1138 	dns_msg.msg = buf;
1139 	dns_msg.msg_size = len;
1140 
1141 	ret = dns_validate_msg(&dns_ctx, &dns_msg, &dns_id, &query_idx,
1142 			       NULL, &query_hash);
1143 	zassert_equal(ret, DNS_EAI_ALLDONE, "[%s] DNS message failed (%d)",
1144 		      test_case, ret);
1145 }
1146 
1147 #define DNS_RESOLVER_MAX_BUF_SIZE	512
1148 #define DNS_RESOLVER_MIN_BUF	1
1149 #define DNS_RESOLVER_BUF_CTR	(DNS_RESOLVER_MIN_BUF + 1)
1150 #define DNS_MAX_NAME_LEN	255
1151 
1152 NET_BUF_POOL_DEFINE(dns_qname_pool, DNS_RESOLVER_BUF_CTR, DNS_MAX_NAME_LEN,
1153 		    0, NULL);
1154 
run_dns_valid_cname_response(const char * test_case,uint8_t * buf,size_t len,int expected_ret)1155 static void run_dns_valid_cname_response(const char *test_case,
1156 					 uint8_t *buf, size_t len,
1157 					 int expected_ret)
1158 {
1159 	static const uint8_t query[] = {
1160 		/* Query string */
1161 		0x0e, 0x77, 0x65, 0x73,	0x74, 0x75, 0x73, 0x32,
1162 		0x2d, 0x70, 0x72, 0x6f, 0x64, 0x2d, 0x32, 0x0d,
1163 		0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61,
1164 		0x74, 0x69, 0x6f, 0x6e, 0x73, 0x05, 0x74, 0x65,
1165 		0x61, 0x6d, 0x73, 0x09, 0x6d, 0x69, 0x63, 0x72,
1166 		0x6f, 0x73, 0x6f, 0x66, 0x74, 0x03, 0x63, 0x6f,
1167 		0x6d, 0x00,
1168 
1169 		/* Type */
1170 		0x00, 0x01,
1171 	};
1172 	struct dns_msg_t dns_msg = { 0 };
1173 	struct net_buf *dns_cname;
1174 	uint16_t dns_id = 0;
1175 	int query_idx = -1;
1176 	uint16_t query_hash = 0;
1177 	int ret;
1178 
1179 	dns_msg.msg = buf;
1180 	dns_msg.msg_size = len;
1181 
1182 	dns_cname = net_buf_alloc(&dns_qname_pool, K_MSEC(100));
1183 	zassert_not_null(dns_cname, "Out of mem");
1184 
1185 	dns_id = dns_unpack_header_id(dns_msg.msg);
1186 
1187 	setup_dns_context(&dns_ctx, 0, dns_id, query, sizeof(query),
1188 			  DNS_QUERY_TYPE_A);
1189 
1190 	ret = dns_validate_msg(&dns_ctx, &dns_msg, &dns_id, &query_idx,
1191 			       dns_cname, &query_hash);
1192 	zassert_equal(ret, expected_ret, "[%s] DNS message failed (%d)",
1193 		      test_case, ret);
1194 }
1195 
1196 #define RUN_VALID_TEST(test_name)					\
1197 	run_dns_valid_response(#test_name, test_name, sizeof(test_name))
1198 
1199 #define RUN_VALID_CNAME_TEST(test_name, expected_ret)			\
1200 	run_dns_valid_cname_response(#test_name, test_name,		\
1201 				     sizeof(test_name), expected_ret)
1202 
test_dns_valid_responses(void)1203 static void test_dns_valid_responses(void)
1204 {
1205 	RUN_VALID_TEST(resp_valid_response_ipv4_6);
1206 	RUN_VALID_TEST(resp_valid_response_ipv4_7);
1207 	RUN_VALID_TEST(resp_valid_response_ipv4_8);
1208 	RUN_VALID_TEST(resp_valid_response_ipv4_9);
1209 
1210 	RUN_VALID_CNAME_TEST(resp_valid_response_ipv4_10, DNS_EAI_AGAIN);
1211 	RUN_VALID_CNAME_TEST(resp_valid_response_ipv4_11, DNS_EAI_ALLDONE);
1212 }
1213 
1214 #define RUN_MALFORMED_TEST(test_name) \
1215 	run_dns_malformed_response(#test_name, test_name, sizeof(test_name))
1216 
test_dns_malformed_responses(void)1217 static void test_dns_malformed_responses(void)
1218 {
1219 	RUN_MALFORMED_TEST(resp_truncated_response_ipv4_1);
1220 	RUN_MALFORMED_TEST(resp_truncated_response_ipv4_2);
1221 	RUN_MALFORMED_TEST(resp_truncated_response_ipv4_3);
1222 	RUN_MALFORMED_TEST(resp_truncated_response_ipv4_4);
1223 	RUN_MALFORMED_TEST(resp_truncated_response_ipv4_5);
1224 	RUN_MALFORMED_TEST(resp_truncated_response_ipv4_6);
1225 }
1226 
ZTEST(dns_packet,test_dns_malformed_and_valid_responses)1227 ZTEST(dns_packet, test_dns_malformed_and_valid_responses)
1228 {
1229 	test_dns_malformed_responses();
1230 	test_dns_valid_responses();
1231 }
1232 
ZTEST(dns_packet,test_dns_id_len)1233 ZTEST(dns_packet, test_dns_id_len)
1234 {
1235 	struct dns_msg_t dns_msg = { 0 };
1236 	uint8_t buf[1];
1237 	uint16_t dns_id = 0;
1238 	int query_idx = -1;
1239 	uint16_t query_hash = 0;
1240 	int ret;
1241 
1242 	dns_msg.msg = buf;
1243 	dns_msg.msg_size = sizeof(buf);
1244 
1245 	ret = dns_validate_msg(&dns_ctx, &dns_msg, &dns_id, &query_idx,
1246 			       NULL, &query_hash);
1247 	zassert_equal(ret, DNS_EAI_FAIL,
1248 		      "DNS message length check failed (%d)", ret);
1249 }
1250 
ZTEST(dns_packet,test_dns_flags_len)1251 ZTEST(dns_packet, test_dns_flags_len)
1252 {
1253 	struct dns_msg_t dns_msg = { 0 };
1254 	uint8_t buf[3];
1255 	uint16_t dns_id = 0;
1256 	int query_idx = -1;
1257 	uint16_t query_hash = 0;
1258 	int ret;
1259 
1260 	dns_msg.msg = buf;
1261 	dns_msg.msg_size = sizeof(buf);
1262 
1263 	ret = dns_validate_msg(&dns_ctx, &dns_msg, &dns_id, &query_idx,
1264 			       NULL, &query_hash);
1265 	zassert_equal(ret, DNS_EAI_FAIL,
1266 		      "DNS message length check failed (%d)", ret);
1267 }
1268 
1269 static uint8_t invalid_answer_resp_ipv4[18] = {
1270 	/* DNS msg header (12 bytes) */
1271 	0x01, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
1272 	0x00, 0x00, 0x01, 0x00, 0x01,
1273 };
1274 
ZTEST(dns_packet,test_dns_invalid_answer)1275 ZTEST(dns_packet, test_dns_invalid_answer)
1276 {
1277 	struct dns_msg_t dns_msg = { 0 };
1278 	enum dns_rr_type type;
1279 	uint32_t ttl;
1280 	int ret;
1281 
1282 	dns_msg.msg = invalid_answer_resp_ipv4;
1283 	dns_msg.msg_size = sizeof(invalid_answer_resp_ipv4);
1284 	dns_msg.answer_offset = 12;
1285 
1286 	ret = dns_unpack_answer(&dns_msg, 0, &ttl, &type);
1287 	zassert_equal(ret, -EINVAL, "DNS message answer check succeed (%d)", ret);
1288 }
1289 
1290 ZTEST_SUITE(dns_packet, NULL, NULL, NULL, NULL, NULL);
1291 /* TODO:
1292  *	1) add malformed DNS data (mostly done)
1293  *	2) add validations against buffer overflows
1294  *	3) add debug info to detect the exit point (or split the tests)
1295  *	4) add test data with CNAME and more RR
1296  */
1297