/*
 * 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 "qemu/osdep.h"
#include "slirp.h"
#include "ip_icmp.h"

/* 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)
{
    while (slirp->icmp.so_next != &slirp->icmp) {
        icmp_detach(slirp->icmp.so_next);
    }
}

static int icmp_send(struct socket *so, struct mbuf *m, int hlen)
{
    struct ip *ip = mtod(m, struct ip *);
    struct sockaddr_in addr;

    so->s = qemu_socket(AF_INET, SOCK_DGRAM, IPPROTO_ICMP);
    if (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_type = IPPROTO_ICMP;
    so->so_state = SS_ISFCONNECTED;
    so->so_expire = curtime + SO_EXPIRE;

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

    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((dfd, "icmp_input icmp sendto tx errno = %d-%s\n", 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)
{
    closesocket(so->s);
    sofree(so);
}

/*
 * Process a received ICMP message.
 */
void icmp_input(struct mbuf *m, int hlen)
{
    register struct icmp *icp;
    register struct ip *ip = mtod(m, struct ip *);
    int icmplen = ip->ip_len;
    Slirp *slirp = m->slirp;

    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;
            if ((so = socreate(slirp)) == NULL)
                goto freeit;
            if (icmp_send(so, m, hlen) == 0) {
                return;
            }
            if (udp_attach(so, AF_INET) == -1) {
                DEBUG_MISC((dfd, "icmp_input udp_attach errno = %d-%s\n", 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_type = IPPROTO_ICMP;
            so->so_state = SS_ISFCONNECTED;

            /* Send the packet */
            addr = so->fhost.ss;
            sotranslate_out(so, &addr);

            if (sendto(so->s, icmp_ping_msg, strlen(icmp_ping_msg), 0,
                       (struct sockaddr *)&addr, sockaddr_size(&addr)) == -1) {
                DEBUG_MISC((dfd, "icmp_input udp sendto tx errno = %d-%s\n",
                            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);
    } /* swith */

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_send_error(struct mbuf *msrc, u_char type, u_char code, int minsize,
                     const char *message)
{
    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 *);
#ifdef DEBUG
    {
        char bufa[20], bufb[20];
        strcpy(bufa, inet_ntoa(ip->ip_src));
        strcpy(bufb, inet_ntoa(ip->ip_dst));
        DEBUG_MISC((dfd, " %.16s to %.16s\n", bufa, bufb));
    }
#endif
    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);

#ifdef DEBUG
    if (message) { /* DEBUG : 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;
    }
#endif

    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 = m->slirp->vhost_addr;

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

end_error:
    return;
}
#undef ICMP_MAXDATALEN

/*
 * 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((caddr_t)(ip + 1), (caddr_t)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;
    }

    (void)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;
    u_char 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 = qemu_recv(so->s, icp, m->m_len, 0);
    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(
            (dfd, " udp icmp rx errno = %d-%s\n", 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);
}
