Most files that have TABs only contain a handful of them. Change
them to spaces so that we don't confuse people.
disas, standard-headers, linux-headers and libdecnumber are imported
from other projects and probably should be exempted from the check.
Outside those, after this patch the following files still contain both
8-space and TAB sequences at the beginning of the line. Many of them
have a majority of TABs, or were initially committed with all tabs.
bsd-user/i386/target_syscall.h
bsd-user/x86_64/target_syscall.h
crypto/aes.c
hw/audio/fmopl.c
hw/audio/fmopl.h
hw/block/tc58128.c
hw/display/cirrus_vga.c
hw/display/xenfb.c
hw/dma/etraxfs_dma.c
hw/intc/sh_intc.c
hw/misc/mst_fpga.c
hw/net/pcnet.c
hw/sh4/sh7750.c
hw/timer/m48t59.c
hw/timer/sh_timer.c
include/crypto/aes.h
include/disas/bfd.h
include/hw/sh4/sh.h
libdecnumber/decNumber.c
linux-headers/asm-generic/unistd.h
linux-headers/linux/kvm.h
linux-user/alpha/target_syscall.h
linux-user/arm/nwfpe/double_cpdo.c
linux-user/arm/nwfpe/fpa11_cpdt.c
linux-user/arm/nwfpe/fpa11_cprt.c
linux-user/arm/nwfpe/fpa11.h
linux-user/flat.h
linux-user/flatload.c
linux-user/i386/target_syscall.h
linux-user/ppc/target_syscall.h
linux-user/sparc/target_syscall.h
linux-user/syscall.c
linux-user/syscall_defs.h
linux-user/x86_64/target_syscall.h
slirp/cksum.c
slirp/if.c
slirp/ip.h
slirp/ip_icmp.c
slirp/ip_icmp.h
slirp/ip_input.c
slirp/ip_output.c
slirp/mbuf.c
slirp/misc.c
slirp/sbuf.c
slirp/socket.c
slirp/socket.h
slirp/tcp_input.c
slirp/tcpip.h
slirp/tcp_output.c
slirp/tcp_subr.c
slirp/tcp_timer.c
slirp/tftp.c
slirp/udp.c
slirp/udp.h
target/cris/cpu.h
target/cris/mmu.c
target/cris/op_helper.c
target/sh4/helper.c
target/sh4/op_helper.c
target/sh4/translate.c
tcg/sparc/tcg-target.inc.c
tests/tcg/cris/check_addo.c
tests/tcg/cris/check_moveq.c
tests/tcg/cris/check_swap.c
tests/tcg/multiarch/test-mmap.c
ui/vnc-enc-hextile-template.h
ui/vnc-enc-zywrle.h
util/envlist.c
util/readline.c
The following have only TABs:
bsd-user/i386/target_signal.h
bsd-user/sparc64/target_signal.h
bsd-user/sparc64/target_syscall.h
bsd-user/sparc/target_signal.h
bsd-user/sparc/target_syscall.h
bsd-user/x86_64/target_signal.h
crypto/desrfb.c
hw/audio/intel-hda-defs.h
hw/core/uboot_image.h
hw/sh4/sh7750_regnames.c
hw/sh4/sh7750_regs.h
include/hw/cris/etraxfs_dma.h
linux-user/alpha/termbits.h
linux-user/arm/nwfpe/fpopcode.h
linux-user/arm/nwfpe/fpsr.h
linux-user/arm/syscall_nr.h
linux-user/arm/target_signal.h
linux-user/cris/target_signal.h
linux-user/i386/target_signal.h
linux-user/linux_loop.h
linux-user/m68k/target_signal.h
linux-user/microblaze/target_signal.h
linux-user/mips64/target_signal.h
linux-user/mips/target_signal.h
linux-user/mips/target_syscall.h
linux-user/mips/termbits.h
linux-user/ppc/target_signal.h
linux-user/sh4/target_signal.h
linux-user/sh4/termbits.h
linux-user/sparc64/target_syscall.h
linux-user/sparc/target_signal.h
linux-user/x86_64/target_signal.h
linux-user/x86_64/termbits.h
pc-bios/optionrom/optionrom.h
slirp/mbuf.h
slirp/misc.h
slirp/sbuf.h
slirp/tcp.h
slirp/tcp_timer.h
slirp/tcp_var.h
target/i386/svm.h
target/sparc/asi.h
target/xtensa/core-dc232b/xtensa-modules.inc.c
target/xtensa/core-dc233c/xtensa-modules.inc.c
target/xtensa/core-de212/core-isa.h
target/xtensa/core-de212/xtensa-modules.inc.c
target/xtensa/core-fsf/xtensa-modules.inc.c
target/xtensa/core-sample_controller/core-isa.h
target/xtensa/core-sample_controller/xtensa-modules.inc.c
target/xtensa/core-test_kc705_be/core-isa.h
target/xtensa/core-test_kc705_be/xtensa-modules.inc.c
tests/tcg/cris/check_abs.c
tests/tcg/cris/check_addc.c
tests/tcg/cris/check_addcm.c
tests/tcg/cris/check_addoq.c
tests/tcg/cris/check_bound.c
tests/tcg/cris/check_ftag.c
tests/tcg/cris/check_int64.c
tests/tcg/cris/check_lz.c
tests/tcg/cris/check_openpf5.c
tests/tcg/cris/check_sigalrm.c
tests/tcg/cris/crisutils.h
tests/tcg/cris/sys.c
tests/tcg/i386/test-i386-ssse3.c
ui/vgafont.h
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Message-Id: <20181213223737.11793-3-pbonzini@redhat.com>
Reviewed-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Wainer dos Santos Moschetta <wainersm@redhat.com>
Acked-by: Richard Henderson <richard.henderson@linaro.org>
Acked-by: Eric Blake <eblake@redhat.com>
Acked-by: David Gibson <david@gibson.dropbear.id.au>
Reviewed-by: Stefan Markovic <smarkovic@wavecomp.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
194 lines
5.1 KiB
C
194 lines
5.1 KiB
C
/*
|
|
* 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 "qemu-common.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 mac_hdr_len, ip_len;
|
|
struct ip_header *ip;
|
|
|
|
/*
|
|
* 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 */
|
|
}
|
|
|
|
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:
|
|
{
|
|
uint16_t csum;
|
|
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:
|
|
{
|
|
uint16_t csum;
|
|
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, buf_off;
|
|
unsigned int i;
|
|
uint32_t res = 0;
|
|
|
|
iovec_off = 0;
|
|
buf_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;
|
|
|
|
buf_off += len;
|
|
iov_off += len;
|
|
size -= len;
|
|
}
|
|
iovec_off += iov[i].iov_len;
|
|
}
|
|
return res;
|
|
}
|