source: mainline/uspace/srv/net/checksum.c@ 31c80a5

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 31c80a5 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
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
[aadf01e]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);
[21580dd]57 }else{
58 seed >>= 1;
59 }
60 }
61 ++ data;
62 length -= 8;
63 }
[aadf01e]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);
[21580dd]69 }else{
70 seed >>= 1;
71 }
72 }
73 length -= 8;
74 }
75 return seed;
76}
77
[aadf01e]78uint32_t compute_crc32_be(uint32_t seed, uint8_t * data, size_t length){
79 size_t index;
[21580dd]80
[aadf01e]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);
[21580dd]86 }else{
87 seed <<= 1;
88 }
89 }
90 ++ data;
91 length -= 8;
92 }
[aadf01e]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);
[21580dd]98 }else{
99 seed <<= 1;
100 }
101 }
102 length -= 8;
103 }
104 return seed;
105}
106
[aadf01e]107uint32_t compute_checksum(uint32_t seed, uint8_t * data, size_t length){
108 size_t index;
[21580dd]109
110 // sum all the 16 bit fields
[aadf01e]111 for(index = 0; index + 1 < length; index += 2){
112 seed += (data[index] << 8) + data[index + 1];
[21580dd]113 }
114
115 // last odd byte with zero padding
[aadf01e]116 if(index + 1 == length){
117 seed += data[index] << 8;
[21580dd]118 }
119
120 return seed;
121}
122
[aadf01e]123uint16_t compact_checksum(uint32_t sum){
[21580dd]124 // shorten to the 16 bits
[aadf01e]125 while(sum >> 16){
126 sum = (sum &0xFFFF) + (sum >> 16);
127 }
[21580dd]128
[aadf01e]129 return (uint16_t) sum;
[21580dd]130}
131
[aadf01e]132uint16_t flip_checksum(uint16_t checksum){
[21580dd]133 // flip, zero is returned as 0xFFFF (not flipped)
[918e9910]134 checksum = ~ checksum;
135 return checksum ? checksum : IP_CHECKSUM_ZERO;
[21580dd]136}
137
[aadf01e]138uint16_t ip_checksum(uint8_t * data, size_t length){
139 return flip_checksum(compact_checksum(compute_checksum(0, data, length)));
[21580dd]140}
141
142/** @}
143 */
Note: See TracBrowser for help on using the repository browser.