home *** CD-ROM | disk | FTP | other *** search
/ PC Welt 2006 November (DVD) / PCWELT_11_2006.ISO / casper / filesystem.squashfs / usr / src / linux-headers-2.6.17-6 / include / net / checksum.h < prev    next >
Encoding:
C/C++ Source or Header  |  2006-08-11  |  2.2 KB  |  88 lines

  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. #ifndef _CHECKSUM_H
  20. #define _CHECKSUM_H
  21.  
  22. #include <linux/errno.h>
  23. #include <asm/types.h>
  24. #include <asm/byteorder.h>
  25. #include <asm/uaccess.h>
  26. #include <asm/checksum.h>
  27.  
  28. #ifndef _HAVE_ARCH_COPY_AND_CSUM_FROM_USER
  29. static inline
  30. unsigned int csum_and_copy_from_user (const unsigned char __user *src, unsigned char *dst,
  31.                       int len, int sum, int *err_ptr)
  32. {
  33.     if (access_ok(VERIFY_READ, src, len))
  34.         return csum_partial_copy_from_user(src, dst, len, sum, err_ptr);
  35.  
  36.     if (len)
  37.         *err_ptr = -EFAULT;
  38.  
  39.     return sum;
  40. }
  41. #endif
  42.  
  43. #ifndef HAVE_CSUM_COPY_USER
  44. static __inline__ unsigned int csum_and_copy_to_user
  45. (const unsigned char *src, unsigned char __user *dst, int len, unsigned int sum, int *err_ptr)
  46. {
  47.     sum = csum_partial(src, len, sum);
  48.  
  49.     if (access_ok(VERIFY_WRITE, dst, len)) {
  50.         if (copy_to_user(dst, src, len) == 0)
  51.             return sum;
  52.     }
  53.     if (len)
  54.         *err_ptr = -EFAULT;
  55.  
  56.     return -1; /* invalid checksum */
  57. }
  58. #endif
  59.  
  60. static inline unsigned int csum_add(unsigned int csum, unsigned int addend)
  61. {
  62.     csum += addend;
  63.     return csum + (csum < addend);
  64. }
  65.  
  66. static inline unsigned int csum_sub(unsigned int csum, unsigned int addend)
  67. {
  68.     return csum_add(csum, ~addend);
  69. }
  70.  
  71. static inline unsigned int
  72. csum_block_add(unsigned int csum, unsigned int csum2, int offset)
  73. {
  74.     if (offset&1)
  75.         csum2 = ((csum2&0xFF00FF)<<8)+((csum2>>8)&0xFF00FF);
  76.     return csum_add(csum, csum2);
  77. }
  78.  
  79. static inline unsigned int
  80. csum_block_sub(unsigned int csum, unsigned int csum2, int offset)
  81. {
  82.     if (offset&1)
  83.         csum2 = ((csum2&0xFF00FF)<<8)+((csum2>>8)&0xFF00FF);
  84.     return csum_sub(csum, csum2);
  85. }
  86.  
  87. #endif
  88.