]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/resolve/test-resolved-etc-hosts.c
Merge pull request #25602 from fbuihuu/fix-TEST-73-LOCALE
[thirdparty/systemd.git] / src / resolve / test-resolved-etc-hosts.c
1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2
3 #include <arpa/inet.h>
4 #include <malloc.h>
5 #include <netinet/in.h>
6 #include <sys/socket.h>
7
8 #include "fd-util.h"
9 #include "fileio.h"
10 #include "fs-util.h"
11 #include "log.h"
12 #include "resolved-etc-hosts.h"
13 #include "strv.h"
14 #include "tests.h"
15 #include "tmpfile-util.h"
16
17 TEST(parse_etc_hosts_system) {
18 _cleanup_fclose_ FILE *f = NULL;
19
20 f = fopen("/etc/hosts", "re");
21 if (!f) {
22 assert_se(errno == ENOENT);
23 return;
24 }
25
26 _cleanup_(etc_hosts_clear) EtcHosts hosts = {};
27 assert_se(etc_hosts_parse(&hosts, f) == 0);
28 }
29
30 #define has_4(_set, _address_str) \
31 set_contains(_set, &(struct in_addr_data) { .family = AF_INET, .address.in = { .s_addr = inet_addr(_address_str) } })
32
33 #define has_6(_set, ...) \
34 set_contains(_set, &(struct in_addr_data) { .family = AF_INET6, .address.in6 = { .s6_addr = __VA_ARGS__ } })
35
36 TEST(parse_etc_hosts) {
37 _cleanup_(unlink_tempfilep) char
38 t[] = "/tmp/test-resolved-etc-hosts.XXXXXX";
39
40 int fd;
41 _cleanup_fclose_ FILE *f;
42
43 fd = mkostemp_safe(t);
44 assert_se(fd >= 0);
45
46 f = fdopen(fd, "r+");
47 assert_se(f);
48 fputs("1.2.3.4 some.where\n"
49 "1.2.3.5 some.where\n"
50 "1.2.3.6 dash dash-dash.where-dash\n"
51 "1.2.3.7 bad-dash- -bad-dash -bad-dash.bad-\n"
52 "1.2.3.8\n"
53 "1.2.3.9 before.comment # within.comment\n"
54 "1.2.3.10 before.comment#within.comment2\n"
55 "1.2.3.11 before.comment# within.comment3\n"
56 "1.2.3.12 before.comment#\n"
57 "1.2.3 short.address\n"
58 "1.2.3.4.5 long.address\n"
59 "1::2::3 multi.colon\n"
60
61 "::0 some.where some.other\n"
62 "0.0.0.0 deny.listed\n"
63 "::5\t\t\t \tsome.where\tsome.other foobar.foo.foo\t\t\t\n"
64 " \n", f);
65 assert_se(fflush_and_check(f) >= 0);
66 rewind(f);
67
68 _cleanup_(etc_hosts_clear) EtcHosts hosts = {};
69 assert_se(etc_hosts_parse(&hosts, f) == 0);
70
71 EtcHostsItemByName *bn;
72 assert_se(bn = hashmap_get(hosts.by_name, "some.where"));
73 assert_se(set_size(bn->addresses) == 3);
74 assert_se(has_4(bn->addresses, "1.2.3.4"));
75 assert_se(has_4(bn->addresses, "1.2.3.5"));
76 assert_se(has_6(bn->addresses, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5}));
77
78 assert_se(bn = hashmap_get(hosts.by_name, "dash"));
79 assert_se(set_size(bn->addresses) == 1);
80 assert_se(has_4(bn->addresses, "1.2.3.6"));
81
82 assert_se(bn = hashmap_get(hosts.by_name, "dash-dash.where-dash"));
83 assert_se(set_size(bn->addresses) == 1);
84 assert_se(has_4(bn->addresses, "1.2.3.6"));
85
86 /* See https://tools.ietf.org/html/rfc1035#section-2.3.1 */
87 FOREACH_STRING(s, "bad-dash-", "-bad-dash", "-bad-dash.bad-")
88 assert_se(!hashmap_get(hosts.by_name, s));
89
90 assert_se(bn = hashmap_get(hosts.by_name, "before.comment"));
91 assert_se(set_size(bn->addresses) == 4);
92 assert_se(has_4(bn->addresses, "1.2.3.9"));
93 assert_se(has_4(bn->addresses, "1.2.3.10"));
94 assert_se(has_4(bn->addresses, "1.2.3.11"));
95 assert_se(has_4(bn->addresses, "1.2.3.12"));
96
97 assert_se(!hashmap_get(hosts.by_name, "within.comment"));
98 assert_se(!hashmap_get(hosts.by_name, "within.comment2"));
99 assert_se(!hashmap_get(hosts.by_name, "within.comment3"));
100 assert_se(!hashmap_get(hosts.by_name, "#"));
101
102 assert_se(!hashmap_get(hosts.by_name, "short.address"));
103 assert_se(!hashmap_get(hosts.by_name, "long.address"));
104 assert_se(!hashmap_get(hosts.by_name, "multi.colon"));
105 assert_se(!set_contains(hosts.no_address, "short.address"));
106 assert_se(!set_contains(hosts.no_address, "long.address"));
107 assert_se(!set_contains(hosts.no_address, "multi.colon"));
108
109 assert_se(bn = hashmap_get(hosts.by_name, "some.other"));
110 assert_se(set_size(bn->addresses) == 1);
111 assert_se(has_6(bn->addresses, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5}));
112
113 assert_se( set_contains(hosts.no_address, "some.where"));
114 assert_se( set_contains(hosts.no_address, "some.other"));
115 assert_se( set_contains(hosts.no_address, "deny.listed"));
116 assert_se(!set_contains(hosts.no_address, "foobar.foo.foo"));
117 }
118
119 static void test_parse_file_one(const char *fname) {
120 _cleanup_(etc_hosts_clear) EtcHosts hosts = {};
121 _cleanup_fclose_ FILE *f;
122
123 log_info("/* %s(\"%s\") */", __func__, fname);
124
125 assert_se(f = fopen(fname, "re"));
126 assert_se(etc_hosts_parse(&hosts, f) == 0);
127 }
128
129 TEST(parse_file) {
130 for (int i = 1; i < saved_argc; i++)
131 test_parse_file_one(saved_argv[i]);
132 }
133
134 DEFINE_TEST_MAIN(LOG_DEBUG);