/* 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;

    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;
    }

    M_DUP_DEBUG(slirp, m, 0, 0);
    struct ip *ip = mtod(m, struct ip *);

    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);
}
