/* SPDX-License-Identifier: BSD-3-Clause */
/*
 * Copyright (c) 1982, 1986, 1988, 1993
 *	The Regents of the University of California.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 *	@(#)ip_icmp.c	8.2 (Berkeley) 1/4/94
 * ip_icmp.c,v 1.7 1995/05/30 08:09:42 rgrimes Exp
 */

#include "slirp.h"
#include "ip_icmp.h"

#ifndef _WIN32
#include <sys/param.h>
#endif

#ifndef WITH_ICMP_ERROR_MSG
#define WITH_ICMP_ERROR_MSG 0
#endif

/* The message sent when emulating PING */
/* Be nice and tell them it's just a pseudo-ping packet */
static const char icmp_ping_msg[] =
    "This is a pseudo-PING packet used by Slirp to emulate ICMP ECHO-REQUEST "
    "packets.\n";

/* list of actions for icmp_send_error() on RX of an icmp message */
static const int icmp_flush[19] = {
    /*  ECHO REPLY (0)  */ 0,
    1,
    1,
    /* DEST UNREACH (3) */ 1,
    /* SOURCE QUENCH (4)*/ 1,
    /* REDIRECT (5) */ 1,
    1,
    1,
    /* ECHO (8) */ 0,
    /* ROUTERADVERT (9) */ 1,
    /* ROUTERSOLICIT (10) */ 1,
    /* TIME EXCEEDED (11) */ 1,
    /* PARAMETER PROBLEM (12) */ 1,
    /* TIMESTAMP (13) */ 0,
    /* TIMESTAMP REPLY (14) */ 0,
    /* INFO (15) */ 0,
    /* INFO REPLY (16) */ 0,
    /* ADDR MASK (17) */ 0,
    /* ADDR MASK REPLY (18) */ 0
};

void icmp_init(Slirp *slirp)
{
    slirp->icmp.so_next = slirp->icmp.so_prev = &slirp->icmp;
    slirp->icmp_last_so = &slirp->icmp;
}

void icmp_cleanup(Slirp *slirp)
{
    struct socket *so, *so_next;

    for (so = slirp->icmp.so_next; so != &slirp->icmp; so = so_next) {
        so_next = so->so_next;
        icmp_detach(so);
    }
}

/* Send ICMP packet to the Internet, and save it to so_m */
static int icmp_send(struct socket *so, struct mbuf *m, int hlen)
{
    Slirp *slirp = m->slirp;
    M_DUP_DEBUG(slirp, m, 0, 0);

    struct ip *ip = mtod(m, struct ip *);
    struct sockaddr_in addr;

    /*
     * The behavior of reading SOCK_DGRAM+IPPROTO_ICMP sockets is inconsistent
     * between host OSes.  On Linux, only the ICMP header and payload is
     * included.  On macOS/Darwin, the socket acts like a raw socket and
     * includes the IP header as well.  On other BSDs, SOCK_DGRAM+IPPROTO_ICMP
     * sockets aren't supported at all, so we treat them like raw sockets.  It
     * isn't possible to detect this difference at runtime, so we must use an
     * #ifdef to determine if we need to remove the IP header.
     */
#if defined(BSD) && !defined(__GNU__)
    so->so_type = IPPROTO_IP;
#else
    so->so_type = IPPROTO_ICMP;
#endif

    so->s = slirp_socket(AF_INET, SOCK_DGRAM, IPPROTO_ICMP);
    if (so->s == -1) {
        if (errno == EAFNOSUPPORT
         || errno == EPROTONOSUPPORT
         || errno == EACCES) {
            /* Kernel doesn't support or allow ping sockets. */
            so->so_type = IPPROTO_IP;
            so->s = slirp_socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
        }
    }
    if (so->s == -1) {
        return -1;
    }
    so->slirp->cb->register_poll_fd(so->s, so->slirp->opaque);

    if (slirp_bind_outbound(so, AF_INET) != 0) {
        // bind failed - close socket
        closesocket(so->s);
        so->s = -1;
        return -1;
    }

    so->so_m = m;
    so->so_faddr = ip->ip_dst;
    so->so_laddr = ip->ip_src;
    so->so_iptos = ip->ip_tos;
    so->so_state = SS_ISFCONNECTED;
    so->so_expire = curtime + SO_EXPIRE;

    addr.sin_family = AF_INET;
    addr.sin_addr = so->so_faddr;

    slirp_insque(so, &so->slirp->icmp);

    if (sendto(so->s, m->m_data + hlen, m->m_len - hlen, 0,
               (struct sockaddr *)&addr, sizeof(addr)) == -1) {
        DEBUG_MISC("icmp_input icmp sendto tx errno = %d-%s", errno,
                   strerror(errno));
        icmp_send_error(m, ICMP_UNREACH, ICMP_UNREACH_NET, 0, strerror(errno));
        icmp_detach(so);
    }

    return 0;
}

void icmp_detach(struct socket *so)
{
    so->slirp->cb->unregister_poll_fd(so->s, so->slirp->opaque);
    closesocket(so->s);
    sofree(so);
}

/*
 * Process a received ICMP message.
 */
void icmp_input(struct mbuf *m, int hlen)
{
    Slirp *slirp = m->slirp;
    M_DUP_DEBUG(slirp, m, 0, 0);

    register struct icmp *icp;
    register struct ip *ip = mtod(m, struct ip *);
    int icmplen = ip->ip_len;

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

    /*
     * Locate icmp structure in mbuf, and check
     * that its not corrupted and of at least minimum length.
     */
    if (icmplen < ICMP_MINLEN) { /* min 8 bytes payload */
    freeit:
        m_free(m);
        goto end_error;
    }

    m->m_len -= hlen;
    m->m_data += hlen;
    icp = mtod(m, struct icmp *);
    if (cksum(m, icmplen)) {
        goto freeit;
    }
    m->m_len += hlen;
    m->m_data -= hlen;

    DEBUG_ARG("icmp_type = %d", icp->icmp_type);
    switch (icp->icmp_type) {
    case ICMP_ECHO:
        ip->ip_len += hlen; /* since ip_input subtracts this */
        if (ip->ip_dst.s_addr == slirp->vhost_addr.s_addr ||
            ip->ip_dst.s_addr == slirp->vnameserver_addr.s_addr) {
            icmp_reflect(m);
        } else if (slirp->restricted) {
            goto freeit;
        } else {
            struct socket *so;
            struct sockaddr_storage addr;
            int ttl;

            so = socreate(slirp, IPPROTO_ICMP);
            if (icmp_send(so, m, hlen) == 0) {
                /* We could send this as ICMP, good! */
                return;
            }

            /* We could not send this as ICMP, try to send it on UDP echo
             * service (7), wishfully hoping that it is open there. */

            if (udp_attach(so, AF_INET) == -1) {
                DEBUG_MISC("icmp_input udp_attach errno = %d-%s", errno,
                           strerror(errno));
                sofree(so);
                m_free(m);
                goto end_error;
            }
            so->so_m = m;
            so->so_ffamily = AF_INET;
            so->so_faddr = ip->ip_dst;
            so->so_fport = htons(7);
            so->so_lfamily = AF_INET;
            so->so_laddr = ip->ip_src;
            so->so_lport = htons(9);
            so->so_iptos = ip->ip_tos;
            so->so_state = SS_ISFCONNECTED;

            /* Send the packet */
            addr = so->fhost.ss;
            if (sotranslate_out(so, &addr) < 0) {
                icmp_send_error(m, ICMP_UNREACH, ICMP_UNREACH_NET, 0,
                                strerror(errno));
                udp_detach(so);
                return;
            }

            /*
             * Check for TTL
             */
            ttl = ip->ip_ttl-1;
            if (ttl <= 0) {
                DEBUG_MISC("udp ttl exceeded");
                icmp_send_error(m, ICMP_TIMXCEED, ICMP_TIMXCEED_INTRANS, 0,
                                NULL);
                udp_detach(so);
                break;
            }
            setsockopt(so->s, IPPROTO_IP, IP_TTL, &ttl, sizeof(ttl));

            if (sendto(so->s, icmp_ping_msg, strlen(icmp_ping_msg), 0,
                       (struct sockaddr *)&addr, sockaddr_size(&addr)) == -1) {
                DEBUG_MISC("icmp_input udp sendto tx errno = %d-%s", errno,
                           strerror(errno));
                icmp_send_error(m, ICMP_UNREACH, ICMP_UNREACH_NET, 0,
                                strerror(errno));
                udp_detach(so);
            }
        } /* if ip->ip_dst.s_addr == alias_addr.s_addr */
        break;
    case ICMP_UNREACH:
        /* XXX? report error? close socket? */
    case ICMP_TIMXCEED:
    case ICMP_PARAMPROB:
    case ICMP_SOURCEQUENCH:
    case ICMP_TSTAMP:
    case ICMP_MASKREQ:
    case ICMP_REDIRECT:
        m_free(m);
        break;

    default:
        m_free(m);
    } /* switch */

end_error:
    /* m is m_free()'d xor put in a socket xor or given to ip_send */
    return;
}


/*
 *	Send an ICMP message in response to a situation
 *
 *	RFC 1122: 3.2.2	MUST send at least the IP header and 8 bytes of header.
 *MAY send more (we do). MUST NOT change this header information. MUST NOT reply
 *to a multicast/broadcast IP address. MUST NOT reply to a multicast/broadcast
 *MAC address. MUST reply to only the first fragment.
 */
/*
 * Send ICMP_UNREACH back to the source regarding msrc.
 * mbuf *msrc is used as a template, but is NOT m_free()'d.
 * It is reported as the bad ip packet.  The header should
 * be fully correct and in host byte order.
 * ICMP fragmentation is illegal.  All machines must accept 576 bytes in one
 * packet.  The maximum payload is 576-20(ip hdr)-8(icmp hdr)=548
 */

#define ICMP_MAXDATALEN (IP_MSS - 28)
void icmp_forward_error(struct mbuf *msrc, uint8_t type, uint8_t code, int minsize,
                        const char *message, struct in_addr *src)
{
    unsigned hlen, shlen, s_ip_len;
    register struct ip *ip;
    register struct icmp *icp;
    register struct mbuf *m;

    DEBUG_CALL("icmp_send_error");
    DEBUG_ARG("msrc = %p", msrc);
    DEBUG_ARG("msrc_len = %d", msrc->m_len);

    if (type != ICMP_UNREACH && type != ICMP_TIMXCEED)
        goto end_error;

    /* check msrc */
    if (!msrc)
        goto end_error;
    ip = mtod(msrc, struct ip *);
    if (slirp_debug & DBG_MISC) {
        char addr_src[INET_ADDRSTRLEN];
        char addr_dst[INET_ADDRSTRLEN];

        inet_ntop(AF_INET, &ip->ip_src, addr_src, sizeof(addr_src));
        inet_ntop(AF_INET, &ip->ip_dst, addr_dst, sizeof(addr_dst));
        DEBUG_MISC(" %.16s to %.16s", addr_src, addr_dst);
    }
    if (ip->ip_off & IP_OFFMASK)
        goto end_error; /* Only reply to fragment 0 */

    /* Do not reply to source-only IPs */
    if ((ip->ip_src.s_addr & htonl(~(0xf << 28))) == 0) {
        goto end_error;
    }

    shlen = ip->ip_hl << 2;
    s_ip_len = ip->ip_len;
    if (ip->ip_p == IPPROTO_ICMP) {
        icp = (struct icmp *)((char *)ip + shlen);
        /*
         *	Assume any unknown ICMP type is an error. This isn't
         *	specified by the RFC, but think about it..
         */
        if (icp->icmp_type > 18 || icmp_flush[icp->icmp_type])
            goto end_error;
    }

    /* make a copy */
    m = m_get(msrc->slirp);
    if (!m) {
        goto end_error;
    }

    {
        int new_m_size;
        new_m_size =
            sizeof(struct ip) + ICMP_MINLEN + msrc->m_len + ICMP_MAXDATALEN;
        if (new_m_size > m->m_size)
            m_inc(m, new_m_size);
    }
    memcpy(m->m_data, msrc->m_data, msrc->m_len);
    m->m_len = msrc->m_len; /* copy msrc to m */

    /* make the header of the reply packet */
    ip = mtod(m, struct ip *);
    hlen = sizeof(struct ip); /* no options in reply */

    /* fill in icmp */
    m->m_data += hlen;
    m->m_len -= hlen;

    icp = mtod(m, struct icmp *);

    if (minsize)
        s_ip_len = shlen + ICMP_MINLEN; /* return header+8b only */
    else if (s_ip_len > ICMP_MAXDATALEN) /* maximum size */
        s_ip_len = ICMP_MAXDATALEN;

    m->m_len = ICMP_MINLEN + s_ip_len; /* 8 bytes ICMP header */

    /* min. size = 8+sizeof(struct ip)+8 */

    icp->icmp_type = type;
    icp->icmp_code = code;
    icp->icmp_id = 0;
    icp->icmp_seq = 0;

    memcpy(&icp->icmp_ip, msrc->m_data, s_ip_len); /* report the ip packet */
    HTONS(icp->icmp_ip.ip_len);
    HTONS(icp->icmp_ip.ip_id);
    HTONS(icp->icmp_ip.ip_off);

    if (message && WITH_ICMP_ERROR_MSG) { /* append message to ICMP packet */
        int message_len;
        char *cpnt;
        message_len = strlen(message);
        if (message_len > ICMP_MAXDATALEN)
            message_len = ICMP_MAXDATALEN;
        cpnt = (char *)m->m_data + m->m_len;
        memcpy(cpnt, message, message_len);
        m->m_len += message_len;
    }

    icp->icmp_cksum = 0;
    icp->icmp_cksum = cksum(m, m->m_len);

    m->m_data -= hlen;
    m->m_len += hlen;

    /* fill in ip */
    ip->ip_hl = hlen >> 2;
    ip->ip_len = m->m_len;

    ip->ip_tos = ((ip->ip_tos & 0x1E) | 0xC0); /* high priority for errors */

    ip->ip_ttl = MAXTTL;
    ip->ip_p = IPPROTO_ICMP;
    ip->ip_dst = ip->ip_src; /* ip addresses */
    ip->ip_src = *src;

    ip_output((struct socket *)NULL, m);

end_error:
    return;
}
#undef ICMP_MAXDATALEN

void icmp_send_error(struct mbuf *msrc, uint8_t type, uint8_t code, int minsize,
                     const char *message)
{
    icmp_forward_error(msrc, type, code, minsize, message, &msrc->slirp->vhost_addr);
}

/*
 * Reflect the ip packet back to the source
 */
void icmp_reflect(struct mbuf *m)
{
    register struct ip *ip = mtod(m, struct ip *);
    int hlen = ip->ip_hl << 2;
    int optlen = hlen - sizeof(struct ip);
    register struct icmp *icp;

    /*
     * Send an icmp packet back to the ip level,
     * after supplying a checksum.
     */
    m->m_data += hlen;
    m->m_len -= hlen;
    icp = mtod(m, struct icmp *);

    icp->icmp_type = ICMP_ECHOREPLY;
    icp->icmp_cksum = 0;
    icp->icmp_cksum = cksum(m, ip->ip_len - hlen);

    m->m_data -= hlen;
    m->m_len += hlen;

    /* fill in ip */
    if (optlen > 0) {
        /*
         * Strip out original options by copying rest of first
         * mbuf's data back, and adjust the IP length.
         */
        memmove((char *)(ip + 1), (char *)ip + hlen,
                (unsigned)(m->m_len - hlen));
        hlen -= optlen;
        ip->ip_hl = hlen >> 2;
        ip->ip_len -= optlen;
        m->m_len -= optlen;
    }

    ip->ip_ttl = MAXTTL;
    { /* swap */
        struct in_addr icmp_dst;
        icmp_dst = ip->ip_dst;
        ip->ip_dst = ip->ip_src;
        ip->ip_src = icmp_dst;
    }

    ip_output((struct socket *)NULL, m);
}

void icmp_receive(struct socket *so)
{
    struct mbuf *m = so->so_m;
    struct ip *ip = mtod(m, struct ip *);
    int hlen = ip->ip_hl << 2;
    uint8_t error_code;
    struct icmp *icp;
    int id, len;

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

    id = icp->icmp_id;
    len = recv(so->s, icp, M_ROOM(m), 0);

    if (so->so_type == IPPROTO_IP) {
        if (len >= sizeof(struct ip)) {
            struct ip *inner_ip = mtod(m, struct ip *);
            int inner_hlen = inner_ip->ip_hl << 2;
            if (inner_hlen > len) {
                len = -1;
                errno = -EINVAL;
            } else {
                len -= inner_hlen;
                memmove(icp, (unsigned char *)icp + inner_hlen, len);
            }
        } else {
            len = -1;
            errno = -EINVAL;
        }
    }

    icp->icmp_id = id;

    m->m_data -= hlen;
    m->m_len += hlen;

    if (len == -1 || len == 0) {
        if (errno == ENETUNREACH) {
            error_code = ICMP_UNREACH_NET;
        } else {
            error_code = ICMP_UNREACH_HOST;
        }
        DEBUG_MISC(" udp icmp rx errno = %d-%s", errno, strerror(errno));
        icmp_send_error(so->so_m, ICMP_UNREACH, error_code, 0, strerror(errno));
    } else {
        icmp_reflect(so->so_m);
        so->so_m = NULL; /* Don't m_free() it again! */
    }
    icmp_detach(so);
}
