]>
Commit | Line | Data |
---|---|---|
db9ecf05 | 1 | /* SPDX-License-Identifier: LGPL-2.1-or-later */ |
76917807 | 2 | |
b5d2f4e7 YW |
3 | #include <unistd.h> |
4 | ||
12c2884c | 5 | #include "firewall-util.h" |
b5d2f4e7 | 6 | #include "firewall-util-private.h" |
cf0fbc49 | 7 | #include "log.h" |
0e544221 | 8 | #include "random-util.h" |
b5d2f4e7 | 9 | #include "socket-util.h" |
6d7c4033 | 10 | #include "tests.h" |
76917807 | 11 | |
b5d2f4e7 YW |
12 | static void test_v6(FirewallContext *ctx) { |
13 | union in_addr_union u1, u2, u3; | |
0e544221 FW |
14 | uint8_t prefixlen; |
15 | int r; | |
16 | ||
c0ef4158 LB |
17 | assert_se(ctx); |
18 | ||
b5d2f4e7 | 19 | log_info("/* %s(backend=%s) */", __func__, firewall_backend_to_string(ctx->backend)); |
0e544221 | 20 | |
b5d2f4e7 YW |
21 | if (!socket_ipv6_is_supported()) |
22 | return log_info("IPv6 is not supported by kernel, skipping tests."); | |
0e544221 | 23 | |
b5d2f4e7 YW |
24 | assert_se(in_addr_from_string(AF_INET6, "dead::beef", &u1) >= 0); |
25 | assert_se(in_addr_from_string(AF_INET6, "1c3::c01d", &u2) >= 0); | |
0e544221 | 26 | |
b5d2f4e7 | 27 | prefixlen = random_u64_range(128 + 1 - 8) + 8; |
87cb1ab6 | 28 | random_bytes(&u3, sizeof(u3)); |
0e544221 | 29 | |
b5d2f4e7 YW |
30 | assert_se(fw_add_masquerade(&ctx, true, AF_INET6, &u1, 128) >= 0); |
31 | assert_se(fw_add_masquerade(&ctx, false, AF_INET6, &u1, 128) >= 0); | |
32 | assert_se(fw_add_masquerade(&ctx, true, AF_INET6, &u1, 64) >= 0); | |
33 | assert_se(fw_add_masquerade(&ctx, false, AF_INET6, &u1, 64) >= 0); | |
34 | assert_se(fw_add_masquerade(&ctx, true, AF_INET6, &u3, prefixlen) >= 0); | |
35 | assert_se(fw_add_masquerade(&ctx, false, AF_INET6, &u3, prefixlen) >= 0); | |
0e544221 | 36 | |
b5d2f4e7 YW |
37 | r = fw_add_local_dnat(&ctx, true, AF_INET6, IPPROTO_TCP, 4711, &u1, 815, NULL); |
38 | if (r == -EOPNOTSUPP) { | |
39 | log_info("IPv6 DNAT seems not supported, skipping the following tests."); | |
40 | return; | |
41 | } | |
42 | assert_se(r >= 0); | |
0e544221 | 43 | |
b5d2f4e7 YW |
44 | assert_se(fw_add_local_dnat(&ctx, true, AF_INET6, IPPROTO_TCP, 4711, &u2, 815, &u1) >= 0); |
45 | assert_se(fw_add_local_dnat(&ctx, false, AF_INET6, IPPROTO_TCP, 4711, &u2, 815, NULL) >= 0); | |
0e544221 | 46 | |
b5d2f4e7 | 47 | } |
0e544221 | 48 | |
b5d2f4e7 | 49 | static union in_addr_union *parse_addr(const char *str, union in_addr_union *u) { |
f21b863e YW |
50 | assert_se(str); |
51 | assert_se(u); | |
b5d2f4e7 YW |
52 | assert_se(in_addr_from_string(AF_INET, str, u) >= 0); |
53 | return u; | |
0e544221 FW |
54 | } |
55 | ||
b5d2f4e7 YW |
56 | static bool test_v4(FirewallContext *ctx) { |
57 | union in_addr_union u, v; | |
76917807 | 58 | int r; |
76917807 | 59 | |
c0ef4158 LB |
60 | assert_se(ctx); |
61 | ||
b5d2f4e7 YW |
62 | log_info("/* %s(backend=%s) */", __func__, firewall_backend_to_string(ctx->backend)); |
63 | ||
ecb4b08c YW |
64 | #if HAVE_LIBIPTC |
65 | if (ctx->backend == FW_BACKEND_IPTABLES && fw_iptables_init_nat(NULL) < 0) { | |
66 | log_debug("iptables backend is used, but nat table is not enabled, skipping tests"); | |
67 | return false; | |
68 | } | |
69 | #endif | |
70 | ||
b5d2f4e7 YW |
71 | assert_se(fw_add_masquerade(&ctx, true, AF_INET, NULL, 0) == -EINVAL); |
72 | assert_se(fw_add_masquerade(&ctx, true, AF_INET, parse_addr("10.1.2.0", &u), 0) == -EINVAL); | |
73 | ||
74 | r = fw_add_masquerade(&ctx, true, AF_INET, parse_addr("10.1.2.3", &u), 32); | |
75 | if (r < 0) { | |
76 | bool ignore = IN_SET(r, -EPERM, -EOPNOTSUPP, -ENOPROTOOPT); | |
761cf19d | 77 | |
b5d2f4e7 YW |
78 | log_full_errno(ignore ? LOG_DEBUG : LOG_ERR, r, |
79 | "Failed to add IPv4 masquerade%s: %m", | |
80 | ignore ? ", skipping following tests" : ""); | |
47ed20e1 | 81 | |
b5d2f4e7 YW |
82 | if (ignore) |
83 | return false; | |
84 | } | |
f21b863e | 85 | assert_se(r >= 0); |
47ed20e1 | 86 | |
b5d2f4e7 YW |
87 | assert_se(fw_add_masquerade(&ctx, true, AF_INET, parse_addr("10.0.2.0", &u), 28) >= 0); |
88 | assert_se(fw_add_masquerade(&ctx, false, AF_INET, parse_addr("10.0.2.0", &u), 28) >= 0); | |
89 | assert_se(fw_add_masquerade(&ctx, false, AF_INET, parse_addr("10.1.2.3", &u), 32) >= 0); | |
90 | assert_se(fw_add_local_dnat(&ctx, true, AF_INET, IPPROTO_TCP, 4711, parse_addr("1.2.3.4", &u), 815, NULL) >= 0); | |
91 | assert_se(fw_add_local_dnat(&ctx, true, AF_INET, IPPROTO_TCP, 4711, parse_addr("1.2.3.4", &u), 815, NULL) >= 0); | |
92 | assert_se(fw_add_local_dnat(&ctx, true, AF_INET, IPPROTO_TCP, 4711, parse_addr("1.2.3.5", &u), 815, parse_addr("1.2.3.4", &v)) >= 0); | |
93 | assert_se(fw_add_local_dnat(&ctx, false, AF_INET, IPPROTO_TCP, 4711, parse_addr("1.2.3.5", &u), 815, NULL) >= 0); | |
76917807 | 94 | |
b5d2f4e7 YW |
95 | return true; |
96 | } | |
47ed20e1 | 97 | |
b5d2f4e7 YW |
98 | int main(int argc, char *argv[]) { |
99 | _cleanup_(fw_ctx_freep) FirewallContext *ctx = NULL; | |
76917807 | 100 | |
b5d2f4e7 | 101 | test_setup_logging(LOG_DEBUG); |
76917807 | 102 | |
b5d2f4e7 YW |
103 | if (getuid() != 0) |
104 | return log_tests_skipped("not root"); | |
76917807 | 105 | |
b5d2f4e7 | 106 | assert_se(fw_ctx_new(&ctx) >= 0); |
c0ef4158 | 107 | assert_se(ctx); |
76917807 | 108 | |
b5d2f4e7 | 109 | if (ctx->backend == FW_BACKEND_NONE) |
84a594f4 | 110 | return log_tests_skipped("no firewall backend supported"); |
76917807 | 111 | |
b5d2f4e7 YW |
112 | if (test_v4(ctx) && ctx->backend == FW_BACKEND_NFTABLES) |
113 | test_v6(ctx); | |
76917807 | 114 | |
b5d2f4e7 YW |
115 | #if HAVE_LIBIPTC |
116 | if (ctx->backend != FW_BACKEND_IPTABLES) { | |
117 | ctx->backend = FW_BACKEND_IPTABLES; | |
118 | test_v4(ctx); | |
119 | } | |
120 | #endif | |
0e544221 | 121 | |
76917807 LP |
122 | return 0; |
123 | } |