root/include/asm-i386/checksum.h

/* [previous][next][first][last][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. ip_fast_csum
  2. csum_tcpudp_magic
  3. ip_compute_csum

   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 fs: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_copyffs( char *src, char *dst, int len, int sum);
  27 
  28 
  29 /*
  30  *      This is a version of ip_compute_csum() optimized for IP headers,
  31  *      which always checksum on 4 octet boundaries.
  32  *
  33  *      By Jorge Cwik <jorge@laser.satlink.net>, adapted for linux by
  34  *      Arnt Gulbrandsen.
  35  */
  36 static inline unsigned short ip_fast_csum(unsigned char * iph,
     /* [previous][next][first][last][top][bottom][index][help] */
  37                                           unsigned int ihl) {
  38         unsigned short int sum;
  39 
  40         __asm__("
  41             movl (%%esi), %%eax
  42             andl $15, %%ecx
  43             subl $4, %%ecx
  44             jbe 2f
  45             addl 4(%%esi), %%eax
  46             adcl 8(%%esi), %%eax
  47             adcl 12(%%esi), %%eax
  48 1:          adcl 16(%%esi), %%eax
  49             lea 4(%%esi), %%esi
  50             decl %%ecx
  51             jne 1b
  52             adcl $0, %%eax
  53             movl %%eax, %%ecx
  54             shrl $16, %%eax
  55             addw %%ecx, %%eax
  56             adcl $0, %%eax
  57             notl %%eax
  58             andl $65535, %%eax
  59 2:
  60             "
  61         : "=a" (sum)
  62         : "S" (iph), "c"(ihl)
  63         : "ax", "cx", "si");
  64         return(sum);
  65 }
  66 
  67 
  68 
  69 
  70 /*
  71  * computes the checksum of the TCP/UDP pseudo-header
  72  * returns a 16-bit checksum, already complemented
  73  */
  74 
  75 static inline unsigned short int csum_tcpudp_magic(unsigned long saddr,
     /* [previous][next][first][last][top][bottom][index][help] */
  76                                                    unsigned long daddr,
  77                                                    unsigned short len,
  78                                                    unsigned short proto,
  79                                                    unsigned int sum) {
  80     __asm__("
  81         addl %2, %0
  82         adcl %3, %0
  83         adcl %4, %0
  84         adcl $0, %0
  85         movl %0, %2
  86         shrl $16, %2
  87         addw %2, %0
  88         adcl $0, %0
  89         notl %0
  90         andl $65535, %0
  91         "
  92         : "=r" (sum)
  93         : "0" (daddr), "S"(saddr), "r"((ntohs(len)<<16)+proto*256), "r"(sum)
  94         : "si" );
  95         return((unsigned short)sum);
  96 }
  97 
  98 /*
  99  * this routine is used for miscellaneous IP-like checksums, mainly
 100  * in icmp.c
 101  */
 102 
 103 static inline unsigned short ip_compute_csum(unsigned char * buff, int len) {
     /* [previous][next][first][last][top][bottom][index][help] */
 104     unsigned short int sum;
 105 
 106     __asm__("
 107         movl %%eax, %%ecx
 108         shrl $16, %%ecx
 109         addw %%cx, %%ax
 110         adcl $0, %%eax
 111         notl %%eax
 112         andl $65535, %%eax
 113         "
 114         : "=a"(sum)
 115         : "a" (csum_partial(buff, len, 0))
 116         : "cx");
 117         return(sum);
 118 }
 119 
 120 #endif

/* [previous][next][first][last][top][bottom][index][help] */