Annotation of embedaddon/coova-chilli/src/chksum.c, revision 1.1.1.1
1.1 misho 1: /*
2: * Chksum library functions
3: * Copyright (c) 2006-2008 David Bird <david@coova.com>
4: *
5: * The contents of this file may be used under the terms of the GNU
6: * General Public License Version 2, provided that the above copyright
7: * notice and this permission notice is included in all copies or
8: * substantial portions of the software.
9: *
10: */
11:
12: #include "system.h"
13: #include "pkt.h"
14: #include "options.h"
15: #include "syserr.h"
16:
17: #define cksum_wrap(c) (c=(c>>16)+(c&0xffff),(~(c+(c>>16))&0xffff))
18:
19: int
20: in_cksum(uint16_t *addr, size_t len)
21: {
22: size_t nleft = len;
23: uint32_t sum = 0;
24: uint16_t * w = addr;
25:
26: while (nleft > 1) {
27: sum += *w++;
28: nleft -= 2;
29: }
30:
31: if (nleft == 1) {
32: uint16_t ans = 0;
33: *(unsigned char *)(&ans) = *(unsigned char *)w ;
34: sum += ans;
35: }
36:
37: return(sum);
38: }
39:
40: int chksum(struct pkt_iphdr_t *iph) {
41: size_t hlen = (iph->version_ihl & 0x0f) << 2;
42: int sum;
43:
44: switch(iph->protocol) {
45: case PKT_IP_PROTO_TCP:
46: {
47: struct pkt_tcphdr_t *tcph = (struct pkt_tcphdr_t *)(((void *)iph) + hlen);
48: size_t len = (size_t)ntohs(iph->tot_len);
49:
50: if (len > 2000) return -1; /* too long? */
51:
52: len -= (iph->version_ihl & 0x0f) << 2;
53:
54: if (len < 20) return -1; /* too short? */
55:
56: tcph->check = 0;
57: sum = in_cksum(((uint16_t *)iph)+6/*saddr*/, 8);
58: sum += ntohs(IPPROTO_TCP + len);
59: sum += in_cksum((uint16_t *)tcph, len);
60: tcph->check = cksum_wrap(sum);
61: }
62: break;
63:
64: case PKT_IP_PROTO_UDP:
65: {
66: struct pkt_udphdr_t *udph = (struct pkt_udphdr_t *)(((void *)iph) + hlen);
67: size_t len = (size_t)ntohs(udph->len);
68:
69: udph->check = 0;
70: sum = in_cksum(((uint16_t *)iph)+6/*saddr*/, 8);
71: sum += ntohs(IPPROTO_UDP + len);
72: sum += in_cksum((uint16_t *)udph, len);
73: udph->check = cksum_wrap(sum);
74: }
75: break;
76: }
77:
78: iph->check = 0;
79: sum = in_cksum((uint16_t *)iph, hlen);
80: iph->check = cksum_wrap(sum);
81:
82: return 0;
83: }
84:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>