15 #include <arpa/inet.h> 16 #include <netinet/ip.h> 17 #include <netinet/ip6.h> 18 #include <netinet/tcp.h> 20 #include <libnetfilter_queue/libnetfilter_queue.h> 24 uint16_t nfq_checksum(uint32_t sum, uint16_t *buf,
int size)
28 size -=
sizeof(uint16_t);
31 #if __BYTE_ORDER == __BIG_ENDIAN 32 sum += (uint16_t)*(uint8_t *)buf << 8;
34 sum += (uint16_t)*(uint8_t *)buf;
38 sum = (sum >> 16) + (sum & 0xffff);
41 return (uint16_t)(~sum);
44 uint16_t nfq_checksum_tcpudp_ipv4(
struct iphdr *iph, uint16_t protonum)
47 uint32_t iph_len = iph->ihl*4;
48 uint32_t len = ntohs(iph->tot_len) - iph_len;
49 uint8_t *payload = (uint8_t *)iph + iph_len;
51 sum += (iph->saddr >> 16) & 0xFFFF;
52 sum += (iph->saddr) & 0xFFFF;
53 sum += (iph->daddr >> 16) & 0xFFFF;
54 sum += (iph->daddr) & 0xFFFF;
55 sum += htons(protonum);
58 return nfq_checksum(sum, (uint16_t *)payload, len);
61 uint16_t nfq_checksum_tcpudp_ipv6(
struct ip6_hdr *ip6h,
void *transport_hdr,
65 uint32_t hdr_len = (uint8_t *)transport_hdr - (uint8_t *)ip6h;
68 uint32_t len = ntohs(ip6h->ip6_plen) - (hdr_len -
sizeof *ip6h);
69 uint8_t *payload = (uint8_t *)ip6h + hdr_len;
73 sum += (ip6h->ip6_src.s6_addr16[i]);
76 sum += (ip6h->ip6_dst.s6_addr16[i]);
78 sum += htons(protonum);
81 return nfq_checksum(sum, (uint16_t *)payload, len);