]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/resolve/test-dns-packet.c
Merge pull request #3594 from poettering/resolved-servfail
[thirdparty/systemd.git] / src / resolve / test-dns-packet.c
1 /***
2 This file is part of systemd
3
4 Copyright 2016 Zbigniew Jędrzejewski-Szmek
5
6 systemd is free software; you can redistribute it and/or modify it
7 under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation; either version 2.1 of the License, or
9 (at your option) any later version.
10
11 systemd is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public License
17 along with systemd; If not, see <http://www.gnu.org/licenses/>.
18 ***/
19
20 #include <net/if.h>
21 #include <glob.h>
22
23 #include "alloc-util.h"
24 #include "fileio.h"
25 #include "glob-util.h"
26 #include "log.h"
27 #include "macro.h"
28 #include "resolved-dns-packet.h"
29 #include "resolved-dns-rr.h"
30 #include "string-util.h"
31 #include "strv.h"
32 #include "unaligned.h"
33
34 #define HASH_KEY SD_ID128_MAKE(d3,1e,48,90,4b,fa,4c,fe,af,9d,d5,a1,d7,2e,8a,b1)
35
36 static void verify_rr_copy(DnsResourceRecord *rr) {
37 _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *copy = NULL;
38 const char *a, *b;
39
40 assert_se(copy = dns_resource_record_copy(rr));
41 assert_se(dns_resource_record_equal(copy, rr) > 0);
42
43 assert_se(a = dns_resource_record_to_string(rr));
44 assert_se(b = dns_resource_record_to_string(copy));
45
46 assert_se(streq(a, b));
47 }
48
49 static uint64_t hash(DnsResourceRecord *rr) {
50 struct siphash state;
51
52 siphash24_init(&state, HASH_KEY.bytes);
53 dns_resource_record_hash_func(rr, &state);
54 return siphash24_finalize(&state);
55 }
56
57 static void test_packet_from_file(const char* filename, bool canonical) {
58 _cleanup_free_ char *data = NULL;
59 size_t data_size, packet_size, offset;
60
61 assert_se(read_full_file(filename, &data, &data_size) >= 0);
62 assert_se(data);
63 assert_se(data_size > 8);
64
65 log_info("============== %s %s==============", filename, canonical ? "canonical " : "");
66
67 for (offset = 0; offset < data_size; offset += 8 + packet_size) {
68 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL, *p2 = NULL;
69 _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL, *rr2 = NULL;
70 const char *s, *s2;
71 uint64_t hash1, hash2;
72
73 packet_size = unaligned_read_le64(data + offset);
74 assert_se(packet_size > 0);
75 assert_se(offset + 8 + packet_size <= data_size);
76
77 assert_se(dns_packet_new(&p, DNS_PROTOCOL_DNS, 0) >= 0);
78
79 assert_se(dns_packet_append_blob(p, data + offset + 8, packet_size, NULL) >= 0);
80 assert_se(dns_packet_read_rr(p, &rr, NULL, NULL) >= 0);
81
82 verify_rr_copy(rr);
83
84 s = dns_resource_record_to_string(rr);
85 assert_se(s);
86 puts(s);
87
88 hash1 = hash(rr);
89
90 assert_se(dns_resource_record_to_wire_format(rr, canonical) >= 0);
91
92 assert_se(dns_packet_new(&p2, DNS_PROTOCOL_DNS, 0) >= 0);
93 assert_se(dns_packet_append_blob(p2, rr->wire_format, rr->wire_format_size, NULL) >= 0);
94 assert_se(dns_packet_read_rr(p2, &rr2, NULL, NULL) >= 0);
95
96 verify_rr_copy(rr);
97
98 s2 = dns_resource_record_to_string(rr);
99 assert_se(s2);
100 assert_se(streq(s, s2));
101
102 hash2 = hash(rr);
103 assert_se(hash1 == hash2);
104 }
105 }
106
107 int main(int argc, char **argv) {
108 int i, N;
109 _cleanup_globfree_ glob_t g = {};
110 char **fnames;
111
112 log_parse_environment();
113
114 if (argc >= 2) {
115 N = argc - 1;
116 fnames = argv + 1;
117 } else {
118 assert_se(glob(RESOLVE_TEST_DIR "/*.pkts", GLOB_NOSORT, NULL, &g) == 0);
119 N = g.gl_pathc;
120 fnames = g.gl_pathv;
121 }
122
123 for (i = 0; i < N; i++) {
124 test_packet_from_file(fnames[i], false);
125 puts("");
126 test_packet_from_file(fnames[i], true);
127 if (i + 1 < N)
128 puts("");
129 }
130
131 return EXIT_SUCCESS;
132 }