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