/* SPDX-License-Identifier: LGPL-2.1-or-later */
/***
  Copyright © 2014 Intel Corporation. All rights reserved.
***/

#include <netinet/icmp6.h>
#include <netinet/in.h>

#include "sd-ndisc.h"

#include "alloc-util.h"
#include "event-util.h"
#include "fd-util.h"
#include "icmp6-util.h"
#include "in-addr-util.h"
#include "memory-util.h"
#include "ndisc-internal.h"
#include "ndisc-router.h"
#include "network-common.h"
#include "random-util.h"
#include "socket-util.h"
#include "string-table.h"
#include "string-util.h"

#define NDISC_TIMEOUT_NO_RA_USEC (NDISC_ROUTER_SOLICITATION_INTERVAL * NDISC_MAX_ROUTER_SOLICITATIONS)

static const char * const ndisc_event_table[_SD_NDISC_EVENT_MAX] = {
        [SD_NDISC_EVENT_TIMEOUT] = "timeout",
        [SD_NDISC_EVENT_ROUTER] = "router",
};

DEFINE_STRING_TABLE_LOOKUP(ndisc_event, sd_ndisc_event_t);

static void ndisc_callback(sd_ndisc *ndisc, sd_ndisc_event_t event, sd_ndisc_router *rt) {
        assert(ndisc);
        assert(event >= 0 && event < _SD_NDISC_EVENT_MAX);

        if (!ndisc->callback)
                return (void) log_ndisc(ndisc, "Received '%s' event.", ndisc_event_to_string(event));

        log_ndisc(ndisc, "Invoking callback for '%s' event.", ndisc_event_to_string(event));
        ndisc->callback(ndisc, event, rt, ndisc->userdata);
}

int sd_ndisc_set_callback(
                sd_ndisc *nd,
                sd_ndisc_callback_t callback,
                void *userdata) {

        assert_return(nd, -EINVAL);

        nd->callback = callback;
        nd->userdata = userdata;

        return 0;
}

int sd_ndisc_set_ifindex(sd_ndisc *nd, int ifindex) {
        assert_return(nd, -EINVAL);
        assert_return(ifindex > 0, -EINVAL);
        assert_return(nd->fd < 0, -EBUSY);

        nd->ifindex = ifindex;
        return 0;
}

int sd_ndisc_set_ifname(sd_ndisc *nd, const char *ifname) {
        assert_return(nd, -EINVAL);
        assert_return(ifname, -EINVAL);

        if (!ifname_valid_full(ifname, IFNAME_VALID_ALTERNATIVE))
                return -EINVAL;

        return free_and_strdup(&nd->ifname, ifname);
}

int sd_ndisc_get_ifname(sd_ndisc *nd, const char **ret) {
        int r;

        assert_return(nd, -EINVAL);

        r = get_ifname(nd->ifindex, &nd->ifname);
        if (r < 0)
                return r;

        if (ret)
                *ret = nd->ifname;

        return 0;
}

int sd_ndisc_set_mac(sd_ndisc *nd, const struct ether_addr *mac_addr) {
        assert_return(nd, -EINVAL);

        if (mac_addr)
                nd->mac_addr = *mac_addr;
        else
                zero(nd->mac_addr);

        return 0;
}

int sd_ndisc_attach_event(sd_ndisc *nd, sd_event *event, int64_t priority) {
        int r;

        assert_return(nd, -EINVAL);
        assert_return(nd->fd < 0, -EBUSY);
        assert_return(!nd->event, -EBUSY);

        if (event)
                nd->event = sd_event_ref(event);
        else {
                r = sd_event_default(&nd->event);
                if (r < 0)
                        return 0;
        }

        nd->event_priority = priority;

        return 0;
}

int sd_ndisc_detach_event(sd_ndisc *nd) {

        assert_return(nd, -EINVAL);
        assert_return(nd->fd < 0, -EBUSY);

        nd->event = sd_event_unref(nd->event);
        return 0;
}

sd_event *sd_ndisc_get_event(sd_ndisc *nd) {
        assert_return(nd, NULL);

        return nd->event;
}

static void ndisc_reset(sd_ndisc *nd) {
        assert(nd);

        (void) event_source_disable(nd->timeout_event_source);
        (void) event_source_disable(nd->timeout_no_ra);
        nd->retransmit_time = 0;
        nd->recv_event_source = sd_event_source_disable_unref(nd->recv_event_source);
        nd->fd = safe_close(nd->fd);
}

static sd_ndisc *ndisc_free(sd_ndisc *nd) {
        assert(nd);

        ndisc_reset(nd);

        sd_event_source_unref(nd->timeout_event_source);
        sd_event_source_unref(nd->timeout_no_ra);
        sd_ndisc_detach_event(nd);

        free(nd->ifname);
        return mfree(nd);
}

DEFINE_PUBLIC_TRIVIAL_REF_UNREF_FUNC(sd_ndisc, sd_ndisc, ndisc_free);

int sd_ndisc_new(sd_ndisc **ret) {
        _cleanup_(sd_ndisc_unrefp) sd_ndisc *nd = NULL;

        assert_return(ret, -EINVAL);

        nd = new(sd_ndisc, 1);
        if (!nd)
                return -ENOMEM;

        *nd = (sd_ndisc) {
                .n_ref = 1,
                .fd = -EBADF,
        };

        *ret = TAKE_PTR(nd);

        return 0;
}

static int ndisc_handle_datagram(sd_ndisc *nd, sd_ndisc_router *rt) {
        int r;

        assert(nd);
        assert(rt);

        r = ndisc_router_parse(nd, rt);
        if (r < 0)
                return r;

        log_ndisc(nd, "Received Router Advertisement: flags %s preference %s lifetime %" PRIu16 " sec",
                  rt->flags & ND_RA_FLAG_MANAGED ? "MANAGED" : rt->flags & ND_RA_FLAG_OTHER ? "OTHER" : "none",
                  rt->preference == SD_NDISC_PREFERENCE_HIGH ? "high" : rt->preference == SD_NDISC_PREFERENCE_LOW ? "low" : "medium",
                  rt->lifetime);

        ndisc_callback(nd, SD_NDISC_EVENT_ROUTER, rt);
        return 0;
}

static int ndisc_recv(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
        _cleanup_(sd_ndisc_router_unrefp) sd_ndisc_router *rt = NULL;
        sd_ndisc *nd = ASSERT_PTR(userdata);
        ssize_t buflen;
        int r;

        assert(s);
        assert(nd->event);

        buflen = next_datagram_size_fd(fd);
        if (buflen < 0) {
                if (ERRNO_IS_TRANSIENT(buflen) || ERRNO_IS_DISCONNECT(buflen))
                        return 0;

                log_ndisc_errno(nd, buflen, "Failed to determine datagram size to read, ignoring: %m");
                return 0;
        }

        rt = ndisc_router_new(buflen);
        if (!rt)
                return -ENOMEM;

        r = icmp6_receive(fd, NDISC_ROUTER_RAW(rt), rt->raw_size, &rt->address, &rt->timestamp);
        if (r < 0) {
                if (ERRNO_IS_TRANSIENT(r) || ERRNO_IS_DISCONNECT(r))
                        return 0;

                switch (r) {
                case -EADDRNOTAVAIL:
                        log_ndisc(nd, "Received RA from non-link-local address %s. Ignoring.",
                                  IN6_ADDR_TO_STRING(&rt->address));
                        break;

                case -EMULTIHOP:
                        log_ndisc(nd, "Received RA with invalid hop limit. Ignoring.");
                        break;

                case -EPFNOSUPPORT:
                        log_ndisc(nd, "Received invalid source address from ICMPv6 socket. Ignoring.");
                        break;

                default:
                        log_ndisc_errno(nd, r, "Unexpected error while reading from ICMPv6, ignoring: %m");
                        break;
                }

                return 0;
        }

        (void) event_source_disable(nd->timeout_event_source);
        (void) ndisc_handle_datagram(nd, rt);
        return 0;
}

static usec_t ndisc_timeout_compute_random(usec_t val) {
        /* compute a time that is random within ±10% of the given value */
        return val - val / 10 +
                (random_u64() % (2 * USEC_PER_SEC)) * val / 10 / USEC_PER_SEC;
}

static int ndisc_timeout(sd_event_source *s, uint64_t usec, void *userdata) {
        sd_ndisc *nd = ASSERT_PTR(userdata);
        usec_t time_now;
        int r;

        assert(s);
        assert(nd->event);

        assert_se(sd_event_now(nd->event, CLOCK_BOOTTIME, &time_now) >= 0);

        if (!nd->retransmit_time)
                nd->retransmit_time = ndisc_timeout_compute_random(NDISC_ROUTER_SOLICITATION_INTERVAL);
        else {
                if (nd->retransmit_time > NDISC_MAX_ROUTER_SOLICITATION_INTERVAL / 2)
                        nd->retransmit_time = ndisc_timeout_compute_random(NDISC_MAX_ROUTER_SOLICITATION_INTERVAL);
                else
                        nd->retransmit_time += ndisc_timeout_compute_random(nd->retransmit_time);
        }

        r = event_reset_time(nd->event, &nd->timeout_event_source,
                             CLOCK_BOOTTIME,
                             time_now + nd->retransmit_time, 10 * USEC_PER_MSEC,
                             ndisc_timeout, nd,
                             nd->event_priority, "ndisc-timeout-no-ra", true);
        if (r < 0)
                goto fail;

        r = icmp6_send_router_solicitation(nd->fd, &nd->mac_addr);
        if (r < 0)
                log_ndisc_errno(nd, r, "Failed to send Router Solicitation, next solicitation in %s, ignoring: %m",
                                FORMAT_TIMESPAN(nd->retransmit_time, USEC_PER_SEC));
        else
                log_ndisc(nd, "Sent Router Solicitation, next solicitation in %s",
                          FORMAT_TIMESPAN(nd->retransmit_time, USEC_PER_SEC));

        return 0;

fail:
        (void) sd_ndisc_stop(nd);
        return 0;
}

static int ndisc_timeout_no_ra(sd_event_source *s, uint64_t usec, void *userdata) {
        sd_ndisc *nd = ASSERT_PTR(userdata);

        assert(s);

        log_ndisc(nd, "No RA received before link confirmation timeout");

        (void) event_source_disable(nd->timeout_no_ra);
        ndisc_callback(nd, SD_NDISC_EVENT_TIMEOUT, NULL);

        return 0;
}

int sd_ndisc_stop(sd_ndisc *nd) {
        if (!nd)
                return 0;

        if (nd->fd < 0)
                return 0;

        log_ndisc(nd, "Stopping IPv6 Router Solicitation client");

        ndisc_reset(nd);
        return 1;
}

int sd_ndisc_start(sd_ndisc *nd) {
        int r;
        usec_t time_now;

        assert_return(nd, -EINVAL);
        assert_return(nd->event, -EINVAL);
        assert_return(nd->ifindex > 0, -EINVAL);

        if (nd->fd >= 0)
                return 0;

        assert(!nd->recv_event_source);

        r = sd_event_now(nd->event, CLOCK_BOOTTIME, &time_now);
        if (r < 0)
                goto fail;

        nd->fd = icmp6_bind_router_solicitation(nd->ifindex);
        if (nd->fd < 0)
                return nd->fd;

        r = sd_event_add_io(nd->event, &nd->recv_event_source, nd->fd, EPOLLIN, ndisc_recv, nd);
        if (r < 0)
                goto fail;

        r = sd_event_source_set_priority(nd->recv_event_source, nd->event_priority);
        if (r < 0)
                goto fail;

        (void) sd_event_source_set_description(nd->recv_event_source, "ndisc-receive-message");

        r = event_reset_time(nd->event, &nd->timeout_event_source,
                             CLOCK_BOOTTIME,
                             time_now + USEC_PER_SEC / 2, 1 * USEC_PER_SEC, /* See RFC 8415 sec. 18.2.1 */
                             ndisc_timeout, nd,
                             nd->event_priority, "ndisc-timeout", true);
        if (r < 0)
                goto fail;

        r = event_reset_time(nd->event, &nd->timeout_no_ra,
                             CLOCK_BOOTTIME,
                             time_now + NDISC_TIMEOUT_NO_RA_USEC, 10 * USEC_PER_MSEC,
                             ndisc_timeout_no_ra, nd,
                             nd->event_priority, "ndisc-timeout-no-ra", true);
        if (r < 0)
                goto fail;

        log_ndisc(nd, "Started IPv6 Router Solicitation client");
        return 1;

fail:
        ndisc_reset(nd);
        return r;
}
