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

#ifndef QEMU_NET_CHECKSUM_H
#define QEMU_NET_CHECKSUM_H

#include "qemu/bswap.h"
struct iovec;

#define CSUM_IP     0x01
#define CSUM_TCP    0x02
#define CSUM_UDP    0x04
#define CSUM_ALL    (CSUM_IP | CSUM_TCP | CSUM_UDP)

uint32_t net_checksum_add_cont(int len, uint8_t *buf, int seq);
uint16_t net_checksum_finish(uint32_t sum);
uint16_t net_checksum_tcpudp(uint16_t length, uint16_t proto,
                             uint8_t *addrs, uint8_t *buf);
void net_checksum_calculate(uint8_t *data, int length, int csum_flag);

static inline uint32_t
net_checksum_add(int len, uint8_t *buf)
{
    return net_checksum_add_cont(len, buf, 0);
}

static inline uint16_t
net_checksum_finish_nozero(uint32_t sum)
{
    return net_checksum_finish(sum) ?: 0xFFFF;
}

static inline uint16_t
net_raw_checksum(uint8_t *data, int length)
{
    return net_checksum_finish(net_checksum_add(length, data));
}

/**
 * net_checksum_add_iov: scatter-gather vector checksumming
 *
 * @iov: input scatter-gather array
 * @iov_cnt: number of array elements
 * @iov_off: starting iov offset for checksumming
 * @size: length of data to be checksummed
 * @csum_offset: offset of the checksum chunk
 */
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);

typedef struct toeplitz_key_st {
    uint32_t leftmost_32_bits;
    uint8_t *next_byte;
} net_toeplitz_key;

static inline
void net_toeplitz_key_init(net_toeplitz_key *key, uint8_t *key_bytes)
{
    key->leftmost_32_bits = be32_to_cpu(*(uint32_t *)key_bytes);
    key->next_byte = key_bytes + sizeof(uint32_t);
}

static inline
void net_toeplitz_add(uint32_t *result,
                      uint8_t *input,
                      uint32_t len,
                      net_toeplitz_key *key)
{
    register uint32_t accumulator = *result;
    register uint32_t leftmost_32_bits = key->leftmost_32_bits;
    register uint32_t byte;

    for (byte = 0; byte < len; byte++) {
        register uint8_t input_byte = input[byte];
        register uint8_t key_byte = *(key->next_byte++);
        register uint8_t bit;

        for (bit = 0; bit < 8; bit++) {
            if (input_byte & (1 << 7)) {
                accumulator ^= leftmost_32_bits;
            }

            leftmost_32_bits =
                (leftmost_32_bits << 1) | ((key_byte & (1 << 7)) >> 7);

            input_byte <<= 1;
            key_byte <<= 1;
        }
    }

    key->leftmost_32_bits = leftmost_32_bits;
    *result = accumulator;
}

#endif /* QEMU_NET_CHECKSUM_H */
