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. csum_fold
  4. 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(const 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( const 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(const 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][next][first][last][top][bottom][index][help] */
  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][next][first][last][top][bottom][index][help] */
  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  *      Fold a partial checksum without adding pseudo headers
 104  */
 105 
 106 static inline unsigned int csum_fold(unsigned int sum)
     /* [previous][next][first][last][top][bottom][index][help] */
 107 {
 108         __asm__("
 109                 addl %1, %0
 110                 adcl $0xffff, %0
 111                 "
 112                 : "=r" (sum)
 113                 : "r" (sum << 16), "0" (sum & 0xffff0000)
 114         );
 115         return (~sum) >> 16;
 116 }
 117  
 118 /*
 119  * this routine is used for miscellaneous IP-like checksums, mainly
 120  * in icmp.c
 121  */
 122 
 123 static inline unsigned short ip_compute_csum(unsigned char * buff, int len) {
     /* [previous][next][first][last][top][bottom][index][help] */
 124     unsigned int sum;
 125 
 126     unsigned int scratch;
 127     __asm__("
 128         movl %0, %1
 129         shrl $16, %1
 130         addw %w1, %w0
 131         adcl $0, %0
 132         notl %0
 133         "
 134         : "=a"(sum), "=r" (scratch)
 135         : "0" (csum_partial(buff, len, 0)));
 136         return(sum);
 137 }
 138 
 139 #endif

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