diff options
author | Duncan Roe <duncan_roe@optusnet.com.au> | 2019-12-20 16:53:47 +1100 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2019-12-30 12:29:56 +0100 |
commit | c432a84f1b6a5fb4435f74408d11ed8f7672ec4b (patch) | |
tree | b138dbaa2901594e9b961af92eddd0920aaeada5 /src/extra/checksum.c | |
parent | 0c2001aa98cec7a3461360be2b94c4f3428cace7 (diff) | |
download | libnetfilter_queue-c432a84f1b6a5fb4435f74408d11ed8f7672ec4b.tar.gz |
src: more IPv6 checksum fixes
- Fix calculation of header length
- Upgrade calculation of payload length: Allow for extra headers before
the UDP header.
- Delete "sum += ... s6_addr16[i] >> 16" lines, since uint16_t >> 16 == 0
- Use upgraded payload length in pseudo-header
Signed-off-by: Duncan Roe <duncan_roe@optusnet.com.au>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'src/extra/checksum.c')
-rw-r--r-- | src/extra/checksum.c | 10 |
1 files changed, 5 insertions, 5 deletions
diff --git a/src/extra/checksum.c b/src/extra/checksum.c index 42389aa..8b23997 100644 --- a/src/extra/checksum.c +++ b/src/extra/checksum.c @@ -62,21 +62,21 @@ uint16_t nfq_checksum_tcpudp_ipv6(struct ip6_hdr *ip6h, void *transport_hdr, uint16_t protonum) { uint32_t sum = 0; - uint32_t hdr_len = (uint32_t *)transport_hdr - (uint32_t *)ip6h; - uint32_t len = ip6h->ip6_plen - hdr_len; + uint32_t hdr_len = (uint8_t *)transport_hdr - (uint8_t *)ip6h; + /* Allow for extra headers before the UDP header */ + /* TODO: Deal with routing headers */ + uint32_t len = ntohs(ip6h->ip6_plen) - (hdr_len - sizeof *ip6h); uint8_t *payload = (uint8_t *)ip6h + hdr_len; int i; for (i=0; i<8; i++) { - sum += (ip6h->ip6_src.s6_addr16[i] >> 16) & 0xFFFF; sum += (ip6h->ip6_src.s6_addr16[i]) & 0xFFFF; } for (i=0; i<8; i++) { - sum += (ip6h->ip6_dst.s6_addr16[i] >> 16) & 0xFFFF; sum += (ip6h->ip6_dst.s6_addr16[i]) & 0xFFFF; } sum += htons(protonum); - sum += htons(ip6h->ip6_plen); + sum += htons(len); return nfq_checksum(sum, (uint16_t *)payload, len); } |