/*
 *  IP checksumming functions.
 *  (c) 2008 Gerd Hoffmann <kraxel@redhat.com>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; under version 2 or later of the License.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, see <http://www.gnu.org/licenses/>.
 */

#include "qemu/osdep.h"
#include "net/checksum.h"
#include "net/eth.h"

uint32_t net_checksum_add_cont(int len, uint8_t *buf, int seq)
{
    uint32_t sum1 = 0, sum2 = 0;
    int i;

    for (i = 0; i < len - 1; i += 2) {
        sum1 += (uint32_t)buf[i];
        sum2 += (uint32_t)buf[i + 1];
    }
    if (i < len) {
        sum1 += (uint32_t)buf[i];
    }

    if (seq & 1) {
        return sum1 + (sum2 << 8);
    } else {
        return sum2 + (sum1 << 8);
    }
}

uint16_t net_checksum_finish(uint32_t sum)
{
    while (sum>>16)
        sum = (sum & 0xFFFF)+(sum >> 16);
    return ~sum;
}

uint16_t net_checksum_tcpudp(uint16_t length, uint16_t proto,
                             uint8_t *addrs, uint8_t *buf)
{
    uint32_t sum = 0;

    sum += net_checksum_add(length, buf);         // payload
    sum += net_checksum_add(8, addrs);            // src + dst address
    sum += proto + length;                        // protocol & length
    return net_checksum_finish(sum);
}

void net_checksum_calculate(uint8_t *data, int length, int csum_flag)
{
    int mac_hdr_len, ip_len;
    struct ip_header *ip;
    uint16_t csum;

    /*
     * Note: We cannot assume "data" is aligned, so the all code uses
     * some macros that take care of possible unaligned access for
     * struct members (just in case).
     */

    /* Ensure we have at least an Eth header */
    if (length < sizeof(struct eth_header)) {
        return;
    }

    /* Handle the optionnal VLAN headers */
    switch (lduw_be_p(&PKT_GET_ETH_HDR(data)->h_proto)) {
    case ETH_P_VLAN:
        mac_hdr_len = sizeof(struct eth_header) +
                     sizeof(struct vlan_header);
        break;
    case ETH_P_DVLAN:
        if (lduw_be_p(&PKT_GET_VLAN_HDR(data)->h_proto) == ETH_P_VLAN) {
            mac_hdr_len = sizeof(struct eth_header) +
                         2 * sizeof(struct vlan_header);
        } else {
            mac_hdr_len = sizeof(struct eth_header) +
                         sizeof(struct vlan_header);
        }
        break;
    default:
        mac_hdr_len = sizeof(struct eth_header);
        break;
    }

    length -= mac_hdr_len;

    /* Now check we have an IP header (with an optionnal VLAN header) */
    if (length < sizeof(struct ip_header)) {
        return;
    }

    ip = (struct ip_header *)(data + mac_hdr_len);

    if (IP_HEADER_VERSION(ip) != IP_HEADER_VERSION_4) {
        return; /* not IPv4 */
    }

    /* Calculate IP checksum */
    if (csum_flag & CSUM_IP) {
        stw_he_p(&ip->ip_sum, 0);
        csum = net_raw_checksum((uint8_t *)ip, IP_HDR_GET_LEN(ip));
        stw_be_p(&ip->ip_sum, csum);
    }

    if (IP4_IS_FRAGMENT(ip)) {
        return; /* a fragmented IP packet */
    }

    ip_len = lduw_be_p(&ip->ip_len);

    /* Last, check that we have enough data for the all IP frame */
    if (length < ip_len) {
        return;
    }

    ip_len -= IP_HDR_GET_LEN(ip);

    switch (ip->ip_p) {
    case IP_PROTO_TCP:
    {
        if (!(csum_flag & CSUM_TCP)) {
            return;
        }

        tcp_header *tcp = (tcp_header *)(ip + 1);

        if (ip_len < sizeof(tcp_header)) {
            return;
        }

        /* Set csum to 0 */
        stw_he_p(&tcp->th_sum, 0);

        csum = net_checksum_tcpudp(ip_len, ip->ip_p,
                                   (uint8_t *)&ip->ip_src,
                                   (uint8_t *)tcp);

        /* Store computed csum */
        stw_be_p(&tcp->th_sum, csum);

        break;
    }
    case IP_PROTO_UDP:
    {
        if (!(csum_flag & CSUM_UDP)) {
            return;
        }

        udp_header *udp = (udp_header *)(ip + 1);

        if (ip_len < sizeof(udp_header)) {
            return;
        }

        /* Set csum to 0 */
        stw_he_p(&udp->uh_sum, 0);

        csum = net_checksum_tcpudp(ip_len, ip->ip_p,
                                   (uint8_t *)&ip->ip_src,
                                   (uint8_t *)udp);

        /* Store computed csum */
        stw_be_p(&udp->uh_sum, csum);

        break;
    }
    default:
        /* Can't handle any other protocol */
        break;
    }
}

uint32_t
net_checksum_add_iov(const struct iovec *iov, const unsigned int iov_cnt,
                     uint32_t iov_off, uint32_t size, uint32_t csum_offset)
{
    size_t iovec_off;
    unsigned int i;
    uint32_t res = 0;

    iovec_off = 0;
    for (i = 0; i < iov_cnt && size; i++) {
        if (iov_off < (iovec_off + iov[i].iov_len)) {
            size_t len = MIN((iovec_off + iov[i].iov_len) - iov_off , size);
            void *chunk_buf = iov[i].iov_base + (iov_off - iovec_off);

            res += net_checksum_add_cont(len, chunk_buf, csum_offset);
            csum_offset += len;

            iov_off += len;
            size -= len;
        }
        iovec_off += iov[i].iov_len;
    }
    return res;
}
