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

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

Coding style (no functional change)

  • Property mode set to 100644
File size: 3.6 KB
Line 
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
49uint32_t compute_crc32_le(uint32_t seed, uint8_t * data, size_t length){
50 size_t index;
51
52 while(length >= 8){
53 seed ^= (*data);
54 for(index = 0; index < 8; ++ index){
55 if(seed &1){
56 seed = (seed >> 1) ^ ((uint32_t) CRC_DIVIDER_LE);
57 }else{
58 seed >>= 1;
59 }
60 }
61 ++ data;
62 length -= 8;
63 }
64 if(length > 0){
65 seed ^= (*data) >> (8 - length);
66 for(index = 0; index < length; ++ index){
67 if(seed &1){
68 seed = (seed >> 1) ^ ((uint32_t) CRC_DIVIDER_LE);
69 }else{
70 seed >>= 1;
71 }
72 }
73 length -= 8;
74 }
75 return seed;
76}
77
78uint32_t compute_crc32_be(uint32_t seed, uint8_t * data, size_t length){
79 size_t index;
80
81 while(length >= 8){
82 seed ^= (*data) << 24;
83 for(index = 0; index < 8; ++ index){
84 if(seed &0x80000000){
85 seed = (seed << 1) ^ ((uint32_t) CRC_DIVIDER_BE);
86 }else{
87 seed <<= 1;
88 }
89 }
90 ++ data;
91 length -= 8;
92 }
93 if(length > 0){
94 seed ^= ((*data) &(0xFF << (8 - length))) << 24;
95 for(index = 0; index < length; ++ index){
96 if(seed &0x80000000){
97 seed = (seed << 1) ^ ((uint32_t) CRC_DIVIDER_BE);
98 }else{
99 seed <<= 1;
100 }
101 }
102 length -= 8;
103 }
104 return seed;
105}
106
107uint32_t compute_checksum(uint32_t seed, uint8_t * data, size_t length){
108 size_t index;
109
110 // sum all the 16 bit fields
111 for(index = 0; index + 1 < length; index += 2){
112 seed += (data[index] << 8) + data[index + 1];
113 }
114
115 // last odd byte with zero padding
116 if(index + 1 == length){
117 seed += data[index] << 8;
118 }
119
120 return seed;
121}
122
123uint16_t compact_checksum(uint32_t sum){
124 // shorten to the 16 bits
125 while(sum >> 16){
126 sum = (sum &0xFFFF) + (sum >> 16);
127 }
128
129 return (uint16_t) sum;
130}
131
132uint16_t flip_checksum(uint16_t checksum){
133 // flip, zero is returned as 0xFFFF (not flipped)
134 checksum = ~ checksum;
135 return checksum ? checksum : IP_CHECKSUM_ZERO;
136}
137
138uint16_t ip_checksum(uint8_t * data, size_t length){
139 return flip_checksum(compact_checksum(compute_checksum(0, data, length)));
140}
141
142/** @}
143 */
Note: See TracBrowser for help on using the repository browser.