1
0
mirror of https://passt.top/passt synced 2024-06-27 21:42:42 +00:00

checksum: Make csum_ip4_header() take a host endian length

csum_ip4_header() takes the packet length as a network endian value.  In
general it's very error-prone to pass non-native-endian values as a raw
integer.  It's particularly bad here because this differs from other
checksum functions (e.g. proto_ipv4_header_psum()) which take host native
lengths.

It turns out all the callers have easy access to the native endian value,
so switch it to use host order like everything else.

Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
This commit is contained in:
David Gibson 2024-05-01 16:53:48 +10:00 committed by Stefano Brivio
parent 1095a7b0c9
commit 9e22c53aa9
4 changed files with 8 additions and 6 deletions

View File

@ -116,7 +116,7 @@ uint16_t csum_fold(uint32_t sum)
/**
* csum_ip4_header() - Calculate IPv4 header checksum
* @tot_len: IPv4 payload length (data + IP header, network order)
* @tot_len: IPv4 packet length (data + IP header, host order)
* @protocol: Protocol number
* @saddr: IPv4 source address
* @daddr: IPv4 destination address
@ -128,7 +128,7 @@ uint16_t csum_ip4_header(uint16_t tot_len, uint8_t protocol,
{
uint32_t sum = L2_BUF_IP4_PSUM(protocol);
sum += tot_len;
sum += htons(tot_len);
sum += (saddr.s_addr >> 16) & 0xffff;
sum += saddr.s_addr & 0xffff;
sum += (daddr.s_addr >> 16) & 0xffff;

6
tap.c
View File

@ -149,17 +149,19 @@ static void *tap_push_l2h(const struct ctx *c, void *buf, uint16_t proto)
static void *tap_push_ip4h(struct iphdr *ip4h, struct in_addr src,
struct in_addr dst, size_t len, uint8_t proto)
{
uint16_t tot_len = len + sizeof(*ip4h);
ip4h->version = 4;
ip4h->ihl = sizeof(struct iphdr) / 4;
ip4h->tos = 0;
ip4h->tot_len = htons(len + sizeof(*ip4h));
ip4h->tot_len = htons(tot_len);
ip4h->id = 0;
ip4h->frag_off = 0;
ip4h->ttl = 255;
ip4h->protocol = proto;
ip4h->saddr = src.s_addr;
ip4h->daddr = dst.s_addr;
ip4h->check = csum_ip4_header(ip4h->tot_len, proto, src, dst);
ip4h->check = csum_ip4_header(tot_len, proto, src, dst);
return ip4h + 1;
}

2
tcp.c
View File

@ -1359,7 +1359,7 @@ static size_t tcp_fill_headers4(const struct ctx *c,
iph->daddr = c->ip4.addr_seen.s_addr;
iph->check = check ? *check :
csum_ip4_header(iph->tot_len, IPPROTO_TCP,
csum_ip4_header(ip_len, IPPROTO_TCP,
*a4, c->ip4.addr_seen);
tcp_fill_header(th, conn, seq);

2
udp.c
View File

@ -605,7 +605,7 @@ static size_t udp_update_hdr4(const struct ctx *c, struct udp4_l2_buf_t *b,
b->iph.tot_len = htons(ip_len);
b->iph.daddr = c->ip4.addr_seen.s_addr;
b->iph.saddr = src.s_addr;
b->iph.check = csum_ip4_header(b->iph.tot_len, IPPROTO_UDP,
b->iph.check = csum_ip4_header(ip_len, IPPROTO_UDP,
src, c->ip4.addr_seen);
b->uh.source = b->s_in.sin_port;