diff options
author | Laurent Vivier <lvivier@redhat.com> | 2024-03-06 16:58:36 +1100 |
---|---|---|
committer | Stefano Brivio <sbrivio@redhat.com> | 2024-03-06 08:03:47 +0100 |
commit | 7df624e79a450ba6b737b972040d9007ecc61672 (patch) | |
tree | b5b04fd7ad258104870e5dcf2d123578458fa247 /udp.c | |
parent | feb4900c25deabaf9b54760e40aea5e65499e987 (diff) | |
download | passt-7df624e79a450ba6b737b972040d9007ecc61672.tar passt-7df624e79a450ba6b737b972040d9007ecc61672.tar.gz passt-7df624e79a450ba6b737b972040d9007ecc61672.tar.bz2 passt-7df624e79a450ba6b737b972040d9007ecc61672.tar.lz passt-7df624e79a450ba6b737b972040d9007ecc61672.tar.xz passt-7df624e79a450ba6b737b972040d9007ecc61672.tar.zst passt-7df624e79a450ba6b737b972040d9007ecc61672.zip |
checksum: introduce functions to compute the header part checksum for TCP/UDP
The TCP and UDP checksums are computed using the data in the TCP/UDP
payload but also some informations in the IP header (protocol,
length, source and destination addresses).
We add two functions, proto_ipv4_header_psum() and
proto_ipv6_header_psum(), to compute the checksum of the IP
header part.
Signed-off-by: Laurent Vivier <lvivier@redhat.com>
Message-ID: <20240303135114.1023026-8-lvivier@redhat.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
Diffstat (limited to 'udp.c')
-rw-r--r-- | udp.c | 18 |
1 files changed, 10 insertions, 8 deletions
@@ -625,6 +625,7 @@ static size_t udp_update_hdr6(const struct ctx *c, int n, in_port_t dstport, { struct udp6_l2_buf_t *b = &udp6_l2_buf[n]; const struct in6_addr *src, *dst; + uint16_t payload_len; in_port_t src_port; size_t ip_len; @@ -634,7 +635,8 @@ static size_t udp_update_hdr6(const struct ctx *c, int n, in_port_t dstport, ip_len = udp6_l2_mh_sock[n].msg_len + sizeof(b->ip6h) + sizeof(b->uh); - b->ip6h.payload_len = htons(udp6_l2_mh_sock[n].msg_len + sizeof(b->uh)); + payload_len = udp6_l2_mh_sock[n].msg_len + sizeof(b->uh); + b->ip6h.payload_len = htons(payload_len); if (IN6_IS_ADDR_LINKLOCAL(src)) { dst = &c->ip6.addr_ll_seen; @@ -670,17 +672,17 @@ static size_t udp_update_hdr6(const struct ctx *c, int n, in_port_t dstport, } b->ip6h.daddr = *dst; b->ip6h.saddr = *src; + b->ip6h.version = 6; + b->ip6h.nexthdr = IPPROTO_UDP; + b->ip6h.hop_limit = 255; b->uh.source = b->s_in6.sin6_port; b->uh.dest = htons(dstport); b->uh.len = b->ip6h.payload_len; - - b->ip6h.hop_limit = IPPROTO_UDP; - b->ip6h.version = b->ip6h.nexthdr = b->uh.check = 0; - b->uh.check = csum(&b->ip6h, ip_len, 0); - b->ip6h.version = 6; - b->ip6h.nexthdr = IPPROTO_UDP; - b->ip6h.hop_limit = 255; + b->uh.check = 0; + b->uh.check = csum(&b->uh, payload_len, + proto_ipv6_header_psum(payload_len, IPPROTO_UDP, + src, dst)); return tap_iov_len(c, &b->taph, ip_len); } |