1 #ifndef _I386_CHECKSUM_H
2 #define _I386_CHECKSUM_H
3
4 /*
5 * computes the checksum of a memory block at buff, length len,
6 * and adds in "sum" (32-bit)
7 *
8 * returns a 32-bit number suitable for feeding into itself
9 * or csum_tcpudp_magic
10 *
11 * this function must be called with even lengths, except
12 * for the last fragment, which may be odd
13 *
14 * it's best to have buff aligned on a 32-bit boundary
15 */
16 unsigned int csum_partial(unsigned char * buff, int len, unsigned int sum);
17
18 /*
19 * the same as csum_partial, but copies from src while it
20 * checksums
21 *
22 * here even more important to align src and dst on a 32-bit (or even
23 * better 64-bit) boundary
24 */
25
26 unsigned int csum_partial_copy( char *src, char *dst, int len, int sum);
27
28
29 /*
30 * the same as csum_partial_copy, but copies from user space.
31 *
32 * here even more important to align src and dst on a 32-bit (or even
33 * better 64-bit) boundary
34 */
35
36 unsigned int csum_partial_copy_fromuser( char *src, char *dst, int len, int sum);
37
38 /*
39 * This is a version of ip_compute_csum() optimized for IP headers,
40 * which always checksum on 4 octet boundaries.
41 *
42 * By Jorge Cwik <jorge@laser.satlink.net>, adapted for linux by
43 * Arnt Gulbrandsen.
44 */
45 static inline unsigned short ip_fast_csum(unsigned char * iph,
/* ![[previous]](../icons/n_left.png)
![[next]](../icons/right.png)
![[first]](../icons/n_first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
46 unsigned int ihl) {
47 unsigned int sum;
48
49 __asm__("
50 movl (%1), %0
51 subl $4, %2
52 jbe 2f
53 addl 4(%1), %0
54 adcl 8(%1), %0
55 adcl 12(%1), %0
56 1: adcl 16(%1), %0
57 lea 4(%1), %1
58 decl %2
59 jne 1b
60 adcl $0, %0
61 movl %0, %2
62 shrl $16, %0
63 addw %w2, %w0
64 adcl $0, %0
65 notl %0
66 2:
67 "
68 : "=&r" (sum), "=&r" (iph), "=&r" (ihl)
69 : "1" (iph), "2" (ihl));
70 return(sum);
71 }
72
73
74
75
76 /*
77 * computes the checksum of the TCP/UDP pseudo-header
78 * returns a 16-bit checksum, already complemented
79 */
80
81 static inline unsigned short int csum_tcpudp_magic(unsigned long saddr,
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
82 unsigned long daddr,
83 unsigned short len,
84 unsigned short proto,
85 unsigned int sum) {
86 __asm__("
87 addl %1, %0
88 adcl %4, %0
89 adcl %5, %0
90 adcl $0, %0
91 movl %0, %1
92 shrl $16, %1
93 addw %w1, %w0
94 adcl $0, %0
95 notl %0
96 "
97 : "=&r" (sum), "=&r" (saddr)
98 : "0" (daddr), "1"(saddr), "r"((ntohs(len)<<16)+proto*256), "r"(sum));
99 return((unsigned short)sum);
100 }
101
102 /*
103 * this routine is used for miscellaneous IP-like checksums, mainly
104 * in icmp.c
105 */
106
107 static inline unsigned short ip_compute_csum(unsigned char * buff, int len) {
/* ![[previous]](../icons/left.png)
![[next]](../icons/n_right.png)
![[first]](../icons/first.png)
![[last]](../icons/n_last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
108 unsigned int sum;
109
110 unsigned int scratch;
111 __asm__("
112 movl %0, %1
113 shrl $16, %1
114 addw %w1, %w0
115 adcl $0, %0
116 notl %0
117 "
118 : "=a"(sum), "=r" (scratch)
119 : "0" (csum_partial(buff, len, 0)));
120 return(sum);
121 }
122
123 #endif