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:
parent
1095a7b0c9
commit
9e22c53aa9
4 changed files with 8 additions and 6 deletions
|
@ -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
6
tap.c
|
@ -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
2
tcp.c
|
@ -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
2
udp.c
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue