/* SPDX-License-Identifier: LGPL-2.1-or-later */

#include "alloc-util.h"
#include "extract-word.h"
#include "hostname-util.h"
#include "in-addr-prefix-util.h"
#include "string-util.h"

/* 0.0.0.0/0 */
#define IN_ADDR_PREFIX_IPV4_ANY ((struct in_addr_prefix) { .family = AF_INET })
/* ::/0 */
#define IN_ADDR_PREFIX_IPV6_ANY ((struct in_addr_prefix) { .family = AF_INET6 })
/* 127.0.0.0/8 */
#define IN_ADDR_PREFIX_IPV4_LOCALHOST                                   \
        ((struct in_addr_prefix) {                                      \
                .family = AF_INET,                                      \
                .address.in.s_addr = htobe32(UINT32_C(127) << 24),      \
                .prefixlen = 8,                                         \
        })
/* ::1/128 */
#define IN_ADDR_PREFIX_IPV6_LOCALHOST                                   \
        ((struct in_addr_prefix) {                                      \
                .family = AF_INET6,                                     \
                .address.in6 = IN6ADDR_LOOPBACK_INIT,                   \
                .prefixlen = 128,                                       \
        })
/* 169.254.0.0/16 */
#define IN_ADDR_PREFIX_IPV4_LINKLOCAL                                   \
        ((struct in_addr_prefix) {                                      \
                .family = AF_INET,                                      \
                .address.in.s_addr = htobe32((UINT32_C(169) << 24) |    \
                                             (UINT32_C(254) << 16)),    \
                .prefixlen = 16,                                        \
        })
/* fe80::/64 */
#define IN_ADDR_PREFIX_IPV6_LINKLOCAL                                   \
        ((struct in_addr_prefix) {                                      \
                .family = AF_INET6,                                     \
                .address.in6.s6_addr[0] = 0xfe,                         \
                .address.in6.s6_addr[1] = 0x80,                         \
                .prefixlen = 64,                                        \
        })
/* 224.0.0.0/4 */
#define IN_ADDR_PREFIX_IPV4_MULTICAST                                   \
        ((struct in_addr_prefix) {                                      \
                .family = AF_INET,                                      \
                .address.in.s_addr = htobe32((UINT32_C(224) << 24)),    \
                .prefixlen = 4,                                         \
        })
/* ff00::/8 */
#define IN_ADDR_PREFIX_IPV6_MULTICAST                                   \
        ((struct in_addr_prefix) {                                      \
                .family = AF_INET6,                                     \
                .address.in6.s6_addr[0] = 0xff,                         \
                .prefixlen = 8,                                         \
        })

static void in_addr_prefix_hash_func(const struct in_addr_prefix *a, struct siphash *state) {
        assert(a);
        assert(state);

        siphash24_compress(&a->family, sizeof(a->family), state);
        siphash24_compress(&a->prefixlen, sizeof(a->prefixlen), state);
        siphash24_compress(&a->address, FAMILY_ADDRESS_SIZE(a->family), state);
}

static int in_addr_prefix_compare_func(const struct in_addr_prefix *x, const struct in_addr_prefix *y) {
        int r;

        assert(x);
        assert(y);

        r = CMP(x->family, y->family);
        if (r != 0)
                return r;

        r = CMP(x->prefixlen, y->prefixlen);
        if (r != 0)
                return r;

        return memcmp(&x->address, &y->address, FAMILY_ADDRESS_SIZE(x->family));
}

DEFINE_HASH_OPS(in_addr_prefix_hash_ops, struct in_addr_prefix, in_addr_prefix_hash_func, in_addr_prefix_compare_func);
DEFINE_HASH_OPS_WITH_KEY_DESTRUCTOR(in_addr_prefix_hash_ops_free, struct in_addr_prefix, in_addr_prefix_hash_func, in_addr_prefix_compare_func, free);

int in_addr_prefix_add(Set **prefixes, const struct in_addr_prefix *prefix) {
        struct in_addr_prefix *copy;

        assert(prefixes);
        assert(prefix);
        assert(IN_SET(prefix->family, AF_INET, AF_INET6));

        copy = newdup(struct in_addr_prefix, prefix, 1);
        if (!copy)
                return -ENOMEM;

        (void) in_addr_mask(copy->family, &copy->address, copy->prefixlen);
        return set_ensure_consume(prefixes, &in_addr_prefix_hash_ops_free, copy);
}

int in_addr_prefixes_reduce(Set *prefixes) {
        uint32_t ipv4_prefixlen_bits = 0;
        uint64_t ipv6_prefixlen_bits[128 / sizeof(uint64_t)] = {};
        uint8_t ipv4_prefixlens[32] = {}, ipv6_prefixlens[128] = {};
        bool ipv4_has_any = false, ipv6_has_any = false;
        size_t ipv4_n_prefixlens = 0, ipv6_n_prefixlens = 0;
        struct in_addr_prefix *p;

        SET_FOREACH(p, prefixes)
                switch (p->family) {
                case AF_INET:
                        assert(p->prefixlen <= 32);
                        if (p->prefixlen == 0)
                                ipv4_has_any = true;
                        else
                                ipv4_prefixlen_bits |= UINT32_C(1) << (p->prefixlen - 1);
                        break;
                case AF_INET6:
                        assert(p->prefixlen <= 128);
                        if (p->prefixlen == 0)
                                ipv6_has_any = true;
                        else
                                ipv6_prefixlen_bits[(p->prefixlen - 1) / sizeof(uint64_t)] |=
                                        UINT64_C(1) << ((p->prefixlen - 1) % sizeof(uint64_t));
                        break;
                default:
                        assert_not_reached();
                }

        if (!ipv4_has_any)
                for (size_t i = 0; i < 32; i++)
                        if (ipv4_prefixlen_bits & (UINT32_C(1) << i))
                                ipv4_prefixlens[ipv4_n_prefixlens++] = i + 1;

        if (!ipv6_has_any)
                for (size_t i = 0; i < 128; i++)
                        if (ipv6_prefixlen_bits[i / sizeof(uint64_t)] &
                            (UINT64_C(1) << (i % sizeof(uint64_t))))
                                ipv6_prefixlens[ipv6_n_prefixlens++] = i + 1;

        SET_FOREACH(p, prefixes) {
                uint8_t *prefixlens;
                bool covered;
                size_t *n;

                if (p->prefixlen == 0)
                        continue;

                switch (p->family) {
                case AF_INET:
                        prefixlens = ipv4_prefixlens;
                        n = &ipv4_n_prefixlens;
                        covered = ipv4_has_any;
                        break;
                case AF_INET6:
                        prefixlens = ipv6_prefixlens;
                        n = &ipv6_n_prefixlens;
                        covered = ipv6_has_any;
                        break;
                default:
                        assert_not_reached();
                }

                for (size_t i = 0; i < *n; i++) {
                        struct in_addr_prefix tmp;

                        if (covered)
                                break;

                        if (prefixlens[i] >= p->prefixlen)
                                break;

                        tmp = *p;
                        tmp.prefixlen = prefixlens[i];
                        (void) in_addr_mask(tmp.family, &tmp.address, tmp.prefixlen);

                        covered = set_contains(prefixes, &tmp);
                }

                if (covered)
                        free(set_remove(prefixes, p));
        }

        return 0;
}

int in_addr_prefixes_merge(Set **dest, Set *src) {
        struct in_addr_prefix *p;
        int r;

        assert(dest);

        SET_FOREACH(p, src) {
                r = in_addr_prefix_add(dest, p);
                if (r < 0)
                        return r;
        }

        return 0;
}

bool in_addr_prefixes_is_any(Set *prefixes) {
        return
                set_contains(prefixes, &IN_ADDR_PREFIX_IPV4_ANY) &&
                set_contains(prefixes, &IN_ADDR_PREFIX_IPV6_ANY);
}

int config_parse_in_addr_prefixes(
                const char *unit,
                const char *filename,
                unsigned line,
                const char *section,
                unsigned section_line,
                const char *lvalue,
                int ltype,
                const char *rvalue,
                void *data,
                void *userdata) {

        Set **prefixes = ASSERT_PTR(data);
        int r;

        assert(IN_SET(ltype, AF_UNSPEC, AF_INET, AF_INET6));

        if (isempty(rvalue)) {
                *prefixes = set_free(*prefixes);
                return 0;
        }

        for (const char *p = rvalue;;) {
                _cleanup_free_ char *word = NULL;

                r = extract_first_word(&p, &word, NULL, 0);
                if (r == -ENOMEM)
                        return log_oom();
                if (r < 0) {
                        log_syntax(unit, LOG_WARNING, filename, line, r, "Invalid syntax, ignoring: %s", rvalue);
                        return 0;
                }
                if (r == 0)
                        return 0;

                if (streq(word, "any")) {
                        /* "any" is a shortcut for 0.0.0.0/0 and ::/0 */

                        if (ltype != AF_INET6) {
                                r = in_addr_prefix_add(prefixes, &IN_ADDR_PREFIX_IPV4_ANY);
                                if (r < 0)
                                        return log_oom();
                        }

                        if (ltype != AF_INET) {
                                r = in_addr_prefix_add(prefixes, &IN_ADDR_PREFIX_IPV6_ANY);
                                if (r < 0)
                                        return log_oom();
                        }

                } else if (is_localhost(word)) {
                        /* "localhost" is a shortcut for 127.0.0.0/8 and ::1/128 */

                        if (ltype != AF_INET6) {
                                r = in_addr_prefix_add(prefixes, &IN_ADDR_PREFIX_IPV4_LOCALHOST);
                                if (r < 0)
                                        return log_oom();
                        }

                        if (ltype != AF_INET) {
                                r = in_addr_prefix_add(prefixes, &IN_ADDR_PREFIX_IPV6_LOCALHOST);
                                if (r < 0)
                                        return log_oom();
                        }

                } else if (streq(word, "link-local")) {
                        /* "link-local" is a shortcut for 169.254.0.0/16 and fe80::/64 */

                        if (ltype != AF_INET6) {
                                r = in_addr_prefix_add(prefixes, &IN_ADDR_PREFIX_IPV4_LINKLOCAL);
                                if (r < 0)
                                        return log_oom();
                        }

                        if (ltype != AF_INET) {
                                r = in_addr_prefix_add(prefixes, &IN_ADDR_PREFIX_IPV6_LINKLOCAL);
                                if (r < 0)
                                        return log_oom();
                        }

                } else if (streq(word, "multicast")) {
                        /* "multicast" is a shortcut for 224.0.0.0/4 and ff00::/8 */

                        if (ltype != AF_INET6) {
                                r = in_addr_prefix_add(prefixes, &IN_ADDR_PREFIX_IPV4_MULTICAST);
                                if (r < 0)
                                        return log_oom();
                        }

                        if (ltype != AF_INET) {
                                r = in_addr_prefix_add(prefixes, &IN_ADDR_PREFIX_IPV6_MULTICAST);
                                if (r < 0)
                                        return log_oom();
                        }

                } else {
                        struct in_addr_prefix a;

                        if (ltype == AF_UNSPEC)
                                r = in_addr_prefix_from_string_auto(word, &a.family, &a.address, &a.prefixlen);
                        else {
                                a.family = ltype;
                                r = in_addr_prefix_from_string(word, a.family, &a.address, &a.prefixlen);
                        }
                        if (r < 0) {
                                log_syntax(unit, LOG_WARNING, filename, line, r,
                                           "Address prefix is invalid, ignoring assignment: %s", word);
                                continue;
                        }

                        r = in_addr_prefix_add(prefixes, &a);
                        if (r < 0)
                                return log_oom();
                }
        }
}
