source: mainline/uspace/srv/net/checksum.c@ daecfed3

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since daecfed3 was 21580dd, checked in by Lukas Mejdrech <lukas@…>, 16 years ago

Merged with network branch svn://svn.helenos.org/HelenOS/branches/network revision 4759; ipc_share_* and ipc_data_* changed to async_*; client connection in module.c returns on IPC_M_PHONE_HUNGUP; * Qemu scripts renamed to net-qe.*; (the dp8390 does not respond)

  • Property mode set to 100644
File size: 3.8 KB
RevLine 
[21580dd]1/*
2 * Copyright (c) 2009 Lukas Mejdrech
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup net
30 * @{
31 */
32
33/** @file
34 * General CRC and checksum computation implementation.
35 */
36
37#include <sys/types.h>
38
39#include "include/checksum.h"
40
41/** Big-endian encoding CRC divider.
42 */
43#define CRC_DIVIDER_BE 0x04C11DB7
44
45/** Little-endian encoding CRC divider.
46 */
47#define CRC_DIVIDER_LE 0xEDB88320
48
49/** IP checksum value for computed zero checksum.
50 * Zero is returned as 0xFFFF (not flipped)
51 */
52#define IP_CHECKSUM_ZERO 0xFFFFu
53
54uint32_t compute_crc32_le( uint32_t seed, uint8_t * data, size_t length ){
55 size_t index;
56
57 while( length >= 8 ){
58 seed ^= ( * data );
59 for( index = 0; index < 8; ++ index ){
60 if( seed & 1 ){
61 seed = ( seed >> 1 ) ^ (( uint32_t ) CRC_DIVIDER_LE );
62 }else{
63 seed >>= 1;
64 }
65 }
66 ++ data;
67 length -= 8;
68 }
69 if( length > 0 ){
70 seed ^= ( * data ) >> ( 8 - length );
71 for( index = 0; index < length; ++ index ){
72 if( seed & 1 ){
73 seed = ( seed >> 1 ) ^ (( uint32_t ) CRC_DIVIDER_LE );
74 }else{
75 seed >>= 1;
76 }
77 }
78 length -= 8;
79 }
80 return seed;
81}
82
83uint32_t compute_crc32_be( uint32_t seed, uint8_t * data, size_t length ){
84 size_t index;
85
86 while( length >= 8 ){
87 seed ^= ( * data ) << 24;
88 for( index = 0; index < 8; ++ index ){
89 if( seed & 0x80000000 ){
90 seed = ( seed << 1 ) ^ (( uint32_t ) CRC_DIVIDER_BE );
91 }else{
92 seed <<= 1;
93 }
94 }
95 ++ data;
96 length -= 8;
97 }
98 if( length > 0 ){
99 seed ^= (( * data ) & ( 0xFF << ( 8 - length ))) << 24;
100 for( index = 0; index < length; ++ index ){
101 if( seed & 0x80000000 ){
102 seed = ( seed << 1 ) ^ (( uint32_t ) CRC_DIVIDER_BE );
103 }else{
104 seed <<= 1;
105 }
106 }
107 length -= 8;
108 }
109 return seed;
110}
111
112uint32_t compute_checksum( uint32_t seed, uint8_t * data, size_t length ){
113 size_t index;
114
115 // sum all the 16 bit fields
116 for( index = 0; index + 1 < length; index += 2 ){
117 seed += ( data[ index ] << 8 ) + data[ index + 1 ];
118 }
119
120 // last odd byte with zero padding
121 if( index + 1 == length ){
122 seed += data[ index ] << 8;
123 }
124
125 return seed;
126}
127
128uint16_t compact_checksum( uint32_t sum ){
129 // shorten to the 16 bits
130 while( sum >> 16 ) sum = ( sum & 0xFFFF ) + ( sum >> 16 );
131
132 return ( uint16_t ) sum;
133}
134
135uint16_t flip_checksum( uint16_t checksum ){
136 // flip, zero is returned as 0xFFFF (not flipped)
137 return ( ~ checksum ) ? ( uint16_t ) ( ~ checksum ) : IP_CHECKSUM_ZERO;
138}
139
140uint16_t ip_checksum( uint8_t * data, size_t length ){
141 return flip_checksum( compact_checksum( compute_checksum( 0, data, length )));
142}
143
144/** @}
145 */
Note: See TracBrowser for help on using the repository browser.