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

#include <arpa/inet.h>
#include <errno.h>
#include <net/if.h>
#include <string.h>

#include "alloc-util.h"
#include "errno-util.h"
#include "extract-word.h"
#include "log.h"
#include "memory-util.h"
#include "netlink-util.h"
#include "parse-util.h"
#include "socket-netlink.h"
#include "socket-util.h"
#include "string-util.h"

int socket_address_parse(SocketAddress *a, const char *s) {
        _cleanup_free_ char *n = NULL;
        char *e;
        int r;

        assert(a);
        assert(s);

        if (IN_SET(*s, '/', '@')) {
                /* AF_UNIX socket */
                struct sockaddr_un un;

                r = sockaddr_un_set_path(&un, s);
                if (r < 0)
                        return r;

                *a = (SocketAddress) {
                        .sockaddr.un = un,
                        .size = r,
                };

        } else if (startswith(s, "vsock:")) {
                /* AF_VSOCK socket in vsock:cid:port notation */
                const char *cid_start = s + STRLEN("vsock:");
                unsigned port, cid;

                e = strchr(cid_start, ':');
                if (!e)
                        return -EINVAL;

                r = safe_atou(e+1, &port);
                if (r < 0)
                        return r;

                n = strndup(cid_start, e - cid_start);
                if (!n)
                        return -ENOMEM;

                if (isempty(n))
                        cid = VMADDR_CID_ANY;
                else {
                        r = safe_atou(n, &cid);
                        if (r < 0)
                                return r;
                }

                *a = (SocketAddress) {
                        .sockaddr.vm = {
                                .svm_cid = cid,
                                .svm_family = AF_VSOCK,
                                .svm_port = port,
                        },
                        .size = sizeof(struct sockaddr_vm),
                };

        } else {
                uint16_t port;

                r = parse_ip_port(s, &port);
                if (r == -ERANGE)
                        return r; /* Valid port syntax, but the numerical value is wrong for a port. */
                if (r >= 0) {
                        /* Just a port */
                        if (socket_ipv6_is_supported())
                                *a = (SocketAddress) {
                                        .sockaddr.in6 = {
                                                .sin6_family = AF_INET6,
                                                .sin6_port = htobe16(port),
                                                .sin6_addr = in6addr_any,
                                        },
                                        .size = sizeof(struct sockaddr_in6),
                                };
                        else
                                *a = (SocketAddress) {
                                        .sockaddr.in = {
                                                .sin_family = AF_INET,
                                                .sin_port = htobe16(port),
                                                .sin_addr.s_addr = INADDR_ANY,
                                        },
                                        .size = sizeof(struct sockaddr_in),
                                };

                } else {
                        union in_addr_union address;
                        int family, ifindex;

                        r = in_addr_port_ifindex_name_from_string_auto(s, &family, &address, &port, &ifindex, NULL);
                        if (r < 0)
                                return r;

                        if (port == 0) /* No port, no go. */
                                return -EINVAL;

                        if (family == AF_INET)
                                *a = (SocketAddress) {
                                        .sockaddr.in = {
                                                .sin_family = AF_INET,
                                                .sin_addr = address.in,
                                                .sin_port = htobe16(port),
                                        },
                                        .size = sizeof(struct sockaddr_in),
                                };
                        else if (family == AF_INET6)
                                *a = (SocketAddress) {
                                        .sockaddr.in6 = {
                                                .sin6_family = AF_INET6,
                                                .sin6_addr = address.in6,
                                                .sin6_port = htobe16(port),
                                                .sin6_scope_id = ifindex,
                                        },
                                        .size = sizeof(struct sockaddr_in6),
                                };
                        else
                                assert_not_reached("Family quarrel");
                }
        }

        return 0;
}

int socket_address_parse_and_warn(SocketAddress *a, const char *s) {
        SocketAddress b;
        int r;

        /* Similar to socket_address_parse() but warns for IPv6 sockets when we don't support them. */

        r = socket_address_parse(&b, s);
        if (r < 0)
                return r;

        if (!socket_ipv6_is_supported() && b.sockaddr.sa.sa_family == AF_INET6) {
                log_warning("Binding to IPv6 address not available since kernel does not support IPv6.");
                return -EAFNOSUPPORT;
        }

        *a = b;
        return 0;
}

int socket_address_parse_netlink(SocketAddress *a, const char *s) {
        _cleanup_free_ char *word = NULL;
        unsigned group = 0;
        int family, r;

        assert(a);
        assert(s);

        r = extract_first_word(&s, &word, NULL, 0);
        if (r < 0)
                return r;
        if (r == 0)
                return -EINVAL;

        family = netlink_family_from_string(word);
        if (family < 0)
                return -EINVAL;

        if (!isempty(s)) {
                r = safe_atou(s, &group);
                if (r < 0)
                        return r;
        }

        *a = (SocketAddress) {
                .type = SOCK_RAW,
                .sockaddr.nl.nl_family = AF_NETLINK,
                .sockaddr.nl.nl_groups = group,
                .protocol = family,
                .size = sizeof(struct sockaddr_nl),
        };

        return 0;
}

bool socket_address_is(const SocketAddress *a, const char *s, int type) {
        struct SocketAddress b;

        assert(a);
        assert(s);

        if (socket_address_parse(&b, s) < 0)
                return false;

        b.type = type;

        return socket_address_equal(a, &b);
}

bool socket_address_is_netlink(const SocketAddress *a, const char *s) {
        struct SocketAddress b;

        assert(a);
        assert(s);

        if (socket_address_parse_netlink(&b, s) < 0)
                return false;

        return socket_address_equal(a, &b);
}

int make_socket_fd(int log_level, const char* address, int type, int flags) {
        SocketAddress a;
        int fd, r;

        r = socket_address_parse(&a, address);
        if (r < 0)
                return log_error_errno(r, "Failed to parse socket address \"%s\": %m", address);

        a.type = type;

        fd = socket_address_listen(&a, type | flags, SOMAXCONN, SOCKET_ADDRESS_DEFAULT,
                                   NULL, false, false, false, 0755, 0644, NULL);
        if (fd < 0 || log_get_max_level() >= log_level) {
                _cleanup_free_ char *p = NULL;

                r = socket_address_print(&a, &p);
                if (r < 0)
                        return log_error_errno(r, "socket_address_print(): %m");

                if (fd < 0)
                        log_error_errno(fd, "Failed to listen on %s: %m", p);
                else
                        log_full(log_level, "Listening on %s", p);
        }

        return fd;
}

int in_addr_port_ifindex_name_from_string_auto(
                const char *s,
                int *ret_family,
                union in_addr_union *ret_address,
                uint16_t *ret_port,
                int *ret_ifindex,
                char **ret_server_name) {

        _cleanup_free_ char *buf1 = NULL, *buf2 = NULL, *name = NULL;
        int family, ifindex = 0, r;
        union in_addr_union a;
        uint16_t port = 0;
        const char *m;

        assert(s);

        /* This accepts the following:
         * 192.168.0.1:53#example.com
         * [2001:4860:4860::8888]:53%eth0#example.com
         *
         * If ret_port is NULL, then the port cannot be specified.
         * If ret_ifindex is NULL, then the interface index cannot be specified.
         * If ret_server_name is NULL, then server_name cannot be specified.
         *
         * ret_family is always AF_INET or AF_INET6.
         */

        m = strchr(s, '#');
        if (m) {
                if (!ret_server_name)
                        return -EINVAL;

                if (isempty(m + 1))
                        return -EINVAL;

                name = strdup(m + 1);
                if (!name)
                        return -ENOMEM;

                s = buf1 = strndup(s, m - s);
                if (!buf1)
                        return -ENOMEM;
        }

        m = strchr(s, '%');
        if (m) {
                if (!ret_ifindex)
                        return -EINVAL;

                if (isempty(m + 1))
                        return -EINVAL;

                if (!ifname_valid_full(m + 1, IFNAME_VALID_ALTERNATIVE | IFNAME_VALID_NUMERIC))
                        return -EINVAL; /* We want to return -EINVAL for syntactically invalid names,
                                         * and -ENODEV for valid but nonexistent interfaces. */

                ifindex = rtnl_resolve_interface(NULL, m + 1);
                if (ifindex < 0)
                        return ifindex;

                s = buf2 = strndup(s, m - s);
                if (!buf2)
                        return -ENOMEM;
        }

        m = strrchr(s, ':');
        if (m) {
                if (*s == '[') {
                        _cleanup_free_ char *ip_str = NULL;

                        if (!ret_port)
                                return -EINVAL;

                        if (*(m - 1) != ']')
                                return -EINVAL;

                        family = AF_INET6;

                        r = parse_ip_port(m + 1, &port);
                        if (r < 0)
                                return r;

                        ip_str = strndup(s + 1, m - s - 2);
                        if (!ip_str)
                                return -ENOMEM;

                        r = in_addr_from_string(family, ip_str, &a);
                        if (r < 0)
                                return r;
                } else {
                        /* First try to parse the string as IPv6 address without port number */
                        r = in_addr_from_string(AF_INET6, s, &a);
                        if (r < 0) {
                                /* Then the input should be IPv4 address with port number */
                                _cleanup_free_ char *ip_str = NULL;

                                if (!ret_port)
                                        return -EINVAL;

                                family = AF_INET;

                                ip_str = strndup(s, m - s);
                                if (!ip_str)
                                        return -ENOMEM;

                                r = in_addr_from_string(family, ip_str, &a);
                                if (r < 0)
                                        return r;

                                r = parse_ip_port(m + 1, &port);
                                if (r < 0)
                                        return r;
                        } else
                                family = AF_INET6;
                }
        } else {
                family = AF_INET;
                r = in_addr_from_string(family, s, &a);
                if (r < 0)
                        return r;
        }

        if (ret_family)
                *ret_family = family;
        if (ret_address)
                *ret_address = a;
        if (ret_port)
                *ret_port = port;
        if (ret_ifindex)
                *ret_ifindex = ifindex;
        if (ret_server_name)
                *ret_server_name = TAKE_PTR(name);

        return r;
}

struct in_addr_full *in_addr_full_free(struct in_addr_full *a) {
        if (!a)
                return NULL;

        free(a->server_name);
        free(a->cached_server_string);
        return mfree(a);
}

int in_addr_full_new(
                int family,
                const union in_addr_union *a,
                uint16_t port,
                int ifindex,
                const char *server_name,
                struct in_addr_full **ret) {

        _cleanup_free_ char *name = NULL;
        struct in_addr_full *x;

        assert(ret);

        if (!isempty(server_name)) {
                name = strdup(server_name);
                if (!name)
                        return -ENOMEM;
        }

        x = new(struct in_addr_full, 1);
        if (!x)
                return -ENOMEM;

        *x = (struct in_addr_full) {
                .family = family,
                .address = *a,
                .port = port,
                .ifindex = ifindex,
                .server_name = TAKE_PTR(name),
        };

        *ret = x;
        return 0;
}

int in_addr_full_new_from_string(const char *s, struct in_addr_full **ret) {
        _cleanup_free_ char *server_name = NULL;
        int family, ifindex, r;
        union in_addr_union a;
        uint16_t port;

        assert(s);

        r = in_addr_port_ifindex_name_from_string_auto(s, &family, &a, &port, &ifindex, &server_name);
        if (r < 0)
                return r;

        return in_addr_full_new(family, &a, port, ifindex, server_name, ret);
}

const char *in_addr_full_to_string(struct in_addr_full *a) {
        assert(a);

        if (!a->cached_server_string)
                (void) in_addr_port_ifindex_name_to_string(
                                a->family,
                                &a->address,
                                a->port,
                                a->ifindex,
                                a->server_name,
                                &a->cached_server_string);

        return a->cached_server_string;
}
