~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/include/net/checksum.h

Version: ~ [ 2.2.5 ] ~ [ 2.4.1 ] ~ [ 2.4.9 ] ~ [ 2.6.17.10 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  * INET         An implementation of the TCP/IP protocol suite for the LINUX
  3  *              operating system.  INET is implemented using the  BSD Socket
  4  *              interface as the means of communication with the user level.
  5  *
  6  *              Checksumming functions for IP, TCP, UDP and so on
  7  *
  8  * Authors:     Jorge Cwik, <jorge@laser.satlink.net>
  9  *              Arnt Gulbrandsen, <agulbra@nvg.unit.no>
 10  *              Borrows very liberally from tcp.c and ip.c, see those
 11  *              files for more names.
 12  *
 13  *              This program is free software; you can redistribute it and/or
 14  *              modify it under the terms of the GNU General Public License
 15  *              as published by the Free Software Foundation; either version
 16  *              2 of the License, or (at your option) any later version.
 17  */
 18 
 19 /*
 20  *      Fixes:
 21  *
 22  *      Ralf Baechle                    :       generic ipv6 checksum
 23  *      <ralf@waldorf-gmbh.de>
 24  */
 25 
 26 #ifndef _CHECKSUM_H
 27 #define _CHECKSUM_H
 28 
 29 #include <asm/types.h>
 30 #include <asm/byteorder.h>
 31 #include <net/ip.h>
 32 #include <asm/uaccess.h>
 33 #include <asm/checksum.h>
 34 
 35 #ifndef _HAVE_ARCH_IPV6_CSUM
 36 
 37 static __inline__ unsigned short int csum_ipv6_magic(struct in6_addr *saddr,
 38                                                      struct in6_addr *daddr,
 39                                                      __u16 len,
 40                                                      unsigned short proto,
 41                                                      unsigned int csum) 
 42 {
 43 
 44         int carry;
 45         __u32 ulen;
 46         __u32 uproto;
 47 
 48         csum += saddr->s6_addr32[0];
 49         carry = (csum < saddr->s6_addr32[0]);
 50         csum += carry;
 51 
 52         csum += saddr->s6_addr32[1];
 53         carry = (csum < saddr->s6_addr32[1]);
 54         csum += carry;
 55 
 56         csum += saddr->s6_addr32[2];
 57         carry = (csum < saddr->s6_addr32[2]);
 58         csum += carry;
 59 
 60         csum += saddr->s6_addr32[3];
 61         carry = (csum < saddr->s6_addr32[3]);
 62         csum += carry;
 63 
 64         csum += daddr->s6_addr32[0];
 65         carry = (csum < daddr->s6_addr32[0]);
 66         csum += carry;
 67 
 68         csum += daddr->s6_addr32[1];
 69         carry = (csum < daddr->s6_addr32[1]);
 70         csum += carry;
 71 
 72         csum += daddr->s6_addr32[2];
 73         carry = (csum < daddr->s6_addr32[2]);
 74         csum += carry;
 75 
 76         csum += daddr->s6_addr32[3];
 77         carry = (csum < daddr->s6_addr32[3]);
 78         csum += carry;
 79 
 80         ulen = htonl((__u32) len);
 81         csum += ulen;
 82         carry = (csum < ulen);
 83         csum += carry;
 84 
 85         uproto = htonl(proto);
 86         csum += uproto;
 87         carry = (csum < uproto);
 88         csum += carry;
 89 
 90         return csum_fold(csum);
 91 }
 92 
 93 #endif
 94 
 95 #ifndef _HAVE_ARCH_COPY_AND_CSUM_FROM_USER
 96 static inline
 97 unsigned int csum_and_copy_from_user (const char *src, char *dst,
 98                                       int len, int sum, int *err_ptr)
 99 {
100         if (verify_area(VERIFY_READ, src, len) == 0)
101                 return csum_partial_copy_from_user(src, dst, len, sum, err_ptr);
102 
103         if (len)
104                 *err_ptr = -EFAULT;
105 
106         return sum;
107 }
108 #endif
109 
110 #ifndef HAVE_CSUM_COPY_USER
111 static __inline__ unsigned int csum_and_copy_to_user
112 (const char *src, char *dst, int len, unsigned int sum, int *err_ptr)
113 {
114         sum = csum_partial(src, len, sum);
115 
116         if (access_ok(VERIFY_WRITE, dst, len)) {
117                 if (copy_to_user(dst, src, len) == 0)
118                         return sum;
119         }
120         if (len)
121                 *err_ptr = -EFAULT;
122 
123         return -1; /* invalid checksum */
124 }
125 #endif
126 
127 static inline unsigned int csum_add(unsigned int csum, unsigned int addend)
128 {
129         csum += addend;
130         return csum + (csum < addend);
131 }
132 
133 static inline unsigned int csum_sub(unsigned int csum, unsigned int addend)
134 {
135         return csum_add(csum, ~addend);
136 }
137 
138 static inline unsigned int
139 csum_block_add(unsigned int csum, unsigned int csum2, int offset)
140 {
141         if (offset&1)
142                 csum2 = ((csum2&0xFF00FF)<<8)+((csum2>>8)&0xFF00FF);
143         return csum_add(csum, csum2);
144 }
145 
146 static inline unsigned int
147 csum_block_sub(unsigned int csum, unsigned int csum2, int offset)
148 {
149         if (offset&1)
150                 csum2 = ((csum2&0xFF00FF)<<8)+((csum2>>8)&0xFF00FF);
151         return csum_sub(csum, csum2);
152 }
153 
154 #endif
155 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.