3 #include <linux/config.h>
4 #include <asm/segment.h>
5 #include <asm/system.h>
6 #include <linux/types.h>
7 #include <linux/kernel.h>
8 #include <linux/sched.h>
9 #include <linux/string.h>
10 #include <linux/errno.h>
11 #include <linux/config.h>
13 #include <linux/socket.h>
14 #include <linux/sockios.h>
16 #include <linux/inet.h>
17 #include <linux/netdevice.h>
18 #include <linux/icmp.h>
19 #include <linux/udp.h>
21 #include <net/protocol.h>
22 #include <net/route.h>
25 #include <linux/skbuff.h>
28 #include <linux/firewall.h>
29 #include <linux/ip_fw.h>
30 #include <net/checksum.h>
31 #include <linux/proc_fs.h>
32 #include <linux/stat.h>
33 #include <net/checksum.h>
36 * computes a partial checksum, e.g. for TCP/UDP fragments
39 unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum) {
41 * Experiments with ethernet and slip connections show that buff
42 * is aligned on either a 2-byte or 4-byte boundary. We get at
43 * least a 2x speedup on 486 and Pentium if it is 4-byte aligned.
44 * Fortunately, it is easy to convert 2-byte alignment to 4-byte
45 * alignment for the unrolled loop.
48 testl $2, %%esi # Check alignment.
49 jz 2f # Jump if alignment is ok.
50 subl $2, %%ecx # Alignment uses up two bytes.
51 jae 1f # Jump if we had at least two bytes.
52 addl $2, %%ecx # ecx was < 2. Deal with it.
63 1: movl (%%esi), %%ebx
88 3: adcl (%%esi), %%eax
106 : "0"(sum), "c"(len), "S"(buff)
107 : "bx", "cx", "dx", "si");
111 /* 32 bits version of the checksum routines written for the Alpha by Linus */
112 static unsigned short from32to16(unsigned long x)
114 /* add up 16-bit and 17-bit words for 17+c bits */
115 x = (x & 0xffff) + (x >> 16);
116 /* add up 16-bit and 2-bit for 16+c bit */
117 x = (x & 0xffff) + (x >> 16);
119 x = (x & 0xffff) + (x >> 16);
124 main(int argc,char *argv[])
126 unsigned long sum1,sum2,sum3,sum4,sum5;
128 __u32 saddr=0x32456787,daddr=0x89764512;
133 if (argc > 1) seed = atoi(argv[1]);
137 for (i=0; i<512 ; i++) {
141 sum1 = csum_tcpudp_magic(saddr,daddr,len,proto,csum_partial(data1,512,0));
143 sum2 = csum_tcpudp_magic(saddr,daddr,len,proto,csum_partial(data1,256,0));
148 sum3 = csum_tcpudp_magic(saddr,daddr,len,proto,csum_partial(data1,256,0));
150 sum4 = ~sum3 + (~sum1 - ~sum2);
151 if (!(sum4>>16)) sum4++;
152 sum4 = 0xFFFF & (~from32to16(sum4));
154 sum5 = csum_tcpudp_magic(saddr,daddr,len,proto,csum_partial(data1,512,0));
157 printf("Failed with seed=%d\n",seed);
162 printf("seed=0x%X\n",seed);
165 printf("%X %X\n",~sum3,~sum3 + (~sum1 - ~sum2));
166 printf("sum1=%X\n",(unsigned int)sum1 & 0xFFFF);
167 printf("sum2=%X\n",(unsigned int)sum2 & 0xFFFF);
168 printf("sum3=%X\n",(unsigned int)sum3 & 0xFFFF);
169 printf("sum4=%X\n",(unsigned int)sum4 & 0xFFFF);
170 printf("sum5=%X\n",(unsigned int)sum5 & 0xFFFF);