From f40eabb01163f383e2471942da45f32361031e39 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Mon, 14 May 2012 13:14:14 +0200 Subject: add pkt_buff and protocol helper functions Signed-off-by: Pablo Neira Ayuso --- src/extra/checksum.c | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 src/extra/checksum.c (limited to 'src/extra/checksum.c') diff --git a/src/extra/checksum.c b/src/extra/checksum.c new file mode 100644 index 0000000..d0c4167 --- /dev/null +++ b/src/extra/checksum.c @@ -0,0 +1,78 @@ +/* + * (C) 2012 by Pablo Neira Ayuso + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This code has been sponsored by Vyatta Inc. + */ + +#include +#include +#include +#include +#include + +#include + +#include "internal.h" + +uint16_t checksum(uint32_t sum, uint16_t *buf, int size) +{ + while (size > 1) { + sum += *buf++; + size -= sizeof(uint16_t); + } + if (size) + sum += *(uint8_t *)buf; + + sum = (sum >> 16) + (sum & 0xffff); + sum += (sum >>16); + + return (uint16_t)(~sum); +} + +uint16_t checksum_tcpudp_ipv4(struct iphdr *iph) +{ + uint32_t sum = 0; + uint32_t iph_len = iph->ihl*4; + uint32_t len = ntohs(iph->tot_len) - iph_len; + uint8_t *payload = (uint8_t *)iph + iph_len; + + sum += (iph->saddr >> 16) & 0xFFFF; + sum += (iph->saddr) & 0xFFFF; + sum += (iph->daddr >> 16) & 0xFFFF; + sum += (iph->daddr) & 0xFFFF; + sum += htons(IPPROTO_TCP); + sum += htons(len); + + return checksum(sum, (uint16_t *)payload, len); +} + +uint16_t checksum_tcpudp_ipv6(struct ip6_hdr *ip6h, void *transport_hdr) +{ + uint32_t sum = 0; + uint32_t hdr_len = (uint32_t *)transport_hdr - (uint32_t *)ip6h; + uint32_t len = ip6h->ip6_plen - hdr_len; + 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(IPPROTO_TCP); + sum += htons(ip6h->ip6_plen); + + return checksum(sum, (uint16_t *)payload, len); +} + +/** + * @} + */ -- cgit v1.2.3