#define UDP_DPORT_OFFSET 2
+void nft_in6addr_to_range(const union in_addr_union *source, unsigned int prefixlen,
+ struct in6_addr *start, struct in6_addr *end);
+
static int nfnl_netlink_sendv(sd_netlink *nfnl,
sd_netlink_message *messages[],
size_t msgcount) {
return 0;
}
-static void nft_in6addr_to_range(const union in_addr_union *source, unsigned int prefixlen,
- struct in6_addr *ret_start, struct in6_addr *ret_end) {
+void nft_in6addr_to_range(const union in_addr_union *source, unsigned int prefixlen,
+ struct in6_addr *ret_start, struct in6_addr *ret_end) {
uint8_t carry = 0;
int i, j;
#define MAKE_IN_ADDR_UNION(a,b,c,d) (union in_addr_union) { .in.s_addr = htobe32((uint32_t) (a) << 24 | (uint32_t) (b) << 16 | (uint32_t) (c) << 8 | (uint32_t) (d))}
+void nft_in6addr_to_range(const union in_addr_union *source, unsigned int prefixlen,
+ struct in6_addr *start, struct in6_addr *end);
+
static void make_in6_addr_union(const char *addr, union in_addr_union *u) {
assert_se(inet_pton(AF_INET6, addr, &u->in6) >= 0);
}
+static bool test_in6_eq(const char *addr, const union in_addr_union *u) {
+ union in_addr_union tmp;
+
+ make_in6_addr_union(addr, &tmp);
+
+ return memcmp(&tmp.in6, &u->in6, sizeof(tmp.in6)) == 0;
+}
+
+static void assert_in6_eq(const union in_addr_union *a, const union in_addr_union *b) {
+ assert_se(memcmp(&a->in6, &b->in6, sizeof(a->in6)) == 0);
+}
+
static void test_v6(FirewallContext **ctx) {
union in_addr_union u = {}, u2 = {};
uint8_t prefixlen;
log_error_errno(r, "Failed to modify ipv6 firewall: %m");
}
+static void test_v6_range(void) {
+ unsigned int prefixlen = 64;
+ union in_addr_union a, b, s;
+
+ make_in6_addr_union("dead:0:0:beef::", &s);
+
+ nft_in6addr_to_range(&s, prefixlen, &a.in6, &b.in6);
+
+ assert_in6_eq(&s, &a);
+ assert_se(test_in6_eq("dead:0:0:bef0::", &b));
+
+ make_in6_addr_union("2001::", &s);
+ prefixlen = 56;
+ nft_in6addr_to_range(&s, prefixlen, &a.in6, &b.in6);
+ assert_in6_eq(&s, &a);
+ assert_se(test_in6_eq("2001:0:0:0100::", &b));
+
+ prefixlen = 48;
+ nft_in6addr_to_range(&s, prefixlen, &a.in6, &b.in6);
+ assert_in6_eq(&s, &a);
+
+ assert_se(test_in6_eq("2001:0:0001::", &b));
+
+ prefixlen = 65;
+ nft_in6addr_to_range(&s, prefixlen, &a.in6, &b.in6);
+ assert_se(test_in6_eq("2001::", &a));
+
+ assert_se(test_in6_eq("2001::8000:0:0:0", &b));
+
+ prefixlen = 66;
+ nft_in6addr_to_range(&s, prefixlen, &a.in6, &b.in6);
+ assert_in6_eq(&s, &a);
+
+ assert_se(test_in6_eq("2001::4000:0:0:0", &b));
+
+ prefixlen = 127;
+ nft_in6addr_to_range(&s, prefixlen, &a.in6, &b.in6);
+ assert_in6_eq(&s, &a);
+ assert_se(test_in6_eq("2001::0002", &b));
+
+ make_in6_addr_union("dead:beef::1", &s);
+ prefixlen = 64;
+ nft_in6addr_to_range(&s, prefixlen, &a.in6, &b.in6);
+ assert_se(test_in6_eq("dead:beef::", &a));
+}
+
int main(int argc, char *argv[]) {
_cleanup_(fw_ctx_freep) FirewallContext *ctx;
int r;
log_error_errno(r, "Failed to modify firewall: %m");
test_v6(&ctx);
+ test_v6_range();
return 0;
}