14 #include <arpa/inet.h>
15 #include <netinet/ip.h>
16 #include <netinet/ip6.h>
17 #include <netinet/tcp.h>
19 #include <libnetfilter_queue/libnetfilter_queue.h>
23 uint16_t nfq_checksum(uint32_t sum, uint16_t *buf,
int size)
27 size -=
sizeof(uint16_t);
30 sum += *(uint8_t *)buf;
32 sum = (sum >> 16) + (sum & 0xffff);
35 return (uint16_t)(~sum);
38 uint16_t nfq_checksum_tcpudp_ipv4(
struct iphdr *iph)
41 uint32_t iph_len = iph->ihl*4;
42 uint32_t len = ntohs(iph->tot_len) - iph_len;
43 uint8_t *payload = (uint8_t *)iph + iph_len;
45 sum += (iph->saddr >> 16) & 0xFFFF;
46 sum += (iph->saddr) & 0xFFFF;
47 sum += (iph->daddr >> 16) & 0xFFFF;
48 sum += (iph->daddr) & 0xFFFF;
49 sum += htons(IPPROTO_TCP);
52 return nfq_checksum(sum, (uint16_t *)payload, len);
55 uint16_t nfq_checksum_tcpudp_ipv6(
struct ip6_hdr *ip6h,
void *transport_hdr)
58 uint32_t hdr_len = (uint32_t *)transport_hdr - (uint32_t *)ip6h;
59 uint32_t len = ip6h->ip6_plen - hdr_len;
60 uint8_t *payload = (uint8_t *)ip6h + hdr_len;
64 sum += (ip6h->ip6_src.s6_addr16[i] >> 16) & 0xFFFF;
65 sum += (ip6h->ip6_src.s6_addr16[i]) & 0xFFFF;
68 sum += (ip6h->ip6_dst.s6_addr16[i] >> 16) & 0xFFFF;
69 sum += (ip6h->ip6_dst.s6_addr16[i]) & 0xFFFF;
71 sum += htons(IPPROTO_TCP);
72 sum += htons(ip6h->ip6_plen);
74 return nfq_checksum(sum, (uint16_t *)payload, len);