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

#include <errno.h>
#include <inttypes.h>
#include <net/ethernet.h>
#include <stdio.h>
#include <sys/types.h>

#include "ether-addr-util.h"
#include "hexdecoct.h"
#include "macro.h"
#include "string-util.h"

char *hw_addr_to_string_full(
                const struct hw_addr_data *addr,
                HardwareAddressToStringFlags flags,
                char buffer[static HW_ADDR_TO_STRING_MAX]) {

        assert(addr);
        assert(buffer);
        assert(addr->length <= HW_ADDR_MAX_SIZE);

        for (size_t i = 0, j = 0; i < addr->length; i++) {
                buffer[j++] = hexchar(addr->bytes[i] >> 4);
                buffer[j++] = hexchar(addr->bytes[i] & 0x0f);
                if (!FLAGS_SET(flags, HW_ADDR_TO_STRING_NO_COLON))
                        buffer[j++] = ':';
        }

        buffer[addr->length == 0 || FLAGS_SET(flags, HW_ADDR_TO_STRING_NO_COLON) ?
               addr->length * 2 :
               addr->length * 3 - 1] = '\0';
        return buffer;
}

struct hw_addr_data *hw_addr_set(struct hw_addr_data *addr, const uint8_t *bytes, size_t length) {
        assert(addr);
        assert(length <= HW_ADDR_MAX_SIZE);

        addr->length = length;
        memcpy_safe(addr->bytes, bytes, length);
        return addr;
}

int hw_addr_compare(const struct hw_addr_data *a, const struct hw_addr_data *b) {
        int r;

        assert(a);
        assert(b);

        r = CMP(a->length, b->length);
        if (r != 0)
                return r;

        return memcmp(a->bytes, b->bytes, a->length);
}

void hw_addr_hash_func(const struct hw_addr_data *p, struct siphash *state) {
        assert(p);
        assert(state);

        siphash24_compress(&p->length, sizeof(p->length), state);
        siphash24_compress(p->bytes, p->length, state);
}

DEFINE_HASH_OPS(hw_addr_hash_ops, struct hw_addr_data, hw_addr_hash_func, hw_addr_compare);
DEFINE_HASH_OPS_WITH_KEY_DESTRUCTOR(hw_addr_hash_ops_free, struct hw_addr_data, hw_addr_hash_func, hw_addr_compare, free);

char* ether_addr_to_string(const struct ether_addr *addr, char buffer[ETHER_ADDR_TO_STRING_MAX]) {
        assert(addr);
        assert(buffer);

        /* Like ether_ntoa() but uses %02x instead of %x to print
         * ethernet addresses, which makes them look less funny. Also,
         * doesn't use a static buffer. */

        sprintf(buffer, "%02x:%02x:%02x:%02x:%02x:%02x",
                addr->ether_addr_octet[0],
                addr->ether_addr_octet[1],
                addr->ether_addr_octet[2],
                addr->ether_addr_octet[3],
                addr->ether_addr_octet[4],
                addr->ether_addr_octet[5]);

        return buffer;
}

int ether_addr_to_string_alloc(const struct ether_addr *addr, char **ret) {
        char *buf;

        assert(addr);
        assert(ret);

        buf = new(char, ETHER_ADDR_TO_STRING_MAX);
        if (!buf)
                return -ENOMEM;

        ether_addr_to_string(addr, buf);

        *ret = buf;
        return 0;
}

int ether_addr_compare(const struct ether_addr *a, const struct ether_addr *b) {
        return memcmp(a, b, ETH_ALEN);
}

static void ether_addr_hash_func(const struct ether_addr *p, struct siphash *state) {
        siphash24_compress(p, sizeof(struct ether_addr), state);
}

DEFINE_HASH_OPS(ether_addr_hash_ops, struct ether_addr, ether_addr_hash_func, ether_addr_compare);
DEFINE_HASH_OPS_WITH_KEY_DESTRUCTOR(ether_addr_hash_ops_free, struct ether_addr, ether_addr_hash_func, ether_addr_compare, free);

static int parse_hw_addr_one_field(const char **s, char sep, size_t len, uint8_t *buf) {
        const char *hex = HEXDIGITS, *p;
        uint16_t data = 0;
        bool cont;

        assert(s);
        assert(*s);
        assert(IN_SET(len, 1, 2));
        assert(buf);

        p = *s;

        for (size_t i = 0; i < len * 2; i++) {
                const char *hexoff;
                size_t x;

                if (*p == '\0' || *p == sep) {
                        if (i == 0)
                                return -EINVAL;
                        break;
                }

                hexoff = strchr(hex, *p);
                if (!hexoff)
                        return -EINVAL;

                assert(hexoff >= hex);
                x = hexoff - hex;
                if (x >= 16)
                        x -= 6; /* A-F */

                assert(x < 16);
                data <<= 4;
                data += x;

                p++;
        }

        if (*p != '\0' && *p != sep)
                return -EINVAL;

        switch (len) {
        case 1:
                buf[0] = data;
                break;
        case 2:
                buf[0] = (data & 0xff00) >> 8;
                buf[1] = data & 0xff;
                break;
        default:
                assert_not_reached();
        }

        cont = *p == sep;
        *s = p + cont;
        return cont;
}

int parse_hw_addr_full(const char *s, size_t expected_len, struct hw_addr_data *ret) {
        size_t field_size, max_len, len = 0;
        uint8_t bytes[HW_ADDR_MAX_SIZE];
        char sep;
        int r;

        assert(s);
        assert(expected_len <= HW_ADDR_MAX_SIZE || expected_len == SIZE_MAX);
        assert(ret);

        /* This accepts the following formats:
         *
         * Dot separated 2 bytes format: xxyy.zzaa.bbcc
         * Colon separated 1 bytes format: xx:yy:zz:aa:bb:cc
         * Hyphen separated 1 bytes format: xx-yy-zz-aa-bb-cc
         *
         * Moreover, if expected_len == 0, 4, or 16, this also accepts:
         *
         * IPv4 format: used by IPv4 tunnel, e.g. ipgre
         * IPv6 format: used by IPv6 tunnel, e.g. ip6gre
         *
         * The expected_len argument controls the length of acceptable addresses:
         *
         * 0: accepts 4 (AF_INET), 16 (AF_INET6), 6 (ETH_ALEN), or 20 (INFINIBAND_ALEN).
         * SIZE_MAX: accepts arbitrary length, but at least one separator must be included.
         * Otherwise: accepts addresses with matching length.
         */

        if (IN_SET(expected_len, 0, sizeof(struct in_addr), sizeof(struct in6_addr))) {
                union in_addr_union a;
                int family;

                if (expected_len == 0)
                        r = in_addr_from_string_auto(s, &family, &a);
                else {
                        family = expected_len == sizeof(struct in_addr) ? AF_INET : AF_INET6;
                        r = in_addr_from_string(family, s, &a);
                }
                if (r >= 0) {
                        ret->length = FAMILY_ADDRESS_SIZE(family);
                        memcpy(ret->bytes, a.bytes, ret->length);
                        return 0;
                }
        }

        max_len =
                expected_len == 0 ? INFINIBAND_ALEN :
                expected_len == SIZE_MAX ? HW_ADDR_MAX_SIZE : expected_len;
        sep = s[strspn(s, HEXDIGITS)];

        if (sep == '.')
                field_size = 2;
        else if (IN_SET(sep, ':', '-'))
                field_size = 1;
        else
                return -EINVAL;

        if (max_len % field_size != 0)
                return -EINVAL;

        for (size_t i = 0; i < max_len / field_size; i++) {
                r = parse_hw_addr_one_field(&s, sep, field_size, bytes + i * field_size);
                if (r < 0)
                        return r;
                if (r == 0) {
                        len = (i + 1) * field_size;
                        break;
                }
        }

        if (len == 0)
                return -EINVAL;

        if (expected_len == 0) {
                if (!IN_SET(len, 4, 16, ETH_ALEN, INFINIBAND_ALEN))
                        return -EINVAL;
        } else if (expected_len != SIZE_MAX) {
                if (len != expected_len)
                        return -EINVAL;
        }

        ret->length = len;
        memcpy(ret->bytes, bytes, ret->length);
        return 0;
}

int parse_ether_addr(const char *s, struct ether_addr *ret) {
        struct hw_addr_data a;
        int r;

        assert(s);
        assert(ret);

        r = parse_hw_addr_full(s, ETH_ALEN, &a);
        if (r < 0)
                return r;

        *ret = a.ether;
        return 0;
}
