/* SPDX-License-Identifier: BSD-3-Clause */
/*
 * Copyright (c) 2013
 * Guillaume Subiron, Yann Bordenave, Serigne Modou Wagne.
 */

#include "slirp.h"
#include "ip6_icmp.h"

#define NDP_Interval \
    g_rand_int_range(slirp->grand, NDP_MinRtrAdvInterval, NDP_MaxRtrAdvInterval)

void icmp6_post_init(Slirp *slirp)
{
    if (!slirp->in6_enabled) {
        return;
    }

    slirp->ra_timer =
        slirp_timer_new(slirp, SLIRP_TIMER_RA, NULL);
    slirp->cb->timer_mod(slirp->ra_timer,
                         slirp->cb->clock_get_ns(slirp->opaque) / SCALE_MS +
                             NDP_Interval,
                         slirp->opaque);
}

void icmp6_cleanup(Slirp *slirp)
{
    if (!slirp->in6_enabled) {
        return;
    }

    slirp->cb->timer_free(slirp->ra_timer, slirp->opaque);
}

static void icmp6_send_echoreply(struct mbuf *m, Slirp *slirp, struct ip6 *ip,
                                 struct icmp6 *icmp)
{
    struct mbuf *t = m_get(slirp);
    t->m_len = sizeof(struct ip6) + ntohs(ip->ip_pl);
    memcpy(t->m_data, m->m_data, t->m_len);

    /* IPv6 Packet */
    struct ip6 *rip = mtod(t, struct ip6 *);
    rip->ip_dst = ip->ip_src;
    rip->ip_src = ip->ip_dst;

    /* ICMPv6 packet */
    t->m_data += sizeof(struct ip6);
    struct icmp6 *ricmp = mtod(t, struct icmp6 *);
    ricmp->icmp6_type = ICMP6_ECHO_REPLY;
    ricmp->icmp6_cksum = 0;

    /* Checksum */
    t->m_data -= sizeof(struct ip6);
    ricmp->icmp6_cksum = ip6_cksum(t);

    ip6_output(NULL, t, 0);
}

void icmp6_forward_error(struct mbuf *m, uint8_t type, uint8_t code, struct in6_addr *src)
{
    Slirp *slirp = m->slirp;
    struct mbuf *t;
    struct ip6 *ip = mtod(m, struct ip6 *);
    char addrstr[INET6_ADDRSTRLEN];

    DEBUG_CALL("icmp6_send_error");
    DEBUG_ARG("type = %d, code = %d", type, code);

    if (IN6_IS_ADDR_MULTICAST(&ip->ip_src) || in6_zero(&ip->ip_src)) {
        /* TODO icmp error? */
        return;
    }

    t = m_get(slirp);

    /* IPv6 packet */
    struct ip6 *rip = mtod(t, struct ip6 *);
    rip->ip_src = *src;
    rip->ip_dst = ip->ip_src;
    inet_ntop(AF_INET6, &rip->ip_dst, addrstr, INET6_ADDRSTRLEN);
    DEBUG_ARG("target = %s", addrstr);

    rip->ip_nh = IPPROTO_ICMPV6;
    const int error_data_len = MIN(
        m->m_len, slirp->if_mtu - (sizeof(struct ip6) + ICMP6_ERROR_MINLEN));
    rip->ip_pl = htons(ICMP6_ERROR_MINLEN + error_data_len);
    t->m_len = sizeof(struct ip6) + ntohs(rip->ip_pl);

    /* ICMPv6 packet */
    t->m_data += sizeof(struct ip6);
    struct icmp6 *ricmp = mtod(t, struct icmp6 *);
    ricmp->icmp6_type = type;
    ricmp->icmp6_code = code;
    ricmp->icmp6_cksum = 0;

    switch (type) {
    case ICMP6_UNREACH:
    case ICMP6_TIMXCEED:
        ricmp->icmp6_err.unused = 0;
        break;
    case ICMP6_TOOBIG:
        ricmp->icmp6_err.mtu = htonl(slirp->if_mtu);
        break;
    case ICMP6_PARAMPROB:
        /* TODO: Handle this case */
        break;
    default:
        g_assert_not_reached();
    }
    t->m_data += ICMP6_ERROR_MINLEN;
    memcpy(t->m_data, m->m_data, error_data_len);

    /* Checksum */
    t->m_data -= ICMP6_ERROR_MINLEN;
    t->m_data -= sizeof(struct ip6);
    ricmp->icmp6_cksum = ip6_cksum(t);

    ip6_output(NULL, t, 0);
}

void icmp6_send_error(struct mbuf *m, uint8_t type, uint8_t code)
{
    struct in6_addr src = LINKLOCAL_ADDR;
    icmp6_forward_error(m, type, code, &src);
}

/*
 * Send NDP Router Advertisement
 */
static void ndp_send_ra(Slirp *slirp)
{
    DEBUG_CALL("ndp_send_ra");

    /* Build IPv6 packet */
    struct mbuf *t = m_get(slirp);
    struct ip6 *rip = mtod(t, struct ip6 *);
    size_t pl_size = 0;
    struct in6_addr addr;
    uint32_t scope_id;

    rip->ip_src = (struct in6_addr)LINKLOCAL_ADDR;
    rip->ip_dst = (struct in6_addr)ALLNODES_MULTICAST;
    rip->ip_nh = IPPROTO_ICMPV6;

    /* Build ICMPv6 packet */
    t->m_data += sizeof(struct ip6);
    struct icmp6 *ricmp = mtod(t, struct icmp6 *);
    ricmp->icmp6_type = ICMP6_NDP_RA;
    ricmp->icmp6_code = 0;
    ricmp->icmp6_cksum = 0;

    /* NDP */
    ricmp->icmp6_nra.chl = NDP_AdvCurHopLimit;
    ricmp->icmp6_nra.M = NDP_AdvManagedFlag;
    ricmp->icmp6_nra.O = NDP_AdvOtherConfigFlag;
    ricmp->icmp6_nra.reserved = 0;
    ricmp->icmp6_nra.lifetime = htons(NDP_AdvDefaultLifetime);
    ricmp->icmp6_nra.reach_time = htonl(NDP_AdvReachableTime);
    ricmp->icmp6_nra.retrans_time = htonl(NDP_AdvRetransTime);
    t->m_data += ICMP6_NDP_RA_MINLEN;
    pl_size += ICMP6_NDP_RA_MINLEN;

    /* Source link-layer address (NDP option) */
    struct ndpopt *opt = mtod(t, struct ndpopt *);
    opt->ndpopt_type = NDPOPT_LINKLAYER_SOURCE;
    opt->ndpopt_len = NDPOPT_LINKLAYER_LEN / 8;
    in6_compute_ethaddr(rip->ip_src, opt->ndpopt_linklayer);
    t->m_data += NDPOPT_LINKLAYER_LEN;
    pl_size += NDPOPT_LINKLAYER_LEN;

    /* Prefix information (NDP option) */
    struct ndpopt *opt2 = mtod(t, struct ndpopt *);
    opt2->ndpopt_type = NDPOPT_PREFIX_INFO;
    opt2->ndpopt_len = NDPOPT_PREFIXINFO_LEN / 8;
    opt2->ndpopt_prefixinfo.prefix_length = slirp->vprefix_len;
    opt2->ndpopt_prefixinfo.L = 1;
    opt2->ndpopt_prefixinfo.A = 1;
    opt2->ndpopt_prefixinfo.reserved1 = 0;
    opt2->ndpopt_prefixinfo.valid_lt = htonl(NDP_AdvValidLifetime);
    opt2->ndpopt_prefixinfo.pref_lt = htonl(NDP_AdvPrefLifetime);
    opt2->ndpopt_prefixinfo.reserved2 = 0;
    opt2->ndpopt_prefixinfo.prefix = slirp->vprefix_addr6;
    t->m_data += NDPOPT_PREFIXINFO_LEN;
    pl_size += NDPOPT_PREFIXINFO_LEN;

    /* Prefix information (NDP option) */
    if (get_dns6_addr(&addr, &scope_id) >= 0) {
        /* Host system does have an IPv6 DNS server, announce our proxy.  */
        struct ndpopt *opt3 = mtod(t, struct ndpopt *);
        opt3->ndpopt_type = NDPOPT_RDNSS;
        opt3->ndpopt_len = NDPOPT_RDNSS_LEN / 8;
        opt3->ndpopt_rdnss.reserved = 0;
        opt3->ndpopt_rdnss.lifetime = htonl(2 * NDP_MaxRtrAdvInterval);
        opt3->ndpopt_rdnss.addr = slirp->vnameserver_addr6;
        t->m_data += NDPOPT_RDNSS_LEN;
        pl_size += NDPOPT_RDNSS_LEN;
    }

    rip->ip_pl = htons(pl_size);
    t->m_data -= sizeof(struct ip6) + pl_size;
    t->m_len = sizeof(struct ip6) + pl_size;

    /* ICMPv6 Checksum */
    ricmp->icmp6_cksum = ip6_cksum(t);

    ip6_output(NULL, t, 0);
}

void ra_timer_handler(Slirp *slirp, void *unused)
{
    slirp->cb->timer_mod(slirp->ra_timer,
                         slirp->cb->clock_get_ns(slirp->opaque) / SCALE_MS +
                             NDP_Interval,
                         slirp->opaque);
    ndp_send_ra(slirp);
}

/*
 * Send NDP Neighbor Solitication
 */
void ndp_send_ns(Slirp *slirp, struct in6_addr addr)
{
    char addrstr[INET6_ADDRSTRLEN];

    inet_ntop(AF_INET6, &addr, addrstr, INET6_ADDRSTRLEN);

    DEBUG_CALL("ndp_send_ns");
    DEBUG_ARG("target = %s", addrstr);

    /* Build IPv6 packet */
    struct mbuf *t = m_get(slirp);
    struct ip6 *rip = mtod(t, struct ip6 *);
    rip->ip_src = slirp->vhost_addr6;
    rip->ip_dst = (struct in6_addr)SOLICITED_NODE_PREFIX;
    memcpy(&rip->ip_dst.s6_addr[13], &addr.s6_addr[13], 3);
    rip->ip_nh = IPPROTO_ICMPV6;
    rip->ip_pl = htons(ICMP6_NDP_NS_MINLEN + NDPOPT_LINKLAYER_LEN);
    t->m_len = sizeof(struct ip6) + ntohs(rip->ip_pl);

    /* Build ICMPv6 packet */
    t->m_data += sizeof(struct ip6);
    struct icmp6 *ricmp = mtod(t, struct icmp6 *);
    ricmp->icmp6_type = ICMP6_NDP_NS;
    ricmp->icmp6_code = 0;
    ricmp->icmp6_cksum = 0;

    /* NDP */
    ricmp->icmp6_nns.reserved = 0;
    ricmp->icmp6_nns.target = addr;

    /* Build NDP option */
    t->m_data += ICMP6_NDP_NS_MINLEN;
    struct ndpopt *opt = mtod(t, struct ndpopt *);
    opt->ndpopt_type = NDPOPT_LINKLAYER_SOURCE;
    opt->ndpopt_len = NDPOPT_LINKLAYER_LEN / 8;
    in6_compute_ethaddr(slirp->vhost_addr6, opt->ndpopt_linklayer);

    /* ICMPv6 Checksum */
    t->m_data -= ICMP6_NDP_NA_MINLEN;
    t->m_data -= sizeof(struct ip6);
    ricmp->icmp6_cksum = ip6_cksum(t);

    ip6_output(NULL, t, 1);
}

/*
 * Send NDP Neighbor Advertisement
 */
static void ndp_send_na(Slirp *slirp, struct ip6 *ip, struct icmp6 *icmp)
{
    /* Build IPv6 packet */
    struct mbuf *t = m_get(slirp);
    struct ip6 *rip = mtod(t, struct ip6 *);
    rip->ip_src = icmp->icmp6_nns.target;
    if (in6_zero(&ip->ip_src)) {
        rip->ip_dst = (struct in6_addr)ALLNODES_MULTICAST;
    } else {
        rip->ip_dst = ip->ip_src;
    }
    rip->ip_nh = IPPROTO_ICMPV6;
    rip->ip_pl = htons(ICMP6_NDP_NA_MINLEN + NDPOPT_LINKLAYER_LEN);
    t->m_len = sizeof(struct ip6) + ntohs(rip->ip_pl);

    /* Build ICMPv6 packet */
    t->m_data += sizeof(struct ip6);
    struct icmp6 *ricmp = mtod(t, struct icmp6 *);
    ricmp->icmp6_type = ICMP6_NDP_NA;
    ricmp->icmp6_code = 0;
    ricmp->icmp6_cksum = 0;

    /* NDP */
    ricmp->icmp6_nna.R = NDP_IsRouter;
    ricmp->icmp6_nna.S = !IN6_IS_ADDR_MULTICAST(&rip->ip_dst);
    ricmp->icmp6_nna.O = 1;
    ricmp->icmp6_nna.reserved_hi = 0;
    ricmp->icmp6_nna.reserved_lo = 0;
    ricmp->icmp6_nna.target = icmp->icmp6_nns.target;

    /* Build NDP option */
    t->m_data += ICMP6_NDP_NA_MINLEN;
    struct ndpopt *opt = mtod(t, struct ndpopt *);
    opt->ndpopt_type = NDPOPT_LINKLAYER_TARGET;
    opt->ndpopt_len = NDPOPT_LINKLAYER_LEN / 8;
    in6_compute_ethaddr(ricmp->icmp6_nna.target, opt->ndpopt_linklayer);

    /* ICMPv6 Checksum */
    t->m_data -= ICMP6_NDP_NA_MINLEN;
    t->m_data -= sizeof(struct ip6);
    ricmp->icmp6_cksum = ip6_cksum(t);

    ip6_output(NULL, t, 0);
}

/*
 * Process a NDP message
 */
static void ndp_input(struct mbuf *m, Slirp *slirp, struct ip6 *ip,
                      struct icmp6 *icmp)
{
    g_assert(M_ROOMBEFORE(m) >= ETH_HLEN);

    m->m_len += ETH_HLEN;
    m->m_data -= ETH_HLEN;
    struct ethhdr *eth = mtod(m, struct ethhdr *);
    m->m_len -= ETH_HLEN;
    m->m_data += ETH_HLEN;

    switch (icmp->icmp6_type) {
    case ICMP6_NDP_RS:
        DEBUG_CALL(" type = Router Solicitation");
        if (ip->ip_hl == 255 && icmp->icmp6_code == 0 &&
            ntohs(ip->ip_pl) >= ICMP6_NDP_RS_MINLEN) {
            /* Gratuitous NDP */
            ndp_table_add(slirp, ip->ip_src, eth->h_source);

            ndp_send_ra(slirp);
        }
        break;

    case ICMP6_NDP_RA:
        DEBUG_CALL(" type = Router Advertisement");
        slirp->cb->guest_error("Warning: guest sent NDP RA, but shouldn't",
                               slirp->opaque);
        break;

    case ICMP6_NDP_NS:
        DEBUG_CALL(" type = Neighbor Solicitation");
        if (ip->ip_hl == 255 && icmp->icmp6_code == 0 &&
            !IN6_IS_ADDR_MULTICAST(&icmp->icmp6_nns.target) &&
            ntohs(ip->ip_pl) >= ICMP6_NDP_NS_MINLEN &&
            (!in6_zero(&ip->ip_src) ||
             in6_solicitednode_multicast(&ip->ip_dst))) {
            if (in6_equal_host(&icmp->icmp6_nns.target)) {
                /* Gratuitous NDP */
                ndp_table_add(slirp, ip->ip_src, eth->h_source);
                ndp_send_na(slirp, ip, icmp);
            }
        }
        break;

    case ICMP6_NDP_NA:
        DEBUG_CALL(" type = Neighbor Advertisement");
        if (ip->ip_hl == 255 && icmp->icmp6_code == 0 &&
            ntohs(ip->ip_pl) >= ICMP6_NDP_NA_MINLEN &&
            !IN6_IS_ADDR_MULTICAST(&icmp->icmp6_nna.target) &&
            (!IN6_IS_ADDR_MULTICAST(&ip->ip_dst) || icmp->icmp6_nna.S == 0)) {
            ndp_table_add(slirp, ip->ip_src, eth->h_source);
        }
        break;

    case ICMP6_NDP_REDIRECT:
        DEBUG_CALL(" type = Redirect");
        slirp->cb->guest_error(
            "Warning: guest sent NDP REDIRECT, but shouldn't", slirp->opaque);
        break;
    }
}

/*
 * Process a received ICMPv6 message.
 */
void icmp6_input(struct mbuf *m)
{
    Slirp *slirp = m->slirp;
    /* NDP reads the ethernet header for gratuitous NDP */
    M_DUP_DEBUG(slirp, m, 1, ETH_HLEN);

    struct icmp6 *icmp;
    struct ip6 *ip = mtod(m, struct ip6 *);
    int hlen = sizeof(struct ip6);

    DEBUG_CALL("icmp6_input");
    DEBUG_ARG("m = %p", m);
    DEBUG_ARG("m_len = %d", m->m_len);

    if (ntohs(ip->ip_pl) < ICMP6_MINLEN) {
        goto end;
    }

    if (ip6_cksum(m)) {
        goto end;
    }

    m->m_len -= hlen;
    m->m_data += hlen;
    icmp = mtod(m, struct icmp6 *);
    m->m_len += hlen;
    m->m_data -= hlen;

    DEBUG_ARG("icmp6_type = %d", icmp->icmp6_type);
    switch (icmp->icmp6_type) {
    case ICMP6_ECHO_REQUEST:
        if (in6_equal_host(&ip->ip_dst)) {
            icmp6_send_echoreply(m, slirp, ip, icmp);
        } else {
            /* TODO */
            g_critical("external icmpv6 not supported yet");
        }
        break;

    case ICMP6_NDP_RS:
    case ICMP6_NDP_RA:
    case ICMP6_NDP_NS:
    case ICMP6_NDP_NA:
    case ICMP6_NDP_REDIRECT:
        ndp_input(m, slirp, ip, icmp);
        break;

    case ICMP6_UNREACH:
    case ICMP6_TOOBIG:
    case ICMP6_TIMXCEED:
    case ICMP6_PARAMPROB:
        /* XXX? report error? close socket? */
    default:
        break;
    }

end:
    m_free(m);
}
