Hi Pablo, >> the function nfq_udp_compute_checksum_ipv4 (src/extra/udp.c) does not >> compute the correct UDP checksum. >> The issue is caused by the called function checksum_tcpudp_ipv4() >> (src/extra/checksum.c) that uses the hard coded protocol id IPPROTO_TCP >> which is fine for TCP but fails for UDP. >> A possible solution might be to pass the protocol id (IPPROTO_TCP / >> IPPROTOC_UDP) as parameter to the function checksum_tcpudp_ipv4(). >> >> The very same is also true for the IPv6 versions of these functions. >> >> Any feedback is welcome. > > Would you send us a patch to fix this? Thanks! Here it is: Regards Mathias Correct the computation of the UDP checksum Index: libnetfilter_queue-1.0.2/src/extra/checksum.c =================================================================== --- libnetfilter_queue-1.0.2.orig/src/extra/checksum.c +++ libnetfilter_queue-1.0.2/src/extra/checksum.c @@ -35,7 +35,7 @@ uint16_t checksum(uint32_t sum, uint16_t return (uint16_t)(~sum); } -uint16_t checksum_tcpudp_ipv4(struct iphdr *iph) +uint16_t checksum_tcpudp_ipv4(struct iphdr *iph, uint16_t protocol_id) { uint32_t sum = 0; uint32_t iph_len = iph->ihl*4; @@ -46,13 +46,13 @@ uint16_t checksum_tcpudp_ipv4(struct iph sum += (iph->saddr) & 0xFFFF; sum += (iph->daddr >> 16) & 0xFFFF; sum += (iph->daddr) & 0xFFFF; - sum += htons(IPPROTO_TCP); + sum += htons(protocol_id); sum += htons(len); return checksum(sum, (uint16_t *)payload, len); } -uint16_t checksum_tcpudp_ipv6(struct ip6_hdr *ip6h, void *transport_hdr) +uint16_t checksum_tcpudp_ipv6(struct ip6_hdr *ip6h, void *transport_hdr, uint16_t protocol_id) { uint32_t sum = 0; uint32_t hdr_len = (uint32_t *)transport_hdr - (uint32_t *)ip6h; @@ -68,7 +68,7 @@ uint16_t checksum_tcpudp_ipv6(struct ip6 sum += (ip6h->ip6_dst.s6_addr16[i] >> 16) & 0xFFFF; sum += (ip6h->ip6_dst.s6_addr16[i]) & 0xFFFF; } - sum += htons(IPPROTO_TCP); + sum += htons(protocol_id); sum += htons(ip6h->ip6_plen); return checksum(sum, (uint16_t *)payload, len); Index: libnetfilter_queue-1.0.2/src/extra/tcp.c =================================================================== --- libnetfilter_queue-1.0.2.orig/src/extra/tcp.c +++ libnetfilter_queue-1.0.2/src/extra/tcp.c @@ -91,7 +91,7 @@ nfq_tcp_compute_checksum_ipv4(struct tcp { /* checksum field in header needs to be zero for calculation. */ tcph->check = 0; - tcph->check = checksum_tcpudp_ipv4(iph); + tcph->check = checksum_tcpudp_ipv4(iph, IPPROTO_TCP); } EXPORT_SYMBOL(nfq_tcp_compute_checksum_ipv4); @@ -105,7 +105,7 @@ nfq_tcp_compute_checksum_ipv6(struct tcp { /* checksum field in header needs to be zero for calculation. */ tcph->check = 0; - tcph->check = checksum_tcpudp_ipv6(ip6h, tcph); + tcph->check = checksum_tcpudp_ipv6(ip6h, tcph, IPPROTO_TCP); } EXPORT_SYMBOL(nfq_tcp_compute_checksum_ipv6); Index: libnetfilter_queue-1.0.2/src/extra/udp.c =================================================================== --- libnetfilter_queue-1.0.2.orig/src/extra/udp.c +++ libnetfilter_queue-1.0.2/src/extra/udp.c @@ -91,7 +91,7 @@ nfq_udp_compute_checksum_ipv4(struct udp { /* checksum field in header needs to be zero for calculation. */ udph->check = 0; - udph->check = checksum_tcpudp_ipv4(iph); + udph->check = checksum_tcpudp_ipv4(iph, IPPROTO_UDP); } EXPORT_SYMBOL(nfq_udp_compute_checksum_ipv4); @@ -110,7 +110,7 @@ nfq_udp_compute_checksum_ipv6(struct udp { /* checksum field in header needs to be zero for calculation. */ udph->check = 0; - udph->check = checksum_tcpudp_ipv6(ip6h, udph); + udph->check = checksum_tcpudp_ipv6(ip6h, udph, IPPROTO_UDP); } EXPORT_SYMBOL(nfq_udp_compute_checksum_ipv6); Index: libnetfilter_queue-1.0.2/src/internal.h =================================================================== --- libnetfilter_queue-1.0.2.orig/src/internal.h +++ libnetfilter_queue-1.0.2/src/internal.h @@ -13,8 +13,8 @@ struct iphdr; struct ip6_hdr; uint16_t checksum(uint32_t sum, uint16_t *buf, int size); -uint16_t checksum_tcpudp_ipv4(struct iphdr *iph); -uint16_t checksum_tcpudp_ipv6(struct ip6_hdr *ip6h, void *transport_hdr); +uint16_t checksum_tcpudp_ipv4(struct iphdr *iph, uint16_t protocol_id); +uint16_t checksum_tcpudp_ipv6(struct ip6_hdr *ip6h, void *transport_hdr, uint16_t protocol_id); struct pkt_buff { uint8_t *mac_header; -- To unsubscribe from this list: send the line "unsubscribe netfilter" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html