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